diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-03-01 01:34:45 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-03-01 01:34:45 +0000 |
commit | 2494dd024b392b8def58bf067cc94b51c214cf77 (patch) | |
tree | aea420ed3f1ec2a060a2192097bad0728f1eb689 | |
parent | 7636d8853f4b96be2fa394eb59047ccad37efa4c (diff) |
Push nested-name-specifier source location information into
DependentNameTypeLoc. Teach the recursive AST visitor and libclang how to
walk DependentNameTypeLoc nodes.
Also, teach libclang about TypedefDecl source ranges, so that we get
those. The massive churn in test/Index/recursive-cxx-member-calls.cpp
is a good thing: we're annotating a lot more of this test correctly
now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126729 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 3 | ||||
-rw-r--r-- | include/clang/AST/TypeLoc.h | 26 | ||||
-rw-r--r-- | lib/AST/TypeLoc.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 37 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 2 | ||||
-rw-r--r-- | test/Index/annotate-nested-name-specifier.cpp | 60 | ||||
-rw-r--r-- | test/Index/recursive-cxx-member-calls.cpp | 36 | ||||
-rw-r--r-- | test/SemaCXX/nested-name-spec-locations.cpp | 11 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 67 |
13 files changed, 183 insertions, 87 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index ebd16f8cc4..aaf9f59ed3 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -995,9 +995,8 @@ DEF_TRAVERSE_TYPELOC(ElaboratedType, { TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc())); }) -// FIXME: use the sourceloc on qualifier? DEF_TRAVERSE_TYPELOC(DependentNameType, { - TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier())); + TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); }) DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, { diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index c7f5ee7633..a724f29fb0 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -1444,6 +1444,9 @@ public: // type is some sort of TypeDeclTypeLoc. struct DependentNameLocInfo : ElaboratedLocInfo { SourceLocation NameLoc; + + /// \brief Data associated with the nested-name-specifier location. + void *QualifierData; }; class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, @@ -1458,13 +1461,18 @@ 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(); } - + SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; } @@ -1476,7 +1484,7 @@ public: if (getKeywordLoc().isValid()) return SourceRange(getKeywordLoc(), getNameLoc()); else - return SourceRange(getQualifierRange().getBegin(), getNameLoc()); + return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); } void copy(DependentNameTypeLoc Loc) { @@ -1485,11 +1493,7 @@ public: memcpy(Data, Loc.Data, size); } - void initializeLocal(ASTContext &Context, SourceLocation Loc) { - setKeywordLoc(Loc); - setQualifierRange(SourceRange(Loc)); - setNameLoc(Loc); - } + void initializeLocal(ASTContext &Context, SourceLocation Loc); }; // This is exactly the structure of an ElaboratedTypeLoc whose inner diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index 14db7f83c2..4b38dbac7b 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -229,6 +229,15 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { return TL; } +void DependentNameTypeLoc::initializeLocal(ASTContext &Context, + SourceLocation Loc) { + setKeywordLoc(Loc); + NestedNameSpecifierLocBuilder Builder; + Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); + setQualifierLoc(Builder.getWithLocInContext(Context)); + setNameLoc(Loc); +} + void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, unsigned NumArgs, const TemplateArgument *Args, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 40e6a94f39..1a7604f7ca 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6913,10 +6913,10 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, // about the template header and build an appropriate non-templated // friend. TODO: for source fidelity, remember the headers. if (isAllExplicitSpecializations) { + NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); ElaboratedTypeKeyword Keyword = TypeWithKeyword::getKeywordForTagTypeKind(Kind); - QualType T = CheckTypenameType(Keyword, TagLoc, - SS.getWithLocInContext(Context), + QualType T = CheckTypenameType(Keyword, TagLoc, QualifierLoc, *Name, NameLoc); if (T.isNull()) return 0; @@ -6925,7 +6925,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, if (isa<DependentNameType>(T)) { DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); TL.setKeywordLoc(TagLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(QualifierLoc); TL.setNameLoc(NameLoc); } else { ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); @@ -6949,7 +6949,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); TL.setKeywordLoc(TagLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(SS.getWithLocInContext(Context)); TL.setNameLoc(NameLoc); FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc, diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index b3187de025..cdb35a20c0 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5909,8 +5909,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, Diag(TypenameLoc, diag::ext_typename_outside_of_template) << FixItHint::CreateRemoval(TypenameLoc); - QualType T = CheckTypenameType(ETK_Typename, TypenameLoc, - SS.getWithLocInContext(Context), + NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); + QualType T = CheckTypenameType(ETK_Typename, TypenameLoc, QualifierLoc, II, IdLoc); if (T.isNull()) return true; @@ -5919,7 +5919,7 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, if (isa<DependentNameType>(T)) { DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); TL.setKeywordLoc(TypenameLoc); - TL.setQualifierRange(SS.getRange()); + TL.setQualifierLoc(QualifierLoc); TL.setNameLoc(IdLoc); } else { ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index ba80076003..2d807ceb25 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -2255,8 +2255,7 @@ namespace { ? DS.getTypeSpecTypeLoc() : SourceLocation()); const CXXScopeSpec& SS = DS.getTypeSpecScope(); - TL.setQualifierRange(SS.isEmpty() ? SourceRange() : SS.getRange()); - // FIXME: load appropriate source location. + TL.setQualifierLoc(SS.getWithLocInContext(Context)); TL.setNameLoc(DS.getTypeSpecTypeLoc()); } void VisitDependentTemplateSpecializationTypeLoc( diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index b36fd76677..c7a11de1aa 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -771,23 +771,23 @@ public: /// (or elaborated type). Subclasses may override this routine to provide /// different behavior. QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *NNS, - const IdentifierInfo *Id, SourceLocation KeywordLoc, - SourceRange NNSRange, + NestedNameSpecifierLoc QualifierLoc, + const IdentifierInfo *Id, SourceLocation IdLoc) { CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, NNS, NNSRange); + SS.Adopt(QualifierLoc); - if (NNS->isDependent()) { + if (QualifierLoc.getNestedNameSpecifier()->isDependent()) { // If the name is still dependent, just build a new dependent name type. if (!SemaRef.computeDeclContext(SS)) - return SemaRef.Context.getDependentNameType(Keyword, NNS, Id); + return SemaRef.Context.getDependentNameType(Keyword, + QualifierLoc.getNestedNameSpecifier(), + Id); } if (Keyword == ETK_None || Keyword == ETK_Typename) - return SemaRef.CheckTypenameType(Keyword, KeywordLoc, - SS.getWithLocInContext(SemaRef.Context), + return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc, *Id, IdLoc); TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); @@ -858,7 +858,9 @@ public: // Build the elaborated-type-specifier type. QualType T = SemaRef.Context.getTypeDeclType(Tag); - return SemaRef.Context.getElaboratedType(Keyword, NNS, T); + return SemaRef.Context.getElaboratedType(Keyword, + QualifierLoc.getNestedNameSpecifier(), + T); } /// \brief Build a new pack expansion type. @@ -4528,17 +4530,16 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, DependentNameTypeLoc TL) { const DependentNameType *T = TL.getTypePtr(); - NestedNameSpecifier *NNS - = getDerived().TransformNestedNameSpecifier(T->getQualifier(), - TL.getQualifierRange()); - if (!NNS) + NestedNameSpecifierLoc QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); + if (!QualifierLoc) return QualType(); QualType Result - = getDerived().RebuildDependentNameType(T->getKeyword(), NNS, - T->getIdentifier(), + = getDerived().RebuildDependentNameType(T->getKeyword(), TL.getKeywordLoc(), - TL.getQualifierRange(), + QualifierLoc, + T->getIdentifier(), TL.getNameLoc()); if (Result.isNull()) return QualType(); @@ -4549,11 +4550,11 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); NewTL.setKeywordLoc(TL.getKeywordLoc()); - NewTL.setQualifierRange(TL.getQualifierRange()); + NewTL.setQualifierRange(QualifierLoc.getSourceRange()); } else { DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); NewTL.setKeywordLoc(TL.getKeywordLoc()); - NewTL.setQualifierRange(TL.getQualifierRange()); + NewTL.setQualifierLoc(QualifierLoc); NewTL.setNameLoc(TL.getNameLoc()); } return Result; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index ffbcbdb9b1..bb4b5667b1 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3525,7 +3525,7 @@ void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { } void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { TL.setKeywordLoc(ReadSourceLocation(Record, Idx)); - TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx)); + TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx)); TL.setNameLoc(ReadSourceLocation(Record, Idx)); } void TypeLocReader::VisitDependentTemplateSpecializationTypeLoc( diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 383ca3dffc..aea3e37659 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -539,7 +539,7 @@ void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { } void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { Writer.AddSourceLocation(TL.getKeywordLoc(), Record); - Writer.AddSourceRange(TL.getQualifierRange(), Record); + Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record); Writer.AddSourceLocation(TL.getNameLoc(), Record); } void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc( diff --git a/test/Index/annotate-nested-name-specifier.cpp b/test/Index/annotate-nested-name-specifier.cpp index 766f21a5b6..c934839cd2 100644 --- a/test/Index/annotate-nested-name-specifier.cpp +++ b/test/Index/annotate-nested-name-specifier.cpp @@ -93,7 +93,15 @@ struct X4<Integer> { } }; -// RUN: c-index-test -test-annotate-tokens=%s:13:1:93:1 %s | FileCheck %s + +template<typename T> +struct X5 { + typedef T type; + typedef typename outer_alias::inner::vector<type>::iterator iter_type; + typedef typename outer_alias::inner::vector<int>::iterator int_ptr_type; +}; + +// RUN: c-index-test -test-annotate-tokens=%s:13:1:102:1 %s | FileCheck %s // CHECK: Keyword: "using" [14:1 - 14:6] UsingDeclaration=vector[4:12] // CHECK: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11 @@ -115,7 +123,38 @@ struct X4<Integer> { // CHECK: Punctuation: "::" [17:38 - 17:40] UsingDeclaration=iterator[5:18] // CHECK: Identifier: "iterator" [17:40 - 17:48] OverloadedDeclRef=iterator[5:18] -// FIXME: Check nested-name-specifiers on VarDecl, CXXMethodDecl. +// CHECK: Keyword: "void" [31:1 - 31:5] CXXMethod=foo:31:33 (Definition) +// CHECK: Identifier: "outer" [31:6 - 31:11] NamespaceRef=outer:20:11 +// CHECK: Punctuation: "::" [31:11 - 31:13] CXXMethod=foo:31:33 (Definition) +// CHECK: Identifier: "inner" [31:13 - 31:18] NamespaceRef=inner:21:13 +// CHECK: Punctuation: "::" [31:18 - 31:20] CXXMethod=foo:31:33 (Definition) +// CHECK: Identifier: "array" [31:20 - 31:25] TemplateRef=array:23:12 +// CHECK: Punctuation: "<" [31:25 - 31:26] CXXMethod=foo:31:33 (Definition) +// CHECK: Identifier: "T" [31:26 - 31:27] CXXMethod=foo:31:33 (Definition) +// CHECK: Punctuation: "," [31:27 - 31:28] CXXMethod=foo:31:33 (Definition) +// CHECK: Identifier: "N" [31:29 - 31:30] DeclRefExpr=N:30:31 +// CHECK: Punctuation: ">" [31:30 - 31:31] CXXMethod=foo:31:33 (Definition) +// CHECK: Punctuation: "::" [31:31 - 31:33] CXXMethod=foo:31:33 (Definition) +// CHECK: Identifier: "foo" [31:33 - 31:36] CXXMethod=foo:31:33 (Definition) +// CHECK: Punctuation: "(" [31:36 - 31:37] CXXMethod=foo:31:33 (Definition) +// CHECK: Punctuation: ")" [31:37 - 31:38] CXXMethod=foo:31:33 (Definition) + +// CHECK: Keyword: "int" [35:1 - 35:4] VarDecl=max_size:35:32 (Definition) +// CHECK: Identifier: "outer" [35:5 - 35:10] NamespaceRef=outer:20:11 +// CHECK: Punctuation: "::" [35:10 - 35:12] VarDecl=max_size:35:32 (Definition) +// CHECK: Identifier: "inner" [35:12 - 35:17] NamespaceRef=inner:21:13 +// CHECK: Punctuation: "::" [35:17 - 35:19] VarDecl=max_size:35:32 (Definition) +// CHECK: Identifier: "array" [35:19 - 35:24] TemplateRef=array:23:12 +// CHECK: Punctuation: "<" [35:24 - 35:25] VarDecl=max_size:35:32 (Definition) +// CHECK: Identifier: "T" [35:25 - 35:26] VarDecl=max_size:35:32 (Definition) +// CHECK: Punctuation: "," [35:26 - 35:27] VarDecl=max_size:35:32 (Definition) +// CHECK: Identifier: "N" [35:28 - 35:29] DeclRefExpr=N:34:31 +// CHECK: Punctuation: ">" [35:29 - 35:30] VarDecl=max_size:35:32 (Definition) +// CHECK: Punctuation: "::" [35:30 - 35:32] VarDecl=max_size:35:32 (Definition) +// CHECK: Identifier: "max_size" [35:32 - 35:40] VarDecl=max_size:35:32 (Definition) +// CHECK: Punctuation: "=" [35:41 - 35:42] VarDecl=max_size:35:32 (Definition) +// CHECK: Literal: "17" [35:43 - 35:45] UnexposedExpr= +// CHECK: Punctuation: ";" [35:45 - 35:46] // CHECK: Keyword: "using" [40:3 - 40:8] UsingDeclaration=iterator:40:46 // CHECK: Keyword: "typename" [40:9 - 40:17] UsingDeclaration=iterator:40:46 @@ -252,3 +291,20 @@ struct X4<Integer> { // CHECK: Punctuation: "(" [92:24 - 92:25] CallExpr=g:86:8 // CHECK: Identifier: "t" [92:25 - 92:26] DeclRefExpr=t:89:15 // CHECK: Punctuation: ")" [92:26 - 92:27] CallExpr=g:86:8 + +// Dependent name type +// CHECK: Keyword: "typedef" [100:3 - 100:10] ClassTemplate=X5:98:8 (Definition) +// CHECK: Keyword: "typename" [100:11 - 100:19] TypedefDecl=iter_type:100:63 (Definition) +// CHECK: Identifier: "outer_alias" [100:20 - 100:31] NamespaceRef=outer_alias:10:11 +// CHECK: Punctuation: "::" [100:31 - 100:33] TypedefDecl=iter_type:100:63 (Definition) +// CHECK: Identifier: "inner" [100:33 - 100:38] NamespaceRef=inner:62:13 +// CHECK: Punctuation: "::" [100:38 - 100:40] TypedefDecl=iter_type:100:63 (Definition) +// CHECK: Identifier: "vector" [100:40 - 100:46] TemplateRef=vector:4:12 +// CHECK: Punctuation: "<" [100:46 - 100:47] TypedefDecl=iter_type:100:63 (Definition) +// CHECK: Identifier: "type" [100:47 - 100:51] TypeRef=type:99:13 +// CHECK: Punctuation: ">" [100:51 - 100:52] TypedefDecl=iter_type:100:63 (Definition) +// CHECK: Punctuation: "::" [100:52 - 100:54] TypedefDecl=iter_type:100:63 (Definition) +// 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) + + diff --git a/test/Index/recursive-cxx-member-calls.cpp b/test/Index/recursive-cxx-member-calls.cpp index 1707491af0..0eb90585af 100644 --- a/test/Index/recursive-cxx-member-calls.cpp +++ b/test/Index/recursive-cxx-member-calls.cpp @@ -429,8 +429,8 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) { // CHECK-tokens: Punctuation: ":" [39:7 - 39:8] UnexposedDecl=:39:1 (Definition) // CHECK-tokens: Keyword: "typedef" [40:3 - 40:10] ClassDecl=StringRef:38:7 (Definition) // CHECK-tokens: Keyword: "const" [40:11 - 40:16] ClassDecl=StringRef:38:7 (Definition) -// CHECK-tokens: Keyword: "char" [40:17 - 40:21] ClassDecl=StringRef:38:7 (Definition) -// CHECK-tokens: Punctuation: "*" [40:22 - 40:23] ClassDecl=StringRef:38:7 (Definition) +// CHECK-tokens: Keyword: "char" [40:17 - 40:21] TypedefDecl=iterator:40:23 (Definition) +// CHECK-tokens: Punctuation: "*" [40:22 - 40:23] TypedefDecl=iterator:40:23 (Definition) // CHECK-tokens: Identifier: "iterator" [40:23 - 40:31] TypedefDecl=iterator:40:23 (Definition) // CHECK-tokens: Punctuation: ";" [40:31 - 40:32] ClassDecl=StringRef:38:7 (Definition) // CHECK-tokens: Keyword: "static" [41:3 - 41:9] ClassDecl=StringRef:38:7 (Definition) @@ -681,14 +681,14 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) { // CHECK-tokens: Keyword: "typedef" [69:5 - 69:12] UnexposedStmt= // CHECK-tokens: Identifier: "std" [69:13 - 69:16] UnexposedStmt= // CHECK-tokens: Punctuation: "::" [69:16 - 69:18] UnexposedStmt= -// CHECK-tokens: Identifier: "pair" [69:18 - 69:22] UnexposedStmt= -// CHECK-tokens: Punctuation: "<" [69:23 - 69:24] UnexposedStmt= -// CHECK-tokens: Identifier: "IdentifierInfo" [69:25 - 69:39] UnexposedStmt= -// CHECK-tokens: Punctuation: "," [69:39 - 69:40] UnexposedStmt= -// CHECK-tokens: Keyword: "const" [69:41 - 69:46] UnexposedStmt= -// CHECK-tokens: Keyword: "char" [69:47 - 69:51] UnexposedStmt= -// CHECK-tokens: Punctuation: "*" [69:52 - 69:53] UnexposedStmt= -// CHECK-tokens: Punctuation: ">" [69:53 - 69:54] UnexposedStmt= +// CHECK-tokens: Identifier: "pair" [69:18 - 69:22] TemplateRef=pair:4:44 +// CHECK-tokens: Punctuation: "<" [69:23 - 69:24] TypedefDecl=actualtype:69:54 (Definition) +// CHECK-tokens: Identifier: "IdentifierInfo" [69:25 - 69:39] TypeRef=class clang::IdentifierInfo:66:7 +// CHECK-tokens: Punctuation: "," [69:39 - 69:40] TypedefDecl=actualtype:69:54 (Definition) +// CHECK-tokens: Keyword: "const" [69:41 - 69:46] TypedefDecl=actualtype:69:54 (Definition) +// CHECK-tokens: Keyword: "char" [69:47 - 69:51] TypedefDecl=actualtype:69:54 (Definition) +// CHECK-tokens: Punctuation: "*" [69:52 - 69:53] TypedefDecl=actualtype:69:54 (Definition) +// CHECK-tokens: Punctuation: ">" [69:53 - 69:54] TypedefDecl=actualtype:69:54 (Definition) // CHECK-tokens: Identifier: "actualtype" [69:54 - 69:64] TypedefDecl=actualtype:69:54 (Definition) // CHECK-tokens: Punctuation: ";" [69:64 - 69:65] UnexposedStmt= // CHECK-tokens: Keyword: "return" [70:5 - 70:11] UnexposedStmt= @@ -713,14 +713,14 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) { // CHECK-tokens: Keyword: "typedef" [73:5 - 73:12] UnexposedStmt= // CHECK-tokens: Identifier: "std" [73:13 - 73:16] UnexposedStmt= // CHECK-tokens: Punctuation: "::" [73:16 - 73:18] UnexposedStmt= -// CHECK-tokens: Identifier: "pair" [73:18 - 73:22] UnexposedStmt= -// CHECK-tokens: Punctuation: "<" [73:23 - 73:24] UnexposedStmt= -// CHECK-tokens: Identifier: "IdentifierInfo" [73:25 - 73:39] UnexposedStmt= -// CHECK-tokens: Punctuation: "," [73:39 - 73:40] UnexposedStmt= -// CHECK-tokens: Keyword: "const" [73:41 - 73:46] UnexposedStmt= -// CHECK-tokens: Keyword: "char" [73:47 - 73:51] UnexposedStmt= -// CHECK-tokens: Punctuation: "*" [73:52 - 73:53] UnexposedStmt= -// CHECK-tokens: Punctuation: ">" [73:53 - 73:54] UnexposedStmt= +// CHECK-tokens: Identifier: "pair" [73:18 - 73:22] TemplateRef=pair:4:44 +// CHECK-tokens: Punctuation: "<" [73:23 - 73:24] TypedefDecl=actualtype:73:54 (Definition) +// CHECK-tokens: Identifier: "IdentifierInfo" [73:25 - 73:39] TypeRef=class clang::IdentifierInfo:66:7 +// CHECK-tokens: Punctuation: "," [73:39 - 73:40] TypedefDecl=actualtype:73:54 (Definition) +// CHECK-tokens: Keyword: "const" [73:41 - 73:46] TypedefDecl=actualtype:73:54 (Definition) +// CHECK-tokens: Keyword: "char" [73:47 - 73:51] TypedefDecl=actualtype:73:54 (Definition) +// CHECK-tokens: Punctuation: "*" [73:52 - 73:53] TypedefDecl=actualtype:73:54 (Definition) +// CHECK-tokens: Punctuation: ">" [73:53 - 73:54] TypedefDecl=actualtype:73:54 (Definition) // CHECK-tokens: Identifier: "actualtype" [73:54 - 73:64] TypedefDecl=actualtype:73:54 (Definition) // CHECK-tokens: Punctuation: ";" [73:64 - 73:65] UnexposedStmt= // CHECK-tokens: Keyword: "const" [74:5 - 74:10] UnexposedStmt= diff --git a/test/SemaCXX/nested-name-spec-locations.cpp b/test/SemaCXX/nested-name-spec-locations.cpp index 344826df5c..996b1cf50a 100644 --- a/test/SemaCXX/nested-name-spec-locations.cpp +++ b/test/SemaCXX/nested-name-spec-locations.cpp @@ -74,3 +74,14 @@ struct DependentScopedDeclRefExpr { void DependentScopedDeclRefExprCheck(DependentScopedDeclRefExpr<int> t) { t.f(); // expected-note{{in instantiation of member function}} } + + +template<typename T> +struct TypenameTypeTester { + typedef typename outer::inner::X0< + typename add_reference<T>::type + * // expected-error{{declared as a pointer to a reference of type}} + >::type type; +}; + +TypenameTypeTester<int> TypenameTypeCheck; // expected-note{{in instantiation of template class}} diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index c244bff50f..72d930ef9e 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -342,7 +342,8 @@ public: bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL); bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL); bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL); - + bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL); + // Data-recursive visitor functions. bool IsInRegionOfInterest(CXCursor C); bool RunVisitorWorkList(VisitorWorkList &WL); @@ -1503,6 +1504,13 @@ bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { return false; } +bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { + if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) + return true; + + return false; +} + bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { return Visit(TL.getPatternLoc()); } @@ -3587,25 +3595,30 @@ static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) { Decl *D = cxcursor::getCursorDecl(C); SourceRange R = D->getSourceRange(); - + + // Adjust the start of the location for declarations preceded by + // declaration specifiers. + SourceLocation StartLoc; if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { - if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) { - TypeLoc TL = TI->getTypeLoc(); - SourceLocation TLoc = TL.getSourceRange().getBegin(); - if (TLoc.isValid() && R.getBegin().isValid() && - SrcMgr.isBeforeInTranslationUnit(TLoc, R.getBegin())) - R.setBegin(TLoc); - } + if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) + StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); + } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) { + if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo()) + StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); + } - // FIXME: Multiple variables declared in a single declaration - // currently lack the information needed to correctly determine their - // ranges when accounting for the type-specifier. We use context - // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, - // and if so, whether it is the first decl. - if (VarDecl *VD = dyn_cast<VarDecl>(D)) { - if (!cxcursor::isFirstInDeclGroup(C)) - R.setBegin(VD->getLocation()); - } + if (StartLoc.isValid() && R.getBegin().isValid() && + SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin())) + R.setBegin(StartLoc); + + // FIXME: Multiple variables declared in a single declaration + // currently lack the information needed to correctly determine their + // ranges when accounting for the type-specifier. We use context + // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, + // and if so, whether it is the first decl. + if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + if (!cxcursor::isFirstInDeclGroup(C)) + R.setBegin(VD->getLocation()); } return R; @@ -4342,15 +4355,19 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { if (MD->isSynthesized()) return CXChildVisit_Continue; } + + SourceLocation StartLoc; if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { - if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) { - TypeLoc TL = TI->getTypeLoc(); - SourceLocation TLoc = TL.getSourceRange().getBegin(); - if (TLoc.isValid() && L.isValid() && - SrcMgr.isBeforeInTranslationUnit(TLoc, L)) - cursorRange.setBegin(TLoc); - } + if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) + StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); + } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) { + if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo()) + StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); } + + if (StartLoc.isValid() && L.isValid() && + SrcMgr.isBeforeInTranslationUnit(StartLoc, L)) + cursorRange.setBegin(StartLoc); } // If the location of the cursor occurs within a macro instantiation, record |