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:
Douglas Gregor 2011-02-28 22:42:13 +00:00
parent adef8fb003
commit 9cbc22ba2d
6 changed files with 40 additions and 42 deletions

View File

@ -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,

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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)

View File

@ -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);