aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h3
-rw-r--r--include/clang/AST/TypeLoc.h26
-rw-r--r--lib/AST/TypeLoc.cpp9
-rw-r--r--lib/Sema/SemaDeclCXX.cpp8
-rw-r--r--lib/Sema/SemaTemplate.cpp6
-rw-r--r--lib/Sema/SemaType.cpp3
-rw-r--r--lib/Sema/TreeTransform.h37
-rw-r--r--lib/Serialization/ASTReader.cpp2
-rw-r--r--lib/Serialization/ASTWriter.cpp2
-rw-r--r--test/Index/annotate-nested-name-specifier.cpp60
-rw-r--r--test/Index/recursive-cxx-member-calls.cpp36
-rw-r--r--test/SemaCXX/nested-name-spec-locations.cpp11
-rw-r--r--tools/libclang/CIndex.cpp67
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