diff options
-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 |