зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
8c0d8a2cc4
Коммит
bc221637f5
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче