Introduced DeclContext::isDependentContext, which determines whether a

given DeclContext is dependent on type parameters. Use this to
properly determine whether a TagDecl is dependent; previously, we were
missing the case where the TagDecl is a local class of a member
function of a class template (phew!).

Also, make sure that, when we instantiate declarations within a member
function of a class template (or a function template, eventually),
that we add those declarations to the "instantiated locals" map so
that they can be found when instantiating declaration references.

Unfortunately, I was not able to write a useful test for this change,
although the assert() that fires when uncommenting the FIXME'd line in
test/SemaTemplate/instantiate-declref.cpp tells the "experienced user"
that we're now doing the right thing.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72526 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-05-28 16:34:51 +00:00
Родитель 8c0d8a2cc4
Коммит bc221637f5
6 изменённых файлов: 27 добавлений и 15 удалений

Просмотреть файл

@ -1081,7 +1081,7 @@ public:
/// \brief Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
bool isDependentType() const;
bool isDependentType() const { return isDependentContext(); }
/// @brief Starts the definition of this tag declaration.
///

Просмотреть файл

@ -441,6 +441,10 @@ public:
return DeclKind == Decl::Namespace;
}
/// \brief Determines whether this context is dependent on a
/// template parameter.
bool isDependentContext() const;
/// isTransparentContext - Determines whether this context is a
/// "transparent" context, meaning that the members declared in this
/// context are semantically declared in the nearest enclosing

Просмотреть файл

@ -528,19 +528,6 @@ OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
// TagDecl Implementation
//===----------------------------------------------------------------------===//
bool TagDecl::isDependentType() const {
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
if (Record->getDescribedClassTemplate())
return true;
if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(getDeclContext()))
return TD->isDependentType();
// FIXME: Tag types declared function templates are dependent types.
// FIXME: Look through block scopes.
return false;
}
void TagDecl::startDefinition() {
TagType *TagT = const_cast<TagType *>(TypeForDecl->getAsTagType());
TagT->decl.setPointer(this);

Просмотреть файл

@ -396,6 +396,21 @@ void DeclContext::DestroyDecls(ASTContext &C) {
(*D++)->Destroy(C);
}
bool DeclContext::isDependentContext() const {
if (isFileContext())
return false;
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this))
if (Record->getDescribedClassTemplate())
return true;
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this))
if (Function->getDescribedFunctionTemplate())
return true;
return getParent() && getParent()->isDependentContext();
}
bool DeclContext::isTransparentContext() const {
if (DeclKind == Decl::Enum)
return true; // FIXME: Check for C++0x scoped enums

Просмотреть файл

@ -97,6 +97,9 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
Typedef->setInvalidDecl();
Owner->addDecl(SemaRef.Context, Typedef);
if (Owner->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Typedef);
return Typedef;
}
@ -211,6 +214,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
Enum->setInstantiationOfMemberEnum(D);
Enum->setAccess(D->getAccess());
Owner->addDecl(SemaRef.Context, Enum);
if (Owner->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
Enum->startDefinition();
llvm::SmallVector<Sema::DeclPtrTy, 16> Enumerators;
@ -276,6 +281,8 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
Record->setInstantiationOfMemberClass(D);
Owner->addDecl(SemaRef.Context, Record);
if (Owner->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
return Record;
}

Просмотреть файл

@ -1,5 +1,4 @@
// RUN: clang-cc -fsyntax-only -verify %s
namespace N {
struct Outer {
struct Inner {