From: Douglas Gregor Date: Sat, 24 Apr 2010 15:35:55 +0000 (+0000) Subject: Keep track of when DependentNameTypes have no associated keyword X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=107de90451b7f7a7749380a9d017ff1bafb6b407;p=clang Keep track of when DependentNameTypes have no associated keyword (e.g., no typename, enum, class, etc.), e.g., because the context is one that is known to refer to a type. Patch from Enea Zaffanella! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102243 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 64afd56a40..dffc7126ed 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -3017,7 +3017,8 @@ public: ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, SourceLocation TemplateLoc, TypeTy *Ty); - QualType CheckTypenameType(NestedNameSpecifier *NNS, + QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, const IdentifierInfo &II, SourceRange Range); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index cdfd0553f2..b8ff182be0 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -89,9 +89,8 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, // We know from the grammar that this name refers to a type, so build a // DependentNameType node to describe the type. - // FIXME: Record somewhere that this DependentNameType node has no "typename" - // keyword associated with it. - return CheckTypenameType((NestedNameSpecifier *)SS->getScopeRep(), + return CheckTypenameType(ETK_None, + (NestedNameSpecifier *)SS->getScopeRep(), II, SS->getRange()).getAsOpaquePtr(); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 9038a25082..f1b1244b9e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1088,7 +1088,8 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, if (!NotUnknownSpecialization) { // When the scope specifier can refer to a member of an unknown // specialization, we take it as a type name. - BaseType = CheckTypenameType((NestedNameSpecifier *)SS.getScopeRep(), + BaseType = CheckTypenameType(ETK_None, + (NestedNameSpecifier *)SS.getScopeRep(), *MemberOrBase, SS.getRange()); if (BaseType.isNull()) return true; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 6983a1e0d8..042f2c14ab 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -261,7 +261,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc, Range = SourceRange(NameLoc); } - return CheckTypenameType(NNS, II, Range).getAsOpaquePtr(); + return CheckTypenameType(ETK_None, NNS, II, Range).getAsOpaquePtr(); } if (ObjectTypePtr) diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 7a3e83a497..1075f41399 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5128,7 +5128,8 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, if (!NNS) return true; - QualType T = CheckTypenameType(NNS, II, SourceRange(TypenameLoc, IdLoc)); + QualType T = CheckTypenameType(ETK_Typename, NNS, II, + SourceRange(TypenameLoc, IdLoc)); if (T.isNull()) return true; return T.getAsOpaquePtr(); @@ -5160,7 +5161,8 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS, /// \brief Build the type that describes a C++ typename specifier, /// e.g., "typename T::type". QualType -Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II, +Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, + NestedNameSpecifier *NNS, const IdentifierInfo &II, SourceRange Range) { CXXRecordDecl *CurrentInstantiation = 0; if (NNS->isDependent()) { @@ -5169,7 +5171,7 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II, // If the nested-name-specifier does not refer to the current // instantiation, then build a typename type. if (!CurrentInstantiation) - return Context.getDependentNameType(ETK_Typename, NNS, &II); + return Context.getDependentNameType(Keyword, NNS, &II); // The nested-name-specifier refers to the current instantiation, so the // "typename" keyword itself is superfluous. In C++03, the program is @@ -5205,7 +5207,7 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II, case LookupResult::NotFoundInCurrentInstantiation: // Okay, it's a member of an unknown instantiation. - return Context.getDependentNameType(ETK_Typename, NNS, &II); + return Context.getDependentNameType(Keyword, NNS, &II); case LookupResult::Found: if (TypeDecl *Type = dyn_cast(Result.getFoundDecl())) { diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 8b2aa4e308..302d405b7f 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -574,10 +574,9 @@ public: TagDecl::TagKind Kind = TagDecl::TK_enum; switch (Keyword) { case ETK_None: - // FIXME: Note the lack of the "typename" specifier! - // Fall through + // Fall through. case ETK_Typename: - return SemaRef.CheckTypenameType(NNS, *Id, SR); + return SemaRef.CheckTypenameType(Keyword, NNS, *Id, SR); case ETK_Class: Kind = TagDecl::TK_class; break; case ETK_Struct: Kind = TagDecl::TK_struct; break;