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! llvm-svn: 102243
This commit is contained in:
parent
fb278831aa
commit
bbdf20acd0
|
@ -3017,7 +3017,8 @@ public:
|
||||||
ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
|
ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
|
||||||
SourceLocation TemplateLoc, TypeTy *Ty);
|
SourceLocation TemplateLoc, TypeTy *Ty);
|
||||||
|
|
||||||
QualType CheckTypenameType(NestedNameSpecifier *NNS,
|
QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
||||||
|
NestedNameSpecifier *NNS,
|
||||||
const IdentifierInfo &II,
|
const IdentifierInfo &II,
|
||||||
SourceRange Range);
|
SourceRange Range);
|
||||||
|
|
||||||
|
|
|
@ -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
|
// We know from the grammar that this name refers to a type, so build a
|
||||||
// DependentNameType node to describe the type.
|
// DependentNameType node to describe the type.
|
||||||
// FIXME: Record somewhere that this DependentNameType node has no "typename"
|
return CheckTypenameType(ETK_None,
|
||||||
// keyword associated with it.
|
(NestedNameSpecifier *)SS->getScopeRep(),
|
||||||
return CheckTypenameType((NestedNameSpecifier *)SS->getScopeRep(),
|
|
||||||
II, SS->getRange()).getAsOpaquePtr();
|
II, SS->getRange()).getAsOpaquePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1088,7 +1088,8 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
|
||||||
if (!NotUnknownSpecialization) {
|
if (!NotUnknownSpecialization) {
|
||||||
// When the scope specifier can refer to a member of an unknown
|
// When the scope specifier can refer to a member of an unknown
|
||||||
// specialization, we take it as a type name.
|
// specialization, we take it as a type name.
|
||||||
BaseType = CheckTypenameType((NestedNameSpecifier *)SS.getScopeRep(),
|
BaseType = CheckTypenameType(ETK_None,
|
||||||
|
(NestedNameSpecifier *)SS.getScopeRep(),
|
||||||
*MemberOrBase, SS.getRange());
|
*MemberOrBase, SS.getRange());
|
||||||
if (BaseType.isNull())
|
if (BaseType.isNull())
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -261,7 +261,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
|
||||||
Range = SourceRange(NameLoc);
|
Range = SourceRange(NameLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CheckTypenameType(NNS, II, Range).getAsOpaquePtr();
|
return CheckTypenameType(ETK_None, NNS, II, Range).getAsOpaquePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectTypePtr)
|
if (ObjectTypePtr)
|
||||||
|
|
|
@ -5128,7 +5128,8 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
|
||||||
if (!NNS)
|
if (!NNS)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
QualType T = CheckTypenameType(NNS, II, SourceRange(TypenameLoc, IdLoc));
|
QualType T = CheckTypenameType(ETK_Typename, NNS, II,
|
||||||
|
SourceRange(TypenameLoc, IdLoc));
|
||||||
if (T.isNull())
|
if (T.isNull())
|
||||||
return true;
|
return true;
|
||||||
return T.getAsOpaquePtr();
|
return T.getAsOpaquePtr();
|
||||||
|
@ -5160,7 +5161,8 @@ Sema::ActOnTypenameType(SourceLocation TypenameLoc, const CXXScopeSpec &SS,
|
||||||
/// \brief Build the type that describes a C++ typename specifier,
|
/// \brief Build the type that describes a C++ typename specifier,
|
||||||
/// e.g., "typename T::type".
|
/// e.g., "typename T::type".
|
||||||
QualType
|
QualType
|
||||||
Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
|
Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
||||||
|
NestedNameSpecifier *NNS, const IdentifierInfo &II,
|
||||||
SourceRange Range) {
|
SourceRange Range) {
|
||||||
CXXRecordDecl *CurrentInstantiation = 0;
|
CXXRecordDecl *CurrentInstantiation = 0;
|
||||||
if (NNS->isDependent()) {
|
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
|
// If the nested-name-specifier does not refer to the current
|
||||||
// instantiation, then build a typename type.
|
// instantiation, then build a typename type.
|
||||||
if (!CurrentInstantiation)
|
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
|
// The nested-name-specifier refers to the current instantiation, so the
|
||||||
// "typename" keyword itself is superfluous. In C++03, the program is
|
// "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:
|
case LookupResult::NotFoundInCurrentInstantiation:
|
||||||
// Okay, it's a member of an unknown instantiation.
|
// 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:
|
case LookupResult::Found:
|
||||||
if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
|
if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
|
||||||
|
|
|
@ -574,10 +574,9 @@ public:
|
||||||
TagDecl::TagKind Kind = TagDecl::TK_enum;
|
TagDecl::TagKind Kind = TagDecl::TK_enum;
|
||||||
switch (Keyword) {
|
switch (Keyword) {
|
||||||
case ETK_None:
|
case ETK_None:
|
||||||
// FIXME: Note the lack of the "typename" specifier!
|
// Fall through.
|
||||||
// Fall through
|
|
||||||
case ETK_Typename:
|
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_Class: Kind = TagDecl::TK_class; break;
|
||||||
case ETK_Struct: Kind = TagDecl::TK_struct; break;
|
case ETK_Struct: Kind = TagDecl::TK_struct; break;
|
||||||
|
|
Loading…
Reference in New Issue