]> granicus.if.org Git - clang/commitdiff
Reinstate r126737, extending the generation of type-source location
authorDouglas Gregor <dgregor@apple.com>
Tue, 1 Mar 2011 16:31:39 +0000 (16:31 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 1 Mar 2011 16:31:39 +0000 (16:31 +0000)
information for qualifier type names throughout the parser to address
several problems.

The commit message from r126737:

Push nested-name-specifier source location information into elaborated
name types, e.g., "enum clang::NestedNameSpecifier::SpecifierKind".

Aside from the normal changes, this also required some tweaks to the
parser. Essentially, when we're looking at a type name (via
getTypeName()) specifically for the purpose of creating an annotation
token, we pass down the flag that asks for full type-source location
information to be stored within the returned type. That way, we retain
source-location information involving nested-name-specifiers rather
than trying to reconstruct that information later, long after it's
been lost in the parser.

With this change, test/Index/recursive-cxx-member-calls.cpp is showing
much improved results again, since that code has lots of
nested-name-specifiers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126748 91177308-0d34-0410-b5e6-96231b3b80d8

19 files changed:
include/clang/AST/RecursiveASTVisitor.h
include/clang/AST/TypeLoc.h
include/clang/Sema/Sema.h
lib/AST/TypeLoc.cpp
lib/Parse/ParseDecl.cpp
lib/Parse/ParseDeclCXX.cpp
lib/Parse/ParseExprCXX.cpp
lib/Parse/Parser.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateInstantiate.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
tools/libclang/CIndex.cpp

index aaf9f59ed33ec287ab336baabf258dba83f91036..972ff5c7604f67a39bbc7df2ef0737a68414b9ad 100644 (file)
@@ -987,10 +987,9 @@ DEF_TRAVERSE_TYPELOC(AttributedType, {
     TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
   })
 
-// FIXME: use the sourceloc on qualifier?
 DEF_TRAVERSE_TYPELOC(ElaboratedType, {
-    if (TL.getTypePtr()->getQualifier()) {
-      TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
+    if (TL.getQualifierLoc()) {
+      TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
     }
     TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
   })
index a724f29fb043b16923fcf4e6e20141db96ecd71d..594aeb1a2ed1ef2875bc663d5d9cd5d58a1f3c77 100644 (file)
@@ -1388,7 +1388,10 @@ class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
 
 struct ElaboratedLocInfo {
   SourceLocation KeywordLoc;
-  SourceRange QualifierRange;
+  
+  /// \brief Opaque data pointer used to reconstruct a nested-name-specifier
+  /// from 
+  void *QualifierData;
 };
 
 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
@@ -1403,27 +1406,29 @@ 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();
   }
 
   SourceRange getLocalSourceRange() const {
     if (getKeywordLoc().isValid())
-      if (getQualifierRange().getEnd().isValid())
-        return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
+      if (getQualifierLoc())
+        return SourceRange(getKeywordLoc(), getQualifierLoc().getEndLoc());
       else
         return SourceRange(getKeywordLoc());
     else
-      return getQualifierRange();
+      return getQualifierLoc().getSourceRange();
   }
 
-  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
-    setKeywordLoc(Loc);
-    setQualifierRange(SourceRange(Loc));
-  }
+  void initializeLocal(ASTContext &Context, SourceLocation Loc);
 
   TypeLoc getNamedTypeLoc() const {
     return getInnerTypeLoc();
@@ -1496,9 +1501,10 @@ public:
   void initializeLocal(ASTContext &Context, SourceLocation Loc);
 };
 
-// This is exactly the structure of an ElaboratedTypeLoc whose inner
-// type is some sort of TemplateSpecializationTypeLoc.
-struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
+struct DependentTemplateSpecializationLocInfo {
+  SourceLocation KeywordLoc;
+  SourceLocation NameLoc;
+  SourceRange QualifierRange;
   SourceLocation LAngleLoc;
   SourceLocation RAngleLoc;
   // followed by a TemplateArgumentLocInfo[]
index 12248c2f7f9fefb1c3072fc3595406b726873d45..633657a1939a28726ce12d1c829d452323a189fe 100644 (file)
@@ -792,7 +792,8 @@ public:
                          Scope *S, CXXScopeSpec *SS = 0,
                          bool isClassName = false,
                          bool HasTrailingDot = false,
-                         ParsedType ObjectType = ParsedType());
+                         ParsedType ObjectType = ParsedType(),
+                         bool WantNontrivialTypeSourceInfo = false);
   TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
   bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
                                SourceLocation IILoc,
index 4b38dbac7b280912c34737c11568a5002e0be989..98c46621f038d92d6ab8dcb34a63ccc60a846f86 100644 (file)
@@ -229,6 +229,14 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
   return TL;
 }
 
+void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, 
+                                        SourceLocation Loc) {
+  setKeywordLoc(Loc);
+  NestedNameSpecifierLocBuilder Builder;
+  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
+  setQualifierLoc(Builder.getWithLocInContext(Context));
+}
+
 void DependentNameTypeLoc::initializeLocal(ASTContext &Context, 
                                            SourceLocation Loc) {
   setKeywordLoc(Loc);
index 077edd700ad653284cf9f3439b46f71eae6b8bb2..532c318a62588e891672060379527a134c8f6320 100644 (file)
@@ -1056,7 +1056,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
 
       ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
                                                Next.getLocation(),
-                                               getCurScope(), &SS);
+                                               getCurScope(), &SS,
+                                               false, false, ParsedType(),
+                                               /*NonTrivialSourceInfo=*/true);
 
       // If the referenced identifier is not a type, then this declspec is
       // erroneous: We already checked about that it has no type specifier, and
index b3ad25b024fc3ab679f26a5745e3c2ee38d555d9..78fe4d2e3117cc3569c057b8949a27cbc90cb249 100644 (file)
@@ -577,7 +577,9 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
   }
 
   // We have an identifier; check whether it is actually a type.
-  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true);
+  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true,
+                                        false, ParsedType(),
+                                        /*NonTrivialTypeSourceInfo=*/true);
   if (!Type) {
     Diag(IdLoc, diag::err_expected_class_name);
     return true;
index 823c08c999d53b1c3a56d75cad4938582b2d9f43..0e23e43a0dfbf276e537b6b0cc2a748b2e59b5d0 100644 (file)
@@ -1472,7 +1472,9 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
         Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
       // We have parsed a constructor name.
       Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, getCurScope(),
-                                                    &SS, false),
+                                                    &SS, false, false,
+                                                    ParsedType(),
+                                            /*NonTrivialTypeSourceInfo=*/true),
                                 IdLoc, IdLoc);
     } else {
       // We have parsed an identifier.
@@ -1510,7 +1512,9 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
         Result.setConstructorName(Actions.getTypeName(*TemplateId->Name,
                                                   TemplateId->TemplateNameLoc, 
                                                       getCurScope(),
-                                                      &SS, false),
+                                                      &SS, false, false,
+                                                      ParsedType(),
+                                            /*NontrivialTypeSourceInfo=*/true),
                                   TemplateId->TemplateNameLoc, 
                                   TemplateId->RAngleLoc);
         TemplateId->Destroy();
index 3ed070321dae5cc07649ef07dccf83dd2f755ffa..ba3c03cdfb52e81c4746eec69b8825a68e7bf193 100644 (file)
@@ -1091,7 +1091,9 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
     if (ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
                                             Tok.getLocation(), getCurScope(),
                                             &SS, false, 
-                                            NextToken().is(tok::period))) {
+                                            NextToken().is(tok::period),
+                                            ParsedType(),
+                                            /*NonTrivialTypeSourceInfo*/true)) {
       // This is a typename. Replace the current token in-place with an
       // annotation type token.
       Tok.setKind(tok::annot_typename);
index 062971724c1f2424cc5be26136cecb915d137440..9d90499759973e5975b7c45b0ad12453b7c678ff 100644 (file)
@@ -17,6 +17,7 @@
 #include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "TypeLocBuilder.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -61,7 +62,8 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr) {
 ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
                              Scope *S, CXXScopeSpec *SS,
                              bool isClassName, bool HasTrailingDot,
-                             ParsedType ObjectTypePtr) {
+                             ParsedType ObjectTypePtr,
+                             bool WantNontrivialTypeSourceInfo) {
   // Determine where we will perform name lookup.
   DeclContext *LookupCtx = 0;
   if (ObjectTypePtr) {
@@ -87,11 +89,15 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
         
         // We know from the grammar that this name refers to a type,
         // so build a dependent node to describe the type.
+        if (WantNontrivialTypeSourceInfo)
+          return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get();
+        
+        NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context);
         QualType T =
-          CheckTypenameType(ETK_None, SourceLocation(),
-                            SS->getWithLocInContext(Context),
+          CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc,
                             II, NameLoc);
-        return ParsedType::make(T);
+        
+          return ParsedType::make(T);
       }
       
       return ParsedType();
@@ -190,9 +196,21 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
     if (T.isNull())
       T = Context.getTypeDeclType(TD);
     
-    if (SS)
-      T = getElaboratedType(ETK_None, *SS, T);
-    
+    if (SS && SS->isNotEmpty()) {
+      if (WantNontrivialTypeSourceInfo) {
+        // Construct a type with type-source information.
+        TypeLocBuilder Builder;
+        Builder.pushTypeSpec(T).setNameLoc(NameLoc);
+        
+        T = getElaboratedType(ETK_None, *SS, T);
+        ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
+        ElabTL.setKeywordLoc(SourceLocation());
+        ElabTL.setQualifierLoc(SS->getWithLocInContext(Context));
+        return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+      } else {
+        T = getElaboratedType(ETK_None, *SS, T);
+      }
+    }
   } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
     if (!HasTrailingDot)
       T = Context.getObjCInterfaceType(IDecl);
@@ -264,7 +282,9 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
         Diag(Result->getLocation(), diag::note_previous_decl)
           << Result->getDeclName();
         
-        SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS);
+        SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS,
+                                    false, false, ParsedType(),
+                                    /*NonTrivialTypeSourceInfo=*/true);
         return true;
       }
     } else if (Lookup.empty()) {
index 1a7604f7ca72fbb46d6108784a7539211ff24e28..f760f3f8710847d79d3d0489765368f25446befa 100644 (file)
@@ -6930,7 +6930,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
     } else {
       ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
       TL.setKeywordLoc(TagLoc);
-      TL.setQualifierRange(SS.getRange());
+      TL.setQualifierLoc(QualifierLoc);
       cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(NameLoc);
     }
 
index cdb35a20c0998ff45bed0fb39a6ba82d9fe1cfc3..fbb7246533509cadb2a756e7778da52359e13e20 100644 (file)
@@ -1821,12 +1821,12 @@ TypeResult Sema::ActOnTagTemplateIdType(CXXScopeSpec &SS,
 
   ElaboratedTypeKeyword Keyword
     = TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
-  QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
+  QualType ElabType = Context.getElaboratedType(Keyword, SS.getScopeRep(), Type);
 
   TypeSourceInfo *ElabDI = Context.CreateTypeSourceInfo(ElabType);
   ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(ElabDI->getTypeLoc());
   TL.setKeywordLoc(TagLoc);
-  TL.setQualifierRange(SS.getRange());
+  TL.setQualifierLoc(SS.getWithLocInContext(Context));
   TL.getNamedTypeLoc().initializeFullCopy(DI->getTypeLoc());
   return CreateParsedType(ElabType, ElabDI);
 }
@@ -5910,8 +5910,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
       << FixItHint::CreateRemoval(TypenameLoc);
 
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
-  QualType T = CheckTypenameType(ETK_Typename, TypenameLoc, QualifierLoc,
-                                 II, IdLoc);
+  QualType T = CheckTypenameType(TypenameLoc.isValid()? ETK_Typename : ETK_None,
+                                 TypenameLoc, QualifierLoc, II, IdLoc);
   if (T.isNull())
     return true;
 
@@ -5924,7 +5924,7 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
   } else {
     ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
     TL.setKeywordLoc(TypenameLoc);
-    TL.setQualifierRange(SS.getRange());
+    TL.setQualifierLoc(QualifierLoc);
     cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
   }
 
@@ -5964,7 +5964,7 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
     // type.
     TypeLocBuilder Builder;
     TemplateSpecializationTypeLoc SpecTL 
-    = Builder.push<TemplateSpecializationTypeLoc>(T);
+      = Builder.push<TemplateSpecializationTypeLoc>(T);
     
     // FIXME: No place to set the location of the 'template' keyword!
     SpecTL.setLAngleLoc(LAngleLoc);
@@ -5973,14 +5973,10 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
     
-    // FIXME: This is a hack. We really want to push the nested-name-specifier
-    // into TemplateSpecializationType.
-    
-    /* Note: NNS already embedded in template specialization type T. */
-    T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T);
+    T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T);
     ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
     TL.setKeywordLoc(TypenameLoc);
-    TL.setQualifierRange(SS.getRange());
+    TL.setQualifierLoc(SS.getWithLocInContext(Context));
     
     TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
     return CreateParsedType(T, TSI);
index ae0ac9cbe35c523af214be766c21a523d57c9cb0..c0f130da88ac804142eb99d17da1167ff0d397e6 100644 (file)
@@ -730,7 +730,8 @@ namespace {
     /// elaborated type.
     QualType RebuildElaboratedType(SourceLocation KeywordLoc,
                                    ElaboratedTypeKeyword Keyword,
-                                   NestedNameSpecifier *NNS, QualType T);
+                                   NestedNameSpecifierLoc QualifierLoc,
+                                   QualType T);
 
     TemplateName TransformTemplateName(TemplateName Name,
                                        QualType ObjectType = QualType(),
@@ -892,7 +893,7 @@ VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
 QualType
 TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
                                             ElaboratedTypeKeyword Keyword,
-                                            NestedNameSpecifier *NNS,
+                                            NestedNameSpecifierLoc QualifierLoc,
                                             QualType T) {
   if (const TagType *TT = T->getAs<TagType>()) {
     TagDecl* TD = TT->getDecl();
@@ -918,7 +919,8 @@ TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
 
   return TreeTransform<TemplateInstantiator>::RebuildElaboratedType(KeywordLoc,
                                                                     Keyword,
-                                                                    NNS, T);
+                                                                  QualifierLoc,
+                                                                    T);
 }
 
 TemplateName TemplateInstantiator::TransformTemplateName(TemplateName Name,
index 2d807ceb25861462a57fe73e1ceca02ea3ef1558..1c8a58b07ce5b2fe5ec6321b2c392c81778443c1 100644 (file)
@@ -2237,7 +2237,7 @@ namespace {
                        ? DS.getTypeSpecTypeLoc()
                        : SourceLocation());
       const CXXScopeSpec& SS = DS.getTypeSpecScope();
-      TL.setQualifierRange(SS.isEmpty() ? SourceRange(): SS.getRange());
+      TL.setQualifierLoc(SS.getWithLocInContext(Context));
       Visit(TL.getNextTypeLoc().getUnqualifiedLoc());
     }
     void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
index c7a11de1aaf7c78fc913312203341b6daf79195f..5485dfb7e4aa43d591c26d079e176ee09a793489 100644 (file)
@@ -723,8 +723,11 @@ public:
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildElaboratedType(SourceLocation KeywordLoc,
                                  ElaboratedTypeKeyword Keyword,
-                                 NestedNameSpecifier *NNS, QualType Named) {
-    return SemaRef.Context.getElaboratedType(Keyword, NNS, Named);
+                                 NestedNameSpecifierLoc QualifierLoc,
+                                 QualType Named) {
+    return SemaRef.Context.getElaboratedType(Keyword, 
+                                         QualifierLoc.getNestedNameSpecifier(), 
+                                             Named);
   }
 
   /// \brief Build a new typename type that refers to a template-id.
@@ -4436,12 +4439,12 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
                                                 ElaboratedTypeLoc TL) {
   const ElaboratedType *T = TL.getTypePtr();
 
-  NestedNameSpecifier *NNS = 0;
+  NestedNameSpecifierLoc QualifierLoc;
   // NOTE: the qualifier in an ElaboratedType is optional.
-  if (T->getQualifier() != 0) {
-    NNS = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
-                                                    TL.getQualifierRange());
-    if (!NNS)
+  if (TL.getQualifierLoc()) {
+    QualifierLoc 
+      = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
+    if (!QualifierLoc)
       return QualType();
   }
 
@@ -4451,18 +4454,18 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
-      NNS != T->getQualifier() ||
+      QualifierLoc != TL.getQualifierLoc() ||
       NamedT != T->getNamedType()) {
     Result = getDerived().RebuildElaboratedType(TL.getKeywordLoc(),
-                                                T->getKeyword(), NNS, NamedT);
+                                                T->getKeyword(), 
+                                                QualifierLoc, NamedT);
     if (Result.isNull())
       return QualType();
   }
 
   ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
   NewTL.setKeywordLoc(TL.getKeywordLoc());
-  NewTL.setQualifierRange(TL.getQualifierRange());
-
+  NewTL.setQualifierLoc(QualifierLoc);
   return Result;
 }
 
@@ -4550,7 +4553,7 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
 
     ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
-    NewTL.setQualifierRange(QualifierLoc.getSourceRange());
+    NewTL.setQualifierLoc(QualifierLoc);
   } else {
     DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
@@ -4621,7 +4624,12 @@ QualType TreeTransform<Derived>::
     // Copy information relevant to the elaborated type.
     ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
     NewTL.setKeywordLoc(TL.getKeywordLoc());
-    NewTL.setQualifierRange(TL.getQualifierRange());
+    
+    // FIXME: DependentTemplateSpecializationType needs better source-location
+    // info.
+    NestedNameSpecifierLocBuilder Builder;
+    Builder.MakeTrivial(SemaRef.Context, NNS, TL.getQualifierRange());
+    NewTL.setQualifierLoc(Builder.getWithLocInContext(SemaRef.Context));
   } else {
     TypeLoc NewTL(Result, TL.getOpaqueData());
     TLB.pushFullCopy(NewTL);
index bb4b5667b1789e82954b2f7d8202925b983d699b..e687d2ccae9170f9f3f79e10c6e4b176dd09ae9d 100644 (file)
@@ -3518,7 +3518,7 @@ void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
 }
 void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
   TL.setKeywordLoc(ReadSourceLocation(Record, Idx));
-  TL.setQualifierRange(Reader.ReadSourceRange(F, Record, Idx));
+  TL.setQualifierLoc(Reader.ReadNestedNameSpecifierLoc(F, Record, Idx));
 }
 void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
   TL.setNameLoc(ReadSourceLocation(Record, Idx));
index aea3e37659d491a83200bc6b0f79ced2e7017f4e..638087a8f869211ab1f3185c9e32fd9ac979d3fe 100644 (file)
@@ -532,7 +532,7 @@ void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
 }
 void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
   Writer.AddSourceLocation(TL.getKeywordLoc(), Record);
-  Writer.AddSourceRange(TL.getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifierLoc(TL.getQualifierLoc(), Record);
 }
 void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
   Writer.AddSourceLocation(TL.getNameLoc(), Record);
index c934839cd2f3c17a86086c52494f4620d3e83e83..beb0e40ac04ce7c2c63bb9d8b680fb9ce135c443 100644 (file)
@@ -307,4 +307,17 @@ struct X5 {
 // CHECK: Identifier: "iterator" [100:54 - 100:62] TypedefDecl=iter_type:100:63 (Definition)
 // CHECK: Identifier: "iter_type" [100:63 - 100:72] TypedefDecl=iter_type:100:63 (Definition)
 
+// CHECK: Keyword: "typedef" [101:3 - 101:10] ClassTemplate=X5:98:8 (Definition)
+// CHECK: Keyword: "typename" [101:11 - 101:19] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "outer_alias" [101:20 - 101:31] NamespaceRef=outer_alias:10:11
+// CHECK: Punctuation: "::" [101:31 - 101:33] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "inner" [101:33 - 101:38] NamespaceRef=inner:62:13
+// CHECK: Punctuation: "::" [101:38 - 101:40] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "vector" [101:40 - 101:46] TemplateRef=vector:4:12
+// CHECK: Punctuation: "<" [101:46 - 101:47] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Keyword: "int" [101:47 - 101:50] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Punctuation: ">" [101:50 - 101:51] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Punctuation: "::" [101:51 - 101:53] TypedefDecl=int_ptr_type:101:62 (Definition)
+// CHECK: Identifier: "iterator" [101:53 - 101:61] TypeRef=iterator:5:18
+// CHECK: Identifier: "int_ptr_type" [101:62 - 101:74] TypedefDecl=int_ptr_type:101:62 (Definition)
 
index 0eb90585af879f41905f5a65abdfa932db673556..f226b25b1f6c3153e3d9c71fdb86d2e7fc87711b 100644 (file)
@@ -771,18 +771,18 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
 // CHECK-tokens: Literal: "1" [75:61 - 75:62] UnexposedExpr=
 // CHECK-tokens: Punctuation: ";" [75:62 - 75:63] UnexposedStmt=
 // CHECK-tokens: Punctuation: "}" [76:3 - 76:4] UnexposedStmt=
-// CHECK-tokens: Identifier: "llvm" [77:3 - 77:7] CXXMethod=getName:77:19 (Definition)
+// CHECK-tokens: Identifier: "llvm" [77:3 - 77:7] NamespaceRef=llvm:37:11
 // CHECK-tokens: Punctuation: "::" [77:7 - 77:9] CXXMethod=getName:77:19 (Definition)
-// CHECK-tokens: Identifier: "StringRef" [77:9 - 77:18] CXXMethod=getName:77:19 (Definition)
+// CHECK-tokens: Identifier: "StringRef" [77:9 - 77:18] TypeRef=class llvm::StringRef:38:7
 // CHECK-tokens: Identifier: "getName" [77:19 - 77:26] CXXMethod=getName:77:19 (Definition)
 // CHECK-tokens: Punctuation: "(" [77:26 - 77:27] CXXMethod=getName:77:19 (Definition)
 // CHECK-tokens: Punctuation: ")" [77:27 - 77:28] CXXMethod=getName:77:19 (Definition)
 // CHECK-tokens: Keyword: "const" [77:29 - 77:34] CXXMethod=getName:77:19 (Definition)
 // CHECK-tokens: Punctuation: "{" [77:35 - 77:36] UnexposedStmt=
 // CHECK-tokens: Keyword: "return" [78:5 - 78:11] UnexposedStmt=
-// CHECK-tokens: Identifier: "llvm" [78:12 - 78:16] CallExpr=StringRef:49:3
+// CHECK-tokens: Identifier: "llvm" [78:12 - 78:16] NamespaceRef=llvm:37:11
 // CHECK-tokens: Punctuation: "::" [78:16 - 78:18] CallExpr=StringRef:49:3
-// CHECK-tokens: Identifier: "StringRef" [78:18 - 78:27] CallExpr=StringRef:49:3
+// CHECK-tokens: Identifier: "StringRef" [78:18 - 78:27] TypeRef=class llvm::StringRef:38:7
 // CHECK-tokens: Punctuation: "(" [78:27 - 78:28] CallExpr=StringRef:49:3
 // CHECK-tokens: Identifier: "getNameStart" [78:28 - 78:40] MemberRefExpr=getNameStart:68:15
 // CHECK-tokens: Punctuation: "(" [78:40 - 78:41] CallExpr=getNameStart:68:15
@@ -892,9 +892,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
 // CHECK-tokens: Keyword: "namespace" [98:7 - 98:16] UsingDirective=:98:17
 // CHECK-tokens: Identifier: "clang" [98:17 - 98:22] NamespaceRef=clang:10:17
 // CHECK-tokens: Punctuation: ";" [98:22 - 98:23]
-// CHECK-tokens: Identifier: "AttributeList" [100:1 - 100:14] CXXMethod=getKind:100:36 (Definition)
+// CHECK-tokens: Identifier: "AttributeList" [100:1 - 100:14] TypeRef=class clang::AttributeList:12:9
 // CHECK-tokens: Punctuation: "::" [100:14 - 100:16] CXXMethod=getKind:100:36 (Definition)
-// CHECK-tokens: Identifier: "Kind" [100:16 - 100:20] CXXMethod=getKind:100:36 (Definition)
+// CHECK-tokens: Identifier: "Kind" [100:16 - 100:20] TypeRef=enum clang::AttributeList::Kind:13:10
 // CHECK-tokens: Identifier: "AttributeList" [100:21 - 100:34] TypeRef=class clang::AttributeList:12:9
 // CHECK-tokens: Punctuation: "::" [100:34 - 100:36] CXXMethod=getKind:100:36 (Definition)
 // CHECK-tokens: Identifier: "getKind" [100:36 - 100:43] CXXMethod=getKind:100:36 (Definition)
@@ -905,9 +905,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
 // CHECK-tokens: Identifier: "Name" [100:67 - 100:71] ParmDecl=Name:100:67 (Definition)
 // CHECK-tokens: Punctuation: ")" [100:71 - 100:72] CXXMethod=getKind:100:36 (Definition)
 // CHECK-tokens: Punctuation: "{" [100:73 - 100:74] UnexposedStmt=
-// CHECK-tokens: Identifier: "llvm" [101:3 - 101:7] VarDecl=AttrName:101:19 (Definition)
+// CHECK-tokens: Identifier: "llvm" [101:3 - 101:7] NamespaceRef=llvm:82:11
 // CHECK-tokens: Punctuation: "::" [101:7 - 101:9] VarDecl=AttrName:101:19 (Definition)
-// CHECK-tokens: Identifier: "StringRef" [101:9 - 101:18] VarDecl=AttrName:101:19 (Definition)
+// CHECK-tokens: Identifier: "StringRef" [101:9 - 101:18] TypeRef=class llvm::StringRef:38:7
 // CHECK-tokens: Identifier: "AttrName" [101:19 - 101:27] VarDecl=AttrName:101:19 (Definition)
 // CHECK-tokens: Punctuation: "=" [101:28 - 101:29] VarDecl=AttrName:101:19 (Definition)
 // CHECK-tokens: Identifier: "Name" [101:30 - 101:34] DeclRefExpr=Name:100:67
@@ -950,13 +950,14 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
 // CHECK-tokens: Punctuation: ")" [103:54 - 103:55] CallExpr=substr:60:13
 // CHECK-tokens: Punctuation: ";" [103:55 - 103:56] UnexposedStmt=
 // CHECK-tokens: Keyword: "return" [105:3 - 105:9] UnexposedStmt=
+// FIXME: Missing "llvm" namespace reference below
 // CHECK-tokens: Identifier: "llvm" [105:10 - 105:14] UnexposedStmt=
 // CHECK-tokens: Punctuation: "::" [105:14 - 105:16] UnexposedStmt=
 // CHECK-tokens: Identifier: "StringSwitch" [105:16 - 105:28] TemplateRef=StringSwitch:83:47
-// CHECK-tokens: Punctuation: "<" [105:29 - 105:30] CallExpr=StringSwitch:87:12
-// CHECK-tokens: Identifier: "AttributeList" [105:31 - 105:44] CallExpr=StringSwitch:87:12
-// CHECK-tokens: Punctuation: "::" [105:44 - 105:46] CallExpr=StringSwitch:87:12
-// CHECK-tokens: Identifier: "Kind" [105:46 - 105:50] CallExpr=StringSwitch:87:12
+// CHECK-tokens: Punctuation: "<" [105:29 - 105:30] UnexposedExpr=StringSwitch:87:12
+// CHECK-tokens: Identifier: "AttributeList" [105:31 - 105:44] TypeRef=class clang::AttributeList:12:9
+// CHECK-tokens: Punctuation: "::" [105:44 - 105:46] UnexposedExpr=StringSwitch:87:12
+// CHECK-tokens: Identifier: "Kind" [105:46 - 105:50] TypeRef=enum clang::AttributeList::Kind:13:10
 // CHECK-tokens: Punctuation: ">" [105:51 - 105:52] CallExpr=StringSwitch:87:12
 // CHECK-tokens: Punctuation: "(" [105:53 - 105:54] CallExpr=StringSwitch:87:12
 // CHECK-tokens: Identifier: "AttrName" [105:54 - 105:62] DeclRefExpr=AttrName:101:19
index 72d930ef9e247cd7b30d7806ff54d31376fce129..8c2111d4ad9f7f5753ac0913e741b58977f13875 100644 (file)
@@ -343,6 +343,7 @@ public:
   bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
   bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
   bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
+  bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
   
   // Data-recursive visitor functions.
   bool IsInRegionOfInterest(CXCursor C);
@@ -1511,6 +1512,13 @@ bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
   return false;
 }
 
+bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+    return true;
+  
+  return Visit(TL.getNamedTypeLoc());
+}
+
 bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
   return Visit(TL.getPatternLoc());
 }