aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-03-01 18:12:44 +0000
committerDouglas Gregor <dgregor@apple.com>2011-03-01 18:12:44 +0000
commit9e876876afc13aa671cc11a17c19907c599b9ab9 (patch)
tree68df752f2a2f51b95147c6a1abcb047a4cb7e956
parent451f8caf37fb6691936f9003833e857e1d1dc987 (diff)
Reinstate the introduction of source-location information for
nested-name-speciciers within elaborated type names, e.g., enum clang::NestedNameSpecifier::SpecifierKind Fixes in this iteration include: (1) Compute the type-source range properly for a dependent template specialization type that starts with "template template-id ::", as in a member access expression dep->template f<T>::f() This is a latent bug I triggered with this change (because now we're checking the computed source ranges for dependent template specialization types). But the real problem was... (2) Make sure to set the qualifier range on a dependent template specialization type appropriately. This will go away once we push nested-name-specifier locations into dependent template specialization types, but it was the source of the valgrind errors on the buildbots. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126765 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h5
-rw-r--r--include/clang/AST/TypeLoc.h40
-rw-r--r--include/clang/Sema/Sema.h3
-rw-r--r--lib/AST/TypeLoc.cpp8
-rw-r--r--lib/Parse/ParseDecl.cpp4
-rw-r--r--lib/Parse/ParseDeclCXX.cpp4
-rw-r--r--lib/Parse/ParseExprCXX.cpp8
-rw-r--r--lib/Parse/Parser.cpp4
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp1
-rw-r--r--lib/Sema/SemaDecl.cpp36
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaTemplate.cpp13
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp8
-rw-r--r--lib/Sema/SemaType.cpp2
-rw-r--r--lib/Sema/TreeTransform.h34
-rw-r--r--lib/Serialization/ASTReader.cpp2
-rw-r--r--lib/Serialization/ASTWriter.cpp2
-rw-r--r--test/Index/annotate-nested-name-specifier.cpp13
-rw-r--r--test/Index/recursive-cxx-member-calls.cpp25
-rw-r--r--tools/libclang/CIndex.cpp8
20 files changed, 151 insertions, 71 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index aaf9f59ed3..972ff5c760 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -987,10 +987,9 @@ DEF_TRAVERSE_TYPELOC(AttributedType, {
TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
})
-// FIXME: use the sourceloc on qualifier?
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getTypePtr()->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
}
TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
})
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index a724f29fb0..591af2a02f 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1388,7 +1388,10 @@ class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
struct ElaboratedLocInfo {
SourceLocation KeywordLoc;
- SourceRange QualifierRange;
+
+ /// \brief Opaque data pointer used to reconstruct a nested-name-specifier
+ /// from
+ void *QualifierData;
};
class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
@@ -1403,27 +1406,29 @@ public:
this->getLocalData()->KeywordLoc = Loc;
}
- SourceRange getQualifierRange() const {
- return this->getLocalData()->QualifierRange;
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+ getLocalData()->QualifierData);
}
- void setQualifierRange(SourceRange Range) {
- this->getLocalData()->QualifierRange = Range;
+
+ void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+ assert(QualifierLoc.getNestedNameSpecifier()
+ == getTypePtr()->getQualifier() &&
+ "Inconsistent nested-name-specifier pointer");
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
- if (getQualifierRange().getEnd().isValid())
- return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
+ if (getQualifierLoc())
+ return SourceRange(getKeywordLoc(), getQualifierLoc().getEndLoc());
else
return SourceRange(getKeywordLoc());
else
- return getQualifierRange();
+ return getQualifierLoc().getSourceRange();
}
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setKeywordLoc(Loc);
- setQualifierRange(SourceRange(Loc));
- }
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
TypeLoc getNamedTypeLoc() const {
return getInnerTypeLoc();
@@ -1496,9 +1501,10 @@ public:
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
-// This is exactly the structure of an ElaboratedTypeLoc whose inner
-// type is some sort of TemplateSpecializationTypeLoc.
-struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+struct DependentTemplateSpecializationLocInfo {
+ SourceLocation KeywordLoc;
+ SourceLocation NameLoc;
+ SourceRange QualifierRange;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
// followed by a TemplateArgumentLocInfo[]
@@ -1563,8 +1569,10 @@ public:
SourceRange getLocalSourceRange() const {
if (getKeywordLoc().isValid())
return SourceRange(getKeywordLoc(), getRAngleLoc());
- else
+ else if (getQualifierRange().isValid())
return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
+ else
+ return SourceRange(getNameLoc(), getRAngleLoc());
}
void copy(DependentTemplateSpecializationTypeLoc Loc) {
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 12248c2f7f..633657a193 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -792,7 +792,8 @@ public:
Scope *S, CXXScopeSpec *SS = 0,
bool isClassName = false,
bool HasTrailingDot = false,
- ParsedType ObjectType = ParsedType());
+ ParsedType ObjectType = ParsedType(),
+ bool WantNontrivialTypeSourceInfo = false);
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
SourceLocation IILoc,
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 4b38dbac7b..98c46621f0 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -229,6 +229,14 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
return TL;
}
+void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
+ SourceLocation Loc) {
+ setKeywordLoc(Loc);
+ NestedNameSpecifierLocBuilder Builder;
+ Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
+ setQualifierLoc(Builder.getWithLocInContext(Context));
+}
+
void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
SourceLocation Loc) {
setKeywordLoc(Loc);
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 077edd700a..532c318a62 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1056,7 +1056,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
Next.getLocation(),
- getCurScope(), &SS);
+ getCurScope(), &SS,
+ false, false, ParsedType(),
+ /*NonTrivialSourceInfo=*/true);
// If the referenced identifier is not a type, then this declspec is
// erroneous: We already checked about that it has no type specifier, and
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index b3ad25b024..78fe4d2e31 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -577,7 +577,9 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
}
// We have an identifier; check whether it is actually a type.
- ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true);
+ ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true,
+ false, ParsedType(),
+ /*NonTrivialTypeSourceInfo=*/true);
if (!Type) {
Diag(IdLoc, diag::err_expected_class_name);
return true;
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 823c08c999..0e23e43a0d 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1472,7 +1472,9 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
// We have parsed a constructor name.
Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, getCurScope(),
- &SS, false),
+ &SS, false, false,
+ ParsedType(),
+ /*NonTrivialTypeSourceInfo=*/true),
IdLoc, IdLoc);
} else {
// We have parsed an identifier.
@@ -1510,7 +1512,9 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
Result.setConstructorName(Actions.getTypeName(*TemplateId->Name,
TemplateId->TemplateNameLoc,
getCurScope(),
- &SS, false),
+ &SS, false, false,
+ ParsedType(),
+ /*NontrivialTypeSourceInfo=*/true),
TemplateId->TemplateNameLoc,
TemplateId->RAngleLoc);
TemplateId->Destroy();
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 3ed070321d..ba3c03cdfb 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1091,7 +1091,9 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
if (ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
Tok.getLocation(), getCurScope(),
&SS, false,
- NextToken().is(tok::period))) {
+ NextToken().is(tok::period),
+ ParsedType(),
+ /*NonTrivialTypeSourceInfo*/true)) {
// This is a typename. Replace the current token in-place with an
// annotation type token.
Tok.setKind(tok::annot_typename);
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 8eb628f59b..6139aae555 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -675,6 +675,7 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
SpecTL.setRAngleLoc(RAngleLoc);
SpecTL.setKeywordLoc(SourceLocation());
SpecTL.setNameLoc(TemplateNameLoc);
+ SpecTL.setQualifierRange(SS.getRange());
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 062971724c..9d90499759 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -17,6 +17,7 @@
#include "clang/Sema/CXXFieldCollector.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
+#include "TypeLocBuilder.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
@@ -61,7 +62,8 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr) {
ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec *SS,
bool isClassName, bool HasTrailingDot,
- ParsedType ObjectTypePtr) {
+ ParsedType ObjectTypePtr,
+ bool WantNontrivialTypeSourceInfo) {
// Determine where we will perform name lookup.
DeclContext *LookupCtx = 0;
if (ObjectTypePtr) {
@@ -87,11 +89,15 @@ 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.
+ if (WantNontrivialTypeSourceInfo)
+ return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get();
+
+ NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context);
QualType T =
- CheckTypenameType(ETK_None, SourceLocation(),
- SS->getWithLocInContext(Context),
+ CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc,
II, NameLoc);
- return ParsedType::make(T);
+
+ return ParsedType::make(T);
}
return ParsedType();
@@ -190,9 +196,21 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
if (T.isNull())
T = Context.getTypeDeclType(TD);
- if (SS)
- T = getElaboratedType(ETK_None, *SS, T);
-
+ if (SS && SS->isNotEmpty()) {
+ if (WantNontrivialTypeSourceInfo) {
+ // Construct a type with type-source information.
+ TypeLocBuilder Builder;
+ Builder.pushTypeSpec(T).setNameLoc(NameLoc);
+
+ T = getElaboratedType(ETK_None, *SS, T);
+ ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
+ ElabTL.setKeywordLoc(SourceLocation());
+ ElabTL.setQualifierLoc(SS->getWithLocInContext(Context));
+ return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+ } else {
+ T = getElaboratedType(ETK_None, *SS, T);
+ }
+ }
} else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
if (!HasTrailingDot)
T = Context.getObjCInterfaceType(IDecl);
@@ -264,7 +282,9 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
Diag(Result->getLocation(), diag::note_previous_decl)
<< Result->getDeclName();
- SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS);
+ SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS,
+ false, false, ParsedType(),
+ /*NonTrivialTypeSourceInfo=*/true);
return true;
}
} else if (Lookup.empty()) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 1a7604f7ca..f760f3f871 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -6930,7 +6930,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
} else {
ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
TL.setKeywordLoc(TagLoc);
- TL.setQualifierRange(SS.getRange());
+ TL.setQualifierLoc(QualifierLoc);
cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(NameLoc);
}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index afb78170c9..a710f94436 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1821,12 +1821,12 @@ TypeResult Sema::ActOnTagTemplateIdType(CXXScopeSpec &SS,
ElaboratedTypeKeyword Keyword
= TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
- QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
+ QualType ElabType = Context.getElaboratedType(Keyword, SS.getScopeRep(), Type);
TypeSourceInfo *ElabDI = Context.CreateTypeSourceInfo(ElabType);
ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(ElabDI->getTypeLoc());
TL.setKeywordLoc(TagLoc);
- TL.setQualifierRange(SS.getRange());
+ TL.setQualifierLoc(SS.getWithLocInContext(Context));
TL.getNamedTypeLoc().initializeFullCopy(DI->getTypeLoc());
return CreateParsedType(ElabType, ElabDI);
}
@@ -5910,8 +5910,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
<< FixItHint::CreateRemoval(TypenameLoc);
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
- QualType T = CheckTypenameType(ETK_Typename, TypenameLoc, QualifierLoc,
- II, IdLoc);
+ QualType T = CheckTypenameType(TypenameLoc.isValid()? ETK_Typename : ETK_None,
+ TypenameLoc, QualifierLoc, II, IdLoc);
if (T.isNull())
return true;
@@ -5924,7 +5924,7 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
} else {
ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
TL.setKeywordLoc(TypenameLoc);
- TL.setQualifierRange(SS.getRange());
+ TL.setQualifierLoc(QualifierLoc);
cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
}
@@ -5996,7 +5996,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T);
ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
TL.setKeywordLoc(TypenameLoc);
- TL.setQualifierRange(SS.getRange());
+ TL.setQualifierLoc(SS.getWithLocInContext(Context));
+
TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
return CreateParsedType(T, TSI);
}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index ae0ac9cbe3..c0f130da88 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -730,7 +730,8 @@ namespace {
/// elaborated type.
QualType RebuildElaboratedType(SourceLocation KeywordLoc,
ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType T);
+ NestedNameSpecifierLoc QualifierLoc,
+ QualType T);
TemplateName TransformTemplateName(TemplateName Name,
QualType ObjectType = QualType(),
@@ -892,7 +893,7 @@ VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
QualType
TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
+ NestedNameSpecifierLoc QualifierLoc,
QualType T) {
if (const TagType *TT = T->getAs<TagType>()) {
TagDecl* TD = TT->getDecl();
@@ -918,7 +919,8 @@ TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(KeywordLoc,
Keyword,
- NNS, T);
+ QualifierLoc,
+ T);
}
TemplateName TemplateInstantiator::TransformTemplateName(TemplateName Name,
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 9d35b1a562..afd118e2ca 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2237,7 +2237,7 @@ namespace {
? DS.getTypeSpecTypeLoc()
: SourceLocation());
const CXXScopeSpec& SS = DS.getTypeSpecScope();
- TL.setQualifierRange(SS.isEmpty() ? SourceRange(): SS.getRange());
+ TL.setQualifierLoc(SS.getWithLocInContext(Context));
Visit(TL.getNextTypeLoc().getUnqualifiedLoc());
}
void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index c7a11de1aa..5485dfb7e4 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -723,8 +723,11 @@ public:
/// Subclasses may override this routine to provide different behavior.
QualType RebuildElaboratedType(SourceLocation KeywordLoc,
ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType Named) {
- return SemaRef.Context.getElaboratedType(Keyword, NNS, Named);
+ NestedNameSpecifierLoc QualifierLoc,
+ QualType Named) {
+ return SemaRef.Context.getElaboratedType(Keyword,
+ QualifierLoc.getNestedNameSpecifier(),
+ Named);
}
/// \brief Build a new typename type that refers to a template-id.
@@ -4436,12 +4439,12 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
ElaboratedTypeLoc TL) {
const ElaboratedType *T = TL.getTypePtr();
- NestedNameSpecifier *NNS = 0;
+ NestedNameSpecifierLoc QualifierLoc;
// NOTE: the qualifier in an ElaboratedType is optional.
- if (T->getQualifier() != 0) {
- NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
- TL.getQualifierRange());
- if (!NNS)
+ if (TL.getQualifierLoc()) {
+ QualifierLoc
+ = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
+ if (!QualifierLoc)
return QualType();
}
@@ -4451,18 +4454,18 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
- NNS != T->getQualifier() ||
+ QualifierLoc != TL.getQualifierLoc() ||
NamedT != T->getNamedType()) {
Result = getDerived().RebuildElaboratedType(TL.getKeywordLoc(),
- T->getKeyword(), NNS, NamedT);
+ T->getKeyword(),
+ QualifierLoc, NamedT);
if (Result.isNull())
return QualType();
}
ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
- NewTL.setQualifierRange(TL.getQualifierRange());
-
+ NewTL.setQualifierLoc(QualifierLoc);
return Result;
}
@@ -4550,7 +4553,7 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
- NewTL.setQualifierRange(QualifierLoc.getSourceRange());
+ NewTL.setQualifierLoc(QualifierLoc);
} else {
DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
@@ -4621,7 +4624,12 @@ QualType TreeTransform<Derived>::
// Copy information relevant to the elaborated type.
ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
NewTL.setKeywordLoc(TL.getKeywordLoc());
- NewTL.setQualifierRange(TL.getQualifierRange());
+
+ // FIXME: DependentTemplateSpecializationType needs better source-location
+ // info.
+ NestedNameSpecifierLocBuilder Builder;
+ Builder.MakeTrivial(SemaRef.Context, NNS, TL.getQualifierRange());
+ NewTL.setQualifierLoc(Builder.getWithLocInContext(SemaRef.Context));
} else {
TypeLoc NewTL(Result, TL.getOpaqueData());
TLB.pushFullCopy(NewTL);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index c0b7d72488..aefc1d1b65 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3520,7 +3520,7 @@ void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
}
void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
TL.setKeywordLoc(ReadSourceLocation(Record, Idx));
- TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx));
+ TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
}
void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation(Record, Idx));
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 7e0af0963d..e9ad4a81b4 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -532,7 +532,7 @@ void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
}
void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
- Writer.AddSourceRange(TL.getQualifierRange(), Record);
+ Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
}
void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
Writer.AddSourceLocation(TL.getNameLoc(), Record);
diff --git a/test/Index/annotate-nested-name-specifier.cpp b/test/Index/annotate-nested-name-specifier.cpp
index c934839cd2..beb0e40ac0 100644
--- a/test/Index/annotate-nested-name-specifier.cpp
+++ b/test/Index/annotate-nested-name-specifier.cpp
@@ -307,4 +307,17 @@ struct X5 {
// CHECK: Identifier: "iterator" [100:54 - 100:62] TypedefDecl=iter_type:100:63 (Definition)
// CHECK: Identifier: "iter_type" [100:63 - 100:72] TypedefDecl=iter_type:100:63 (Definition)
+// CHECK: Keyword: "typedef" [101:3 - 101:10] ClassTemplate=X5:98:8 (Definition)
+// CHECK: Keyword: "typename" [101:11 - 101:19] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "outer_alias" [101:20 - 101:31] NamespaceRef=outer_alias:10:11
+// CHECK: Punctuation: "::" [101:31 - 101:33] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "inner" [101:33 - 101:38] NamespaceRef=inner:62:13
+// CHECK: Punctuation: "::" [101:38 - 101:40] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "vector" [101:40 - 101:46] TemplateRef=vector:4:12
+// CHECK: Punctuation: "<" [101:46 - 101:47] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Keyword: "int" [101:47 - 101:50] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Punctuation: ">" [101:50 - 101:51] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Punctuation: "::" [101:51 - 101:53] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "iterator" [101:53 - 101:61] TypeRef=iterator:5:18
+// CHECK: Identifier: "int_ptr_type" [101:62 - 101:74] TypedefDecl=int_ptr_type:101:62 (Definition)
diff --git a/test/Index/recursive-cxx-member-calls.cpp b/test/Index/recursive-cxx-member-calls.cpp
index 0eb90585af..f226b25b1f 100644
--- a/test/Index/recursive-cxx-member-calls.cpp
+++ b/test/Index/recursive-cxx-member-calls.cpp
@@ -771,18 +771,18 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Literal: "1" [75:61 - 75:62] UnexposedExpr=
// CHECK-tokens: Punctuation: ";" [75:62 - 75:63] UnexposedStmt=
// CHECK-tokens: Punctuation: "}" [76:3 - 76:4] UnexposedStmt=
-// CHECK-tokens: Identifier: "llvm" [77:3 - 77:7] CXXMethod=getName:77:19 (Definition)
+// CHECK-tokens: Identifier: "llvm" [77:3 - 77:7] NamespaceRef=llvm:37:11
// CHECK-tokens: Punctuation: "::" [77:7 - 77:9] CXXMethod=getName:77:19 (Definition)
-// CHECK-tokens: Identifier: "StringRef" [77:9 - 77:18] CXXMethod=getName:77:19 (Definition)
+// CHECK-tokens: Identifier: "StringRef" [77:9 - 77:18] TypeRef=class llvm::StringRef:38:7
// CHECK-tokens: Identifier: "getName" [77:19 - 77:26] CXXMethod=getName:77:19 (Definition)
// CHECK-tokens: Punctuation: "(" [77:26 - 77:27] CXXMethod=getName:77:19 (Definition)
// CHECK-tokens: Punctuation: ")" [77:27 - 77:28] CXXMethod=getName:77:19 (Definition)
// CHECK-tokens: Keyword: "const" [77:29 - 77:34] CXXMethod=getName:77:19 (Definition)
// CHECK-tokens: Punctuation: "{" [77:35 - 77:36] UnexposedStmt=
// CHECK-tokens: Keyword: "return" [78:5 - 78:11] UnexposedStmt=
-// CHECK-tokens: Identifier: "llvm" [78:12 - 78:16] CallExpr=StringRef:49:3
+// CHECK-tokens: Identifier: "llvm" [78:12 - 78:16] NamespaceRef=llvm:37:11
// CHECK-tokens: Punctuation: "::" [78:16 - 78:18] CallExpr=StringRef:49:3
-// CHECK-tokens: Identifier: "StringRef" [78:18 - 78:27] CallExpr=StringRef:49:3
+// CHECK-tokens: Identifier: "StringRef" [78:18 - 78:27] TypeRef=class llvm::StringRef:38:7
// CHECK-tokens: Punctuation: "(" [78:27 - 78:28] CallExpr=StringRef:49:3
// CHECK-tokens: Identifier: "getNameStart" [78:28 - 78:40] MemberRefExpr=getNameStart:68:15
// CHECK-tokens: Punctuation: "(" [78:40 - 78:41] CallExpr=getNameStart:68:15
@@ -892,9 +892,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Keyword: "namespace" [98:7 - 98:16] UsingDirective=:98:17
// CHECK-tokens: Identifier: "clang" [98:17 - 98:22] NamespaceRef=clang:10:17
// CHECK-tokens: Punctuation: ";" [98:22 - 98:23]
-// CHECK-tokens: Identifier: "AttributeList" [100:1 - 100:14] CXXMethod=getKind:100:36 (Definition)
+// CHECK-tokens: Identifier: "AttributeList" [100:1 - 100:14] TypeRef=class clang::AttributeList:12:9
// CHECK-tokens: Punctuation: "::" [100:14 - 100:16] CXXMethod=getKind:100:36 (Definition)
-// CHECK-tokens: Identifier: "Kind" [100:16 - 100:20] CXXMethod=getKind:100:36 (Definition)
+// CHECK-tokens: Identifier: "Kind" [100:16 - 100:20] TypeRef=enum clang::AttributeList::Kind:13:10
// CHECK-tokens: Identifier: "AttributeList" [100:21 - 100:34] TypeRef=class clang::AttributeList:12:9
// CHECK-tokens: Punctuation: "::" [100:34 - 100:36] CXXMethod=getKind:100:36 (Definition)
// CHECK-tokens: Identifier: "getKind" [100:36 - 100:43] CXXMethod=getKind:100:36 (Definition)
@@ -905,9 +905,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Identifier: "Name" [100:67 - 100:71] ParmDecl=Name:100:67 (Definition)
// CHECK-tokens: Punctuation: ")" [100:71 - 100:72] CXXMethod=getKind:100:36 (Definition)
// CHECK-tokens: Punctuation: "{" [100:73 - 100:74] UnexposedStmt=
-// CHECK-tokens: Identifier: "llvm" [101:3 - 101:7] VarDecl=AttrName:101:19 (Definition)
+// CHECK-tokens: Identifier: "llvm" [101:3 - 101:7] NamespaceRef=llvm:82:11
// CHECK-tokens: Punctuation: "::" [101:7 - 101:9] VarDecl=AttrName:101:19 (Definition)
-// CHECK-tokens: Identifier: "StringRef" [101:9 - 101:18] VarDecl=AttrName:101:19 (Definition)
+// CHECK-tokens: Identifier: "StringRef" [101:9 - 101:18] TypeRef=class llvm::StringRef:38:7
// CHECK-tokens: Identifier: "AttrName" [101:19 - 101:27] VarDecl=AttrName:101:19 (Definition)
// CHECK-tokens: Punctuation: "=" [101:28 - 101:29] VarDecl=AttrName:101:19 (Definition)
// CHECK-tokens: Identifier: "Name" [101:30 - 101:34] DeclRefExpr=Name:100:67
@@ -950,13 +950,14 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Punctuation: ")" [103:54 - 103:55] CallExpr=substr:60:13
// CHECK-tokens: Punctuation: ";" [103:55 - 103:56] UnexposedStmt=
// CHECK-tokens: Keyword: "return" [105:3 - 105:9] UnexposedStmt=
+// FIXME: Missing "llvm" namespace reference below
// CHECK-tokens: Identifier: "llvm" [105:10 - 105:14] UnexposedStmt=
// CHECK-tokens: Punctuation: "::" [105:14 - 105:16] UnexposedStmt=
// CHECK-tokens: Identifier: "StringSwitch" [105:16 - 105:28] TemplateRef=StringSwitch:83:47
-// CHECK-tokens: Punctuation: "<" [105:29 - 105:30] CallExpr=StringSwitch:87:12
-// CHECK-tokens: Identifier: "AttributeList" [105:31 - 105:44] CallExpr=StringSwitch:87:12
-// CHECK-tokens: Punctuation: "::" [105:44 - 105:46] CallExpr=StringSwitch:87:12
-// CHECK-tokens: Identifier: "Kind" [105:46 - 105:50] CallExpr=StringSwitch:87:12
+// CHECK-tokens: Punctuation: "<" [105:29 - 105:30] UnexposedExpr=StringSwitch:87:12
+// CHECK-tokens: Identifier: "AttributeList" [105:31 - 105:44] TypeRef=class clang::AttributeList:12:9
+// CHECK-tokens: Punctuation: "::" [105:44 - 105:46] UnexposedExpr=StringSwitch:87:12
+// CHECK-tokens: Identifier: "Kind" [105:46 - 105:50] TypeRef=enum clang::AttributeList::Kind:13:10
// CHECK-tokens: Punctuation: ">" [105:51 - 105:52] CallExpr=StringSwitch:87:12
// CHECK-tokens: Punctuation: "(" [105:53 - 105:54] CallExpr=StringSwitch:87:12
// CHECK-tokens: Identifier: "AttrName" [105:54 - 105:62] DeclRefExpr=AttrName:101:19
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 72d930ef9e..8c2111d4ad 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -343,6 +343,7 @@ public:
bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
+ bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
// Data-recursive visitor functions.
bool IsInRegionOfInterest(CXCursor C);
@@ -1511,6 +1512,13 @@ bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
return false;
}
+bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+ if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+ return true;
+
+ return Visit(TL.getNamedTypeLoc());
+}
+
bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
return Visit(TL.getPatternLoc());
}