forked from OSchip/llvm-project
Teach Sema::CheckTypenameType to use nested-name-specifiers with
source-location information. We don't actually preserve this information in any of the resulting TypeLocs (yet), so it doesn't matter. llvm-svn: 126693
This commit is contained in:
parent
adef8fb003
commit
9cbc22ba2d
|
@ -3416,10 +3416,9 @@ public:
|
|||
SourceLocation RAngleLoc);
|
||||
|
||||
QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
||||
NestedNameSpecifier *NNS,
|
||||
const IdentifierInfo &II,
|
||||
SourceLocation KeywordLoc,
|
||||
SourceRange NNSRange,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const IdentifierInfo &II,
|
||||
SourceLocation IILoc);
|
||||
|
||||
TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
|
||||
|
|
|
@ -88,8 +88,9 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
|
|||
// We know from the grammar that this name refers to a type,
|
||||
// so build a dependent node to describe the type.
|
||||
QualType T =
|
||||
CheckTypenameType(ETK_None, SS->getScopeRep(), II,
|
||||
SourceLocation(), SS->getRange(), NameLoc);
|
||||
CheckTypenameType(ETK_None, SourceLocation(),
|
||||
SS->getWithLocInContext(Context),
|
||||
II, NameLoc);
|
||||
return ParsedType::make(T);
|
||||
}
|
||||
|
||||
|
|
|
@ -1226,10 +1226,9 @@ Sema::ActOnMemInitializer(Decl *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(ETK_None,
|
||||
(NestedNameSpecifier *)SS.getScopeRep(),
|
||||
*MemberOrBase, SourceLocation(),
|
||||
SS.getRange(), IdLoc);
|
||||
BaseType = CheckTypenameType(ETK_None, SourceLocation(),
|
||||
SS.getWithLocInContext(Context),
|
||||
*MemberOrBase, IdLoc);
|
||||
if (BaseType.isNull())
|
||||
return true;
|
||||
|
||||
|
@ -6916,8 +6915,9 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
|
|||
if (isAllExplicitSpecializations) {
|
||||
ElaboratedTypeKeyword Keyword
|
||||
= TypeWithKeyword::getKeywordForTagTypeKind(Kind);
|
||||
QualType T = CheckTypenameType(Keyword, SS.getScopeRep(), *Name,
|
||||
TagLoc, SS.getRange(), NameLoc);
|
||||
QualType T = CheckTypenameType(Keyword, TagLoc,
|
||||
SS.getWithLocInContext(Context),
|
||||
*Name, NameLoc);
|
||||
if (T.isNull())
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -236,19 +236,11 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
|
|||
if (isDependent) {
|
||||
// We didn't find our type, but that's okay: it's dependent
|
||||
// anyway.
|
||||
NestedNameSpecifier *NNS = 0;
|
||||
SourceRange Range;
|
||||
if (SS.isSet()) {
|
||||
NNS = (NestedNameSpecifier *)SS.getScopeRep();
|
||||
Range = SourceRange(SS.getRange().getBegin(), NameLoc);
|
||||
} else {
|
||||
NNS = NestedNameSpecifier::Create(Context, &II);
|
||||
Range = SourceRange(NameLoc);
|
||||
}
|
||||
|
||||
QualType T = CheckTypenameType(ETK_None, NNS, II,
|
||||
SourceLocation(),
|
||||
Range, NameLoc);
|
||||
|
||||
// FIXME: What if we have no nested-name-specifier?
|
||||
QualType T = CheckTypenameType(ETK_None, SourceLocation(),
|
||||
SS.getWithLocInContext(Context),
|
||||
II, NameLoc);
|
||||
return ParsedType::make(T);
|
||||
}
|
||||
|
||||
|
|
|
@ -5901,18 +5901,17 @@ TypeResult
|
|||
Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
|
||||
const CXXScopeSpec &SS, const IdentifierInfo &II,
|
||||
SourceLocation IdLoc) {
|
||||
NestedNameSpecifier *NNS
|
||||
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
||||
if (!NNS)
|
||||
if (SS.isInvalid())
|
||||
return true;
|
||||
|
||||
|
||||
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
|
||||
!getLangOptions().CPlusPlus0x)
|
||||
Diag(TypenameLoc, diag::ext_typename_outside_of_template)
|
||||
<< FixItHint::CreateRemoval(TypenameLoc);
|
||||
|
||||
QualType T = CheckTypenameType(ETK_Typename, NNS, II,
|
||||
TypenameLoc, SS.getRange(), IdLoc);
|
||||
QualType T = CheckTypenameType(ETK_Typename, TypenameLoc,
|
||||
SS.getWithLocInContext(Context),
|
||||
II, IdLoc);
|
||||
if (T.isNull())
|
||||
return true;
|
||||
|
||||
|
@ -6017,19 +6016,22 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
|
|||
/// \brief Build the type that describes a C++ typename specifier,
|
||||
/// e.g., "typename T::type".
|
||||
QualType
|
||||
Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
||||
NestedNameSpecifier *NNS, const IdentifierInfo &II,
|
||||
SourceLocation KeywordLoc, SourceRange NNSRange,
|
||||
Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
||||
SourceLocation KeywordLoc,
|
||||
NestedNameSpecifierLoc QualifierLoc,
|
||||
const IdentifierInfo &II,
|
||||
SourceLocation IILoc) {
|
||||
CXXScopeSpec SS;
|
||||
SS.MakeTrivial(Context, NNS, NNSRange);
|
||||
SS.Adopt(QualifierLoc);
|
||||
|
||||
DeclContext *Ctx = computeDeclContext(SS);
|
||||
if (!Ctx) {
|
||||
// If the nested-name-specifier is dependent and couldn't be
|
||||
// resolved to a type, build a typename type.
|
||||
assert(NNS->isDependent());
|
||||
return Context.getDependentNameType(Keyword, NNS, &II);
|
||||
assert(QualifierLoc.getNestedNameSpecifier()->isDependent());
|
||||
return Context.getDependentNameType(Keyword,
|
||||
QualifierLoc.getNestedNameSpecifier(),
|
||||
&II);
|
||||
}
|
||||
|
||||
// If the nested-name-specifier refers to the current instantiation,
|
||||
|
@ -6054,7 +6056,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
|||
case LookupResult::FoundUnresolvedValue: {
|
||||
// We found a using declaration that is a value. Most likely, the using
|
||||
// declaration itself is meant to have the 'typename' keyword.
|
||||
SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(),
|
||||
SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(),
|
||||
IILoc);
|
||||
Diag(IILoc, diag::err_typename_refers_to_using_value_decl)
|
||||
<< Name << Ctx << FullRange;
|
||||
|
@ -6070,13 +6072,16 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
|||
|
||||
case LookupResult::NotFoundInCurrentInstantiation:
|
||||
// Okay, it's a member of an unknown instantiation.
|
||||
return Context.getDependentNameType(Keyword, NNS, &II);
|
||||
return Context.getDependentNameType(Keyword,
|
||||
QualifierLoc.getNestedNameSpecifier(),
|
||||
&II);
|
||||
|
||||
case LookupResult::Found:
|
||||
if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
|
||||
// We found a type. Build an ElaboratedType, since the
|
||||
// typename-specifier was just sugar.
|
||||
return Context.getElaboratedType(ETK_Typename, NNS,
|
||||
return Context.getElaboratedType(ETK_Typename,
|
||||
QualifierLoc.getNestedNameSpecifier(),
|
||||
Context.getTypeDeclType(Type));
|
||||
}
|
||||
|
||||
|
@ -6099,7 +6104,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
|||
|
||||
// If we get here, it's because name lookup did not find a
|
||||
// type. Emit an appropriate diagnostic and return an error.
|
||||
SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : NNSRange.getBegin(),
|
||||
SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(),
|
||||
IILoc);
|
||||
Diag(IILoc, DiagID) << FullRange << Name << Ctx;
|
||||
if (Referenced)
|
||||
|
|
|
@ -786,8 +786,9 @@ public:
|
|||
}
|
||||
|
||||
if (Keyword == ETK_None || Keyword == ETK_Typename)
|
||||
return SemaRef.CheckTypenameType(Keyword, NNS, *Id,
|
||||
KeywordLoc, NNSRange, IdLoc);
|
||||
return SemaRef.CheckTypenameType(Keyword, KeywordLoc,
|
||||
SS.getWithLocInContext(SemaRef.Context),
|
||||
*Id, IdLoc);
|
||||
|
||||
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
|
||||
|
||||
|
|
Loading…
Reference in New Issue