]> granicus.if.org Git - clang/commitdiff
Push nested-name-specifier source location information into
authorDouglas Gregor <dgregor@apple.com>
Tue, 1 Mar 2011 01:34:45 +0000 (01:34 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 1 Mar 2011 01:34:45 +0000 (01:34 +0000)
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

13 files changed:
include/clang/AST/RecursiveASTVisitor.h
include/clang/AST/TypeLoc.h
lib/AST/TypeLoc.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaType.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/Index/annotate-nested-name-specifier.cpp
test/Index/recursive-cxx-member-calls.cpp
test/SemaCXX/nested-name-spec-locations.cpp
tools/libclang/CIndex.cpp

index ebd16f8cc42e1d44ce1b9da5b0976d2ad7ded7e0..aaf9f59ed33ec287ab336baabf258dba83f91036 100644 (file)
@@ -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, {
index c7f5ee76330c5589f3db1a8b0ca345fe1bb99370..a724f29fb043b16923fcf4e6e20141db96ecd71d 100644 (file)
@@ -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
index 14db7f83c2d096f8822856effc392b646a4eeb3b..4b38dbac7b280912c34737c11568a5002e0be989 100644 (file)
@@ -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,
index 40e6a94f39d4ae70f452647bedabd9d8f6c40171..1a7604f7ca72fbb46d6108784a7539211ff24e28 100644 (file)
@@ -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,
index b3187de02587675ce57c6b4318677418505bbc31..cdb35a20c0998ff45bed0fb39a6ba82d9fe1cfc3 100644 (file)
@@ -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());
index ba80076003c9a082d81fc25a14eb94b34e73b8e6..2d807ceb25861462a57fe73e1ceca02ea3ef1558 100644 (file)
@@ -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(
index b36fd76677023c7be334e752bffddac7944abfdc..c7a11de1aaf7c78fc913312203341b6daf79195f 100644 (file)
@@ -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;
index ffbcbdb9b1a65e79589b9f603c5e183d1510c3ab..bb4b5667b1789e82954b2f7d8202925b983d699b 100644 (file)
@@ -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(
index 383ca3dffc6cf56b2b74f232186e13040caa73cc..aea3e37659d491a83200bc6b0f79ced2e7017f4e 100644 (file)
@@ -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(
index 766f21a5b6f61393f56415b53ca7404aa4595349..c934839cd2f3c17a86086c52494f4620d3e83e83 100644 (file)
@@ -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)
+
+
index 1707491af03ec63d7c2497365dfa405aab324efb..0eb90585af879f41905f5a65abdfa932db673556 100644 (file)
@@ -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=
index 344826df5c64c50d718f63c823c3a555c26f3eab..996b1cf50ac8088f5338febb50b990ea1fbebc4d 100644 (file)
@@ -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}}
index c244bff50f029c1d3614b4ae938e7ed5b75547be..72d930ef9e247cd7b30d7806ff54d31376fce129 100644 (file)
@@ -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