diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index aaf9f59ed33e..972ff5c7604f 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/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/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index a724f29fb043..594aeb1a2ed1 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -1388,7 +1388,10 @@ class AutoTypeLoc : public InheritingConcreteTypeLocgetLocalData()->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[] diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 12248c2f7f9f..633657a1939a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/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/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 4b38dbac7b28..98c46621f038 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/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/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 3ed070321dae..ba3c03cdfb52 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 062971724c1f..25ac11a6f8f9 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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(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(IIDecl)) { if (!HasTrailingDot) T = Context.getObjCInterfaceType(IDecl); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 1a7604f7ca72..f760f3f87108 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6930,7 +6930,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, } else { ElaboratedTypeLoc TL = cast(TSI->getTypeLoc()); TL.setKeywordLoc(TagLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(QualifierLoc); cast(TL.getNamedTypeLoc()).setNameLoc(NameLoc); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index cdb35a20c099..fbb724653350 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/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(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(TSI->getTypeLoc()); TL.setKeywordLoc(TypenameLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(QualifierLoc); cast(TL.getNamedTypeLoc()).setNameLoc(IdLoc); } @@ -5964,7 +5964,7 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, // type. TypeLocBuilder Builder; TemplateSpecializationTypeLoc SpecTL - = Builder.push(T); + = Builder.push(T); // FIXME: No place to set the location of the 'template' keyword! SpecTL.setLAngleLoc(LAngleLoc); @@ -5973,14 +5973,10 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); - // FIXME: This is a hack. We really want to push the nested-name-specifier - // into TemplateSpecializationType. - - /* Note: NNS already embedded in template specialization type T. */ - T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T); + T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T); ElaboratedTypeLoc TL = Builder.push(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/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index ae0ac9cbe35c..c0f130da88ac 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/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()) { TagDecl* TD = TT->getDecl(); @@ -918,7 +919,8 @@ TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc, return TreeTransform::RebuildElaboratedType(KeywordLoc, Keyword, - NNS, T); + QualifierLoc, + T); } TemplateName TemplateInstantiator::TransformTemplateName(TemplateName Name, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 2d807ceb2586..1c8a58b07ce5 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/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/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c7a11de1aaf7..5485dfb7e4aa 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/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::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::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(Result); NewTL.setKeywordLoc(TL.getKeywordLoc()); - NewTL.setQualifierRange(TL.getQualifierRange()); - + NewTL.setQualifierLoc(QualifierLoc); return Result; } @@ -4550,7 +4553,7 @@ QualType TreeTransform::TransformDependentNameType(TypeLocBuilder &TLB, ElaboratedTypeLoc NewTL = TLB.push(Result); NewTL.setKeywordLoc(TL.getKeywordLoc()); - NewTL.setQualifierRange(QualifierLoc.getSourceRange()); + NewTL.setQualifierLoc(QualifierLoc); } else { DependentNameTypeLoc NewTL = TLB.push(Result); NewTL.setKeywordLoc(TL.getKeywordLoc()); @@ -4621,7 +4624,12 @@ QualType TreeTransform:: // Copy information relevant to the elaborated type. ElaboratedTypeLoc NewTL = TLB.push(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/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index bb4b5667b178..e687d2ccae91 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3518,7 +3518,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/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index aea3e37659d4..638087a8f869 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/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/clang/test/Index/annotate-nested-name-specifier.cpp b/clang/test/Index/annotate-nested-name-specifier.cpp index c934839cd2f3..beb0e40ac04c 100644 --- a/clang/test/Index/annotate-nested-name-specifier.cpp +++ b/clang/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/clang/test/Index/recursive-cxx-member-calls.cpp b/clang/test/Index/recursive-cxx-member-calls.cpp index 0eb90585af87..6982714e502b 100644 --- a/clang/test/Index/recursive-cxx-member-calls.cpp +++ b/clang/test/Index/recursive-cxx-member-calls.cpp @@ -771,7 +771,7 @@ 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: "getName" [77:19 - 77:26] CXXMethod=getName:77:19 (Definition) @@ -780,9 +780,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) { // 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,7 +892,7 @@ 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: "AttributeList" [100:21 - 100:34] TypeRef=class clang::AttributeList:12:9 @@ -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/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 72d930ef9e24..8c2111d4ad9f 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/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()); }