]> granicus.if.org Git - clang/commitdiff
Use NestedNameSpecifierLoc within out-of-line variables, function, and
authorDouglas Gregor <dgregor@apple.com>
Fri, 25 Feb 2011 02:25:35 +0000 (02:25 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 25 Feb 2011 02:25:35 +0000 (02:25 +0000)
tag definitions. Also, add support for template instantiation of
NestedNameSpecifierLocs.

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

18 files changed:
include/clang/AST/ASTImporter.h
include/clang/AST/Decl.h
include/clang/AST/NestedNameSpecifier.h
include/clang/Sema/DeclSpec.h
include/clang/Sema/Sema.h
lib/AST/ASTImporter.cpp
lib/AST/Decl.cpp
lib/Sema/DeclSpec.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateInstantiate.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
lib/Sema/TreeTransform.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/Index/annotate-nested-name-specifier.cpp
tools/libclang/CIndex.cpp

index b659ce74bb7cbac8c2c09d5b97ff26e30fc3dba3..e1535965b1e44d7713ebe9559e32fedb7ebdc5cc 100644 (file)
@@ -145,7 +145,14 @@ namespace clang {
     /// \returns the equivalent nested-name-specifier in the "to"
     /// context, or NULL if an error occurred.
     NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
-    
+
+    /// \brief Import the given nested-name-specifier from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent nested-name-specifier in the "to"
+    /// context.
+    NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
+
     /// \brief Import the goven template name from the "from" context into the
     /// "to" context.
     TemplateName Import(TemplateName From);
index 1d5d0fe68ba068a1deaa79987d22eb13670bdd01..ec379c3707233aeddfa3fffef68522ca62d5e108 100644 (file)
@@ -475,10 +475,7 @@ public:
 /// QualifierInfo - A struct with extended info about a syntactic
 /// name qualifier, to be used for the case of out-of-line declarations.
 struct QualifierInfo {
-  /// NNS - The syntactic name qualifier.
-  NestedNameSpecifier *NNS;
-  /// NNSRange - The source range for the qualifier.
-  SourceRange NNSRange;
+  NestedNameSpecifierLoc QualifierLoc;
   /// NumTemplParamLists - The number of template parameter lists
   /// that were matched against the template-ids occurring into the NNS.
   unsigned NumTemplParamLists;
@@ -487,8 +484,7 @@ struct QualifierInfo {
   TemplateParameterList** TemplParamLists;
 
   /// Default constructor.
-  QualifierInfo()
-    : NNS(0), NNSRange(), NumTemplParamLists(0), TemplParamLists(0) {}
+  QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {}
   /// setTemplateParameterListsInfo - Sets info about matched template
   /// parameter lists.
   void setTemplateParameterListsInfo(ASTContext &Context,
@@ -545,14 +541,22 @@ public:
     return SourceRange(getOuterLocStart(), getLocation());
   }
 
+  /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+  /// declaration, if it was present in the source.
   NestedNameSpecifier *getQualifier() const {
-    return hasExtInfo() ? getExtInfo()->NNS : 0;
+    return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
+                        : 0;
   }
-  SourceRange getQualifierRange() const {
-    return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
+  
+  /// \brief Retrieve the nested-name-specifier (with source-location 
+  /// information) that qualifies the name of this declaration, if it was 
+  /// present in the source.
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    return hasExtInfo() ? getExtInfo()->QualifierLoc
+                        : NestedNameSpecifierLoc();
   }
-  void setQualifierInfo(NestedNameSpecifier *Qualifier,
-                        SourceRange QualifierRange);
+  
+  void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
 
   unsigned getNumTemplateParameterLists() const {
     return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
@@ -2140,14 +2144,22 @@ public:
 
   void setTypedefForAnonDecl(TypedefDecl *TDD);
 
+  /// \brief Retrieve the nested-name-specifier that qualifies the name of this
+  /// declaration, if it was present in the source.
   NestedNameSpecifier *getQualifier() const {
-    return hasExtInfo() ? getExtInfo()->NNS : 0;
+    return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
+                        : 0;
   }
-  SourceRange getQualifierRange() const {
-    return hasExtInfo() ? getExtInfo()->NNSRange : SourceRange();
+  
+  /// \brief Retrieve the nested-name-specifier (with source-location 
+  /// information) that qualifies the name of this declaration, if it was 
+  /// present in the source.
+  NestedNameSpecifierLoc getQualifierLoc() const {
+    return hasExtInfo() ? getExtInfo()->QualifierLoc
+                        : NestedNameSpecifierLoc();
   }
-  void setQualifierInfo(NestedNameSpecifier *Qualifier,
-                        SourceRange QualifierRange);
+    
+  void setQualifierInfo(NestedNameSpecifierLoc QualifierLoc);
 
   unsigned getNumTemplateParameterLists() const {
     return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0;
index 2803f5195144325725f8ea9964febe17482a0575..5e9adfccc4828604ac625915f2349f59f378666c 100644 (file)
@@ -268,6 +268,18 @@ public:
     return getSourceRange().getEnd();
   }
 
+  /// \brief Retrieve the location of the beginning of this
+  /// component of the nested-name-specifier.
+  SourceLocation getLocalBeginLoc() const { 
+    return getLocalSourceRange().getBegin();
+  }
+  
+  /// \brief Retrieve the location of the end of this component of the
+  /// nested-name-specifier.
+  SourceLocation getLocalEndLoc() const { 
+    return getLocalSourceRange().getEnd();
+  }
+
   /// \brief Return the prefix of this nested-name-specifier.
   ///
   /// For example, if this instance refers to a nested-name-specifier
index 9386d35873400a107b5980bccc5ddeab0a36ebe0..64126bd4d80ab169f98157d3383b783c2ae5008a 100644 (file)
@@ -168,7 +168,7 @@ public:
   ///
   /// \param Context The context into which this nested-name-specifier will be
   /// copied.
-  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context);
+  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
 
   /// No scope specifier.
   bool isEmpty() const { return !Range.isValid(); }
index 8573f1dbfc72334097aafa29aecfab02386df80f..a93739892cfe458b8d4fa7552542b12a96a9564a 100644 (file)
@@ -4293,6 +4293,11 @@ public:
   SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
                            SourceRange Range,
                            const MultiLevelTemplateArgumentList &TemplateArgs);
+
+  NestedNameSpecifierLoc
+  SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
+                           const MultiLevelTemplateArgumentList &TemplateArgs);
+
   DeclarationNameInfo
   SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
                            const MultiLevelTemplateArgumentList &TemplateArgs);
index 65c0a3bb619f2ac10ed973deee253f12aadc87fe..21f10fb7ad99cafb5d9786920b18a5322cea095b 100644 (file)
@@ -2097,11 +2097,7 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
                                   D->isScoped(), D->isScopedUsingClassTag(),
                                   D->isFixed());
   // Import the qualifier, if any.
-  if (D->getQualifier()) {
-    NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
-    SourceRange NNSRange = Importer.Import(D->getQualifierRange());
-    D2->setQualifierInfo(NNS, NNSRange);
-  }
+  D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
   D2->setAccess(D->getAccess());
   D2->setLexicalDeclContext(LexicalDC);
   Importer.Imported(D, D2);
@@ -2225,12 +2221,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
                                     Name.getAsIdentifierInfo(), 
                                     Importer.Import(D->getTagKeywordLoc()));
     }
-    // Import the qualifier, if any.
-    if (D->getQualifier()) {
-      NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
-      SourceRange NNSRange = Importer.Import(D->getQualifierRange());
-      D2->setQualifierInfo(NNS, NNSRange);
-    }
+    
+    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
     D2->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDecl(D2);
   }
@@ -2408,11 +2400,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
   }
 
   // Import the qualifier, if any.
-  if (D->getQualifier()) {
-    NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
-    SourceRange NNSRange = Importer.Import(D->getQualifierRange());
-    ToFunction->setQualifierInfo(NNS, NNSRange);
-  }
+  ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
   ToFunction->setAccess(D->getAccess());
   ToFunction->setLexicalDeclContext(LexicalDC);
   ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
@@ -2666,12 +2654,7 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
                                    Name.getAsIdentifierInfo(), T, TInfo,
                                    D->getStorageClass(),
                                    D->getStorageClassAsWritten());
-  // Import the qualifier, if any.
-  if (D->getQualifier()) {
-    NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
-    SourceRange NNSRange = Importer.Import(D->getQualifierRange());
-    ToVar->setQualifierInfo(NNS, NNSRange);
-  }
+  ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
   ToVar->setAccess(D->getAccess());
   ToVar->setLexicalDeclContext(LexicalDC);
   Importer.Imported(D, ToVar);
@@ -3591,14 +3574,7 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
                                                      Name.getAsIdentifierInfo(),                                                       
                                Importer.Import(DTemplated->getTagKeywordLoc()));
   D2Templated->setAccess(DTemplated->getAccess());
-  
-  
-  // Import the qualifier, if any.
-  if (DTemplated->getQualifier()) {
-    NestedNameSpecifier *NNS = Importer.Import(DTemplated->getQualifier());
-    SourceRange NNSRange = Importer.Import(DTemplated->getQualifierRange());
-    D2Templated->setQualifierInfo(NNS, NNSRange);
-  }
+  D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
   D2Templated->setLexicalDeclContext(LexicalDC);
   
   // Create the class template declaration itself.
@@ -3703,12 +3679,7 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
     ClassTemplate->AddSpecialization(D2, InsertPos);
     
     // Import the qualifier, if any.
-    if (D->getQualifier()) {
-      NestedNameSpecifier *NNS = Importer.Import(D->getQualifier());
-      SourceRange NNSRange = Importer.Import(D->getQualifierRange());
-      D2->setQualifierInfo(NNS, NNSRange);
-    }
-
+    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
     
     // Add the specialization to this context.
     D2->setLexicalDeclContext(LexicalDC);
@@ -4067,6 +4038,11 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
   return 0;
 }
 
+NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
+  // FIXME: Implement!
+  return NestedNameSpecifierLoc();
+}
+
 TemplateName ASTImporter::Import(TemplateName From) {
   switch (From.getKind()) {
   case TemplateName::Template:
index ccc883e944fcb936731f88e71b02813b44eac78c..d7e389e616413988fb1ff41d6c226300d91852c4 100644 (file)
@@ -935,9 +935,8 @@ SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
   return SourceLocation();
 }
 
-void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
-                                      SourceRange QualifierRange) {
-  if (Qualifier) {
+void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
+  if (QualifierLoc) {
     // Make sure the extended decl info is allocated.
     if (!hasExtInfo()) {
       // Save (non-extended) type source info pointer.
@@ -948,12 +947,10 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
       getExtInfo()->TInfo = savedTInfo;
     }
     // Set qualifier info.
-    getExtInfo()->NNS = Qualifier;
-    getExtInfo()->NNSRange = QualifierRange;
+    getExtInfo()->QualifierLoc = QualifierLoc;
   }
   else {
     // Here Qualifier == 0, i.e., we are removing the qualifier (if any).
-    assert(QualifierRange.isInvalid());
     if (hasExtInfo()) {
       // Save type source info pointer.
       TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
@@ -975,7 +972,7 @@ QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
                                              TemplateParameterList **TPLists) {
   assert((NumTPLists == 0 || TPLists != 0) &&
          "Empty array of template parameters with positive size!");
-  assert((NumTPLists == 0 || NNS) &&
+  assert((NumTPLists == 0 || QualifierLoc) &&
          "Nonempty array of template parameters with no qualifier!");
 
   // Free previous template parameters (if any).
@@ -2027,19 +2024,16 @@ TagDecl* TagDecl::getDefinition() const {
   return 0;
 }
 
-void TagDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
-                               SourceRange QualifierRange) {
-  if (Qualifier) {
+void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
+  if (QualifierLoc) {
     // Make sure the extended qualifier info is allocated.
     if (!hasExtInfo())
       TypedefDeclOrQualifier = new (getASTContext()) ExtInfo;
     // Set qualifier info.
-    getExtInfo()->NNS = Qualifier;
-    getExtInfo()->NNSRange = QualifierRange;
+    getExtInfo()->QualifierLoc = QualifierLoc;
   }
   else {
     // Here Qualifier == 0, i.e., we are removing the qualifier (if any).
-    assert(QualifierRange.isInvalid());
     if (hasExtInfo()) {
       getASTContext().Deallocate(getExtInfo());
       TypedefDeclOrQualifier = (TypedefDecl*) 0;
index 2d8537428086d2a0fe2d5d8e4f2dd5b53bdcbbcd..037594a44a1c6125cdf147d2b769cca2fc7e5078 100644 (file)
@@ -265,7 +265,8 @@ void CXXScopeSpec::Adopt(NestedNameSpecifierLoc Other) {
   BufferCapacity = 0;
 }
 
-NestedNameSpecifierLoc CXXScopeSpec::getWithLocInContext(ASTContext &Context) {
+NestedNameSpecifierLoc 
+CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
   if (isEmpty() || isInvalid())
     return NestedNameSpecifierLoc();
   
index 75e7c6f2d9c77ce69e397389811ef40016917f06..d6efd7a6c9dd468d1816af0e990d0f68aa2bb87a 100644 (file)
@@ -2895,8 +2895,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
 static void SetNestedNameSpecifier(DeclaratorDecl *DD, Declarator &D) {
   CXXScopeSpec &SS = D.getCXXScopeSpec();
   if (!SS.isSet()) return;
-  DD->setQualifierInfo(static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
-                       SS.getRange());
+  DD->setQualifierInfo(SS.getWithLocInContext(DD->getASTContext()));
 }
 
 NamedDecl*
@@ -6445,9 +6444,7 @@ CreateNewDecl:
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
     if (SS.isSet()) {
-      NestedNameSpecifier *NNS
-        = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
-      New->setQualifierInfo(NNS, SS.getRange());
+      New->setQualifierInfo(SS.getWithLocInContext(Context));
       if (NumMatchedTemplateParamLists > 0) {
         New->setTemplateParameterListsInfo(Context,
                                            NumMatchedTemplateParamLists,
index bef1bb451f028c337e4dc568f5be7c6551085f4d..893cf6ac26e47f3f28a6db0e4c4a816402b92784 100644 (file)
@@ -2841,7 +2841,7 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
                                 FD->getType(), FD->getTypeSourceInfo());
     if (FD->getQualifier()) {
       FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
-      NewFD->setQualifierInfo(FD->getQualifier(), FD->getQualifierRange());
+      NewFD->setQualifierInfo(FD->getQualifierLoc());
     }
   } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
     NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
@@ -2851,7 +2851,7 @@ NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
                            VD->getStorageClassAsWritten());
     if (VD->getQualifier()) {
       VarDecl *NewVD = cast<VarDecl>(NewD);
-      NewVD->setQualifierInfo(VD->getQualifier(), VD->getQualifierRange());
+      NewVD->setQualifierInfo(VD->getQualifierLoc());
     }
   }
   return NewD;
index 8f7b7da6f3be4dfca5686bfccd44a07a2fdae62f..5b09dfcee1572b1029b9529d4ec19ea0463da4dd 100644 (file)
@@ -783,8 +783,7 @@ Sema::ActOnTemplateParameterList(unsigned Depth,
 
 static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) {
   if (SS.isSet())
-    T->setQualifierInfo(static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
-                        SS.getRange());
+    T->setQualifierInfo(SS.getWithLocInContext(T->getASTContext()));
 }
 
 DeclResult
index 44f5913d55c7c84edd54731ebdaeb97b3555f59a..ae0ac9cbe35c523af214be766c21a523d57c9cb0 100644 (file)
@@ -2140,6 +2140,17 @@ Sema::SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
   return Instantiator.TransformNestedNameSpecifier(NNS, Range);
 }
 
+NestedNameSpecifierLoc
+Sema::SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
+                        const MultiLevelTemplateArgumentList &TemplateArgs) {  
+  if (!NNS)
+    return NestedNameSpecifierLoc();
+  
+  TemplateInstantiator Instantiator(*this, TemplateArgs, NNS.getBeginLoc(),
+                                    DeclarationName());
+  return Instantiator.TransformNestedNameSpecifierLoc(NNS);
+}
+
 /// \brief Do template substitution on declaration name info.
 DeclarationNameInfo
 Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
index e1a70651972f783af9467d6e84cd2399559ac075..f437cd30924f9afabea78dd5ce5ff8e1402a1792 100644 (file)
@@ -27,33 +27,33 @@ using namespace clang;
 
 bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl,
                                               DeclaratorDecl *NewDecl) {
-  NestedNameSpecifier *OldQual = OldDecl->getQualifier();
-  if (!OldQual) return false;
-
-  SourceRange QualRange = OldDecl->getQualifierRange();
-
-  NestedNameSpecifier *NewQual
-    = SemaRef.SubstNestedNameSpecifier(OldQual, QualRange, TemplateArgs);
-  if (!NewQual)
+  if (!OldDecl->getQualifierLoc())
+    return false;
+  
+  NestedNameSpecifierLoc NewQualifierLoc
+    = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), 
+                                          TemplateArgs);
+  
+  if (!NewQualifierLoc)
     return true;
-
-  NewDecl->setQualifierInfo(NewQual, QualRange);
+  
+  NewDecl->setQualifierInfo(NewQualifierLoc);
   return false;
 }
 
 bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,
                                               TagDecl *NewDecl) {
-  NestedNameSpecifier *OldQual = OldDecl->getQualifier();
-  if (!OldQual) return false;
-
-  SourceRange QualRange = OldDecl->getQualifierRange();
-
-  NestedNameSpecifier *NewQual
-    = SemaRef.SubstNestedNameSpecifier(OldQual, QualRange, TemplateArgs);
-  if (!NewQual)
+  if (!OldDecl->getQualifierLoc())
+    return false;
+  
+  NestedNameSpecifierLoc NewQualifierLoc
+  = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(), 
+                                        TemplateArgs);
+  
+  if (!NewQualifierLoc)
     return true;
-
-  NewDecl->setQualifierInfo(NewQual, QualRange);
+  
+  NewDecl->setQualifierInfo(NewQualifierLoc);
   return false;
 }
 
@@ -642,12 +642,12 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   // Instantiate the qualifier.  We have to do this first in case
   // we're a friend declaration, because if we are then we need to put
   // the new declaration in the appropriate context.
-  NestedNameSpecifier *Qualifier = Pattern->getQualifier();
-  if (Qualifier) {
-    Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
-                                                 Pattern->getQualifierRange(),
-                                                 TemplateArgs);
-    if (!Qualifier) return 0;
+  NestedNameSpecifierLoc QualifierLoc = Pattern->getQualifierLoc();
+  if (QualifierLoc) {
+    QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
+                                                       TemplateArgs);
+    if (!QualifierLoc)
+      return 0;
   }
 
   CXXRecordDecl *PrevDecl = 0;
@@ -668,9 +668,9 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   // the appropriate context.
   DeclContext *DC = Owner;
   if (isFriend) {
-    if (Qualifier) {
+    if (QualifierLoc) {
       CXXScopeSpec SS;
-      SS.MakeTrivial(SemaRef.Context, Qualifier, Pattern->getQualifierRange());
+      SS.Adopt(QualifierLoc);
       DC = SemaRef.computeDeclContext(SS);
       if (!DC) return 0;
     } else {
@@ -691,10 +691,10 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
         PrevDecl = PrevClassTemplate->getTemplatedDecl();
     }
 
-    if (!PrevClassTemplate && Qualifier) {
+    if (!PrevClassTemplate && QualifierLoc) {
       SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope)
         << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC
-        << Pattern->getQualifierRange();
+        << QualifierLoc.getSourceRange();
       return 0;
     }
 
@@ -755,8 +755,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
                             Pattern->getTagKeywordLoc(), PrevDecl,
                             /*DelayTypeCreation=*/true);
 
-  if (Qualifier)
-    RecordInst->setQualifierInfo(Qualifier, Pattern->getQualifierRange());
+  if (QualifierLoc)
+    RecordInst->setQualifierInfo(QualifierLoc);
 
   ClassTemplateDecl *Inst
     = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(),
@@ -968,12 +968,12 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
     return 0;
   QualType T = TInfo->getType();
 
-  NestedNameSpecifier *Qualifier = D->getQualifier();
-  if (Qualifier) {
-    Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
-                                                 D->getQualifierRange(),
-                                                 TemplateArgs);
-    if (!Qualifier) return 0;
+  NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
+  if (QualifierLoc) {
+    QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
+                                                       TemplateArgs);
+    if (!QualifierLoc)
+      return 0;
   }
 
   // If we're instantiating a local function declaration, put the result
@@ -981,9 +981,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
   DeclContext *DC;
   if (D->getDeclContext()->isFunctionOrMethod())
     DC = Owner;
-  else if (isFriend && Qualifier) {
+  else if (isFriend && QualifierLoc) {
     CXXScopeSpec SS;
-    SS.MakeTrivial(SemaRef.Context, Qualifier, D->getQualifierRange());
+    SS.Adopt(QualifierLoc);
     DC = SemaRef.computeDeclContext(SS);
     if (!DC) return 0;
   } else {
@@ -997,8 +997,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
                            D->getStorageClass(), D->getStorageClassAsWritten(),
                            D->isInlineSpecified(), D->hasWrittenPrototype());
 
-  if (Qualifier)
-    Function->setQualifierInfo(Qualifier, D->getQualifierRange());
+  if (QualifierLoc)
+    Function->setQualifierInfo(QualifierLoc);
 
   DeclContext *LexicalDC = Owner;
   if (!isFriend && D->isOutOfLine()) {
@@ -1260,19 +1260,19 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
       return 0;    
   }
 
-  NestedNameSpecifier *Qualifier = D->getQualifier();
-  if (Qualifier) {
-    Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
-                                                 D->getQualifierRange(),
+  NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
+  if (QualifierLoc) {
+    QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
                                                  TemplateArgs);
-    if (!Qualifier) return 0;
+    if (!QualifierLoc) 
+      return 0;
   }
 
   DeclContext *DC = Owner;
   if (isFriend) {
-    if (Qualifier) {
+    if (QualifierLoc) {
       CXXScopeSpec SS;
-      SS.MakeTrivial(SemaRef.Context, Qualifier, D->getQualifierRange());
+      SS.Adopt(QualifierLoc);
       DC = SemaRef.computeDeclContext(SS);
 
       if (DC && SemaRef.RequireCompleteDeclContext(SS, DC))
@@ -1315,8 +1315,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
                                    D->isInlineSpecified());
   }
 
-  if (Qualifier)
-    Method->setQualifierInfo(Qualifier, D->getQualifierRange());
+  if (QualifierLoc)
+    Method->setQualifierInfo(QualifierLoc);
 
   if (TemplateParams) {
     // Our resulting instantiation is actually a function template, since we
index fa0c2b97d4ec18cd2965daedbf96112bba59ab81..641df425ad174e8fd1cd5e45845e2d031bc7f629 100644 (file)
@@ -385,6 +385,17 @@ public:
                                               QualType ObjectType = QualType(),
                                           NamedDecl *FirstQualifierInScope = 0);
 
+  /// \brief Transform the given nested-name-specifier with source-location
+  /// information.
+  ///
+  /// By default, transforms all of the types and declarations within the
+  /// nested-name-specifier. Subclasses may override this function to provide
+  /// alternate behavior.
+  NestedNameSpecifierLoc TransformNestedNameSpecifierLoc(
+                                                    NestedNameSpecifierLoc NNS,
+                                          QualType ObjectType = QualType(),
+                                          NamedDecl *FirstQualifierInScope = 0);
+
   /// \brief Transform the given declaration name.
   ///
   /// By default, transforms the types of conversion function, constructor,
@@ -2264,6 +2275,11 @@ private:
                                              QualType ObjectType,
                                              NamedDecl *FirstQualifierInScope,
                                              NestedNameSpecifier *Prefix);
+  
+  TypeLoc TransformTypeInObjectScope(TypeLoc TL,
+                                     QualType ObjectType,
+                                     NamedDecl *FirstQualifierInScope,
+                                     CXXScopeSpec &SS);
 };
 
 template<typename Derived>
@@ -2503,6 +2519,105 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
   return 0;
 }
 
+template<typename Derived>
+NestedNameSpecifierLoc
+TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
+                                                    NestedNameSpecifierLoc NNS,
+                                                     QualType ObjectType,
+                                             NamedDecl *FirstQualifierInScope) {
+  llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
+  for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier; 
+       Qualifier = Qualifier.getPrefix())
+    Qualifiers.push_back(Qualifier);
+
+  CXXScopeSpec SS;
+  while (!Qualifiers.empty()) {
+    NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
+    NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
+    
+    switch (QNNS->getKind()) {
+    case NestedNameSpecifier::Identifier:
+      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/0, 
+                                              *QNNS->getAsIdentifier(),
+                                              Q.getLocalBeginLoc(), 
+                                              Q.getLocalEndLoc(),
+                                              ObjectType, false, SS, 
+                                              FirstQualifierInScope, false))
+        return NestedNameSpecifierLoc();
+        
+      break;
+      
+    case NestedNameSpecifier::Namespace: {
+      NamespaceDecl *NS
+        = cast_or_null<NamespaceDecl>(
+                                    getDerived().TransformDecl(
+                                                          Q.getLocalBeginLoc(),
+                                                       QNNS->getAsNamespace()));
+      SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
+      break;
+    }
+      
+    case NestedNameSpecifier::NamespaceAlias: {
+      NamespaceAliasDecl *Alias
+        = cast_or_null<NamespaceAliasDecl>(
+                      getDerived().TransformDecl(Q.getLocalBeginLoc(),
+                                                 QNNS->getAsNamespaceAlias()));
+      SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(), 
+                Q.getLocalEndLoc());
+      break;
+    }
+      
+    case NestedNameSpecifier::Global:
+      // There is no meaningful transformation that one could perform on the
+      // global scope.
+      SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
+      break;
+      
+    case NestedNameSpecifier::TypeSpecWithTemplate:
+    case NestedNameSpecifier::TypeSpec: {
+      TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
+                                              FirstQualifierInScope, SS);
+      
+      if (!TL)
+        return NestedNameSpecifierLoc();
+      
+      if (TL.getType()->isDependentType() || TL.getType()->isRecordType() ||
+          (SemaRef.getLangOptions().CPlusPlus0x && 
+           TL.getType()->isEnumeralType())) {
+        assert(!TL.getType().hasLocalQualifiers() && 
+               "Can't get cv-qualifiers here");
+        SS.Extend(SemaRef.Context, /*FIXME:*/SourceLocation(), TL,
+                  Q.getLocalEndLoc());
+        break;
+      }
+      
+      SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) 
+        << TL.getType() << SS.getRange();
+      return NestedNameSpecifierLoc();
+    }
+  }
+    
+    // The object type and qualifier-in-scope really apply to the
+    // leftmost entity.
+    ObjectType = QualType();
+    FirstQualifierInScope = 0;
+  }
+  
+  // Don't rebuild the nested-name-specifier if we don't have to.
+  if (SS.getScopeRep() == NNS.getNestedNameSpecifier() && 
+      !getDerived().AlwaysRebuild())
+    return NNS;
+  
+  // If we can re-use the source-location data from the original 
+  // nested-name-specifier, do so.
+  if (SS.location_size() == NNS.getDataLength() &&
+      memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
+    return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
+
+  // Allocate new nested-name-specifier location information.
+  return SS.getWithLocInContext(SemaRef.Context);
+}
+
 template<typename Derived>
 DeclarationNameInfo
 TreeTransform<Derived>
@@ -3099,7 +3214,7 @@ TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSI,
                                                    QualType ObjectType,
                                                    NamedDecl *UnqualLookup,
                                                   NestedNameSpecifier *Prefix) {
-  // TODO: in some cases, we might be some verification to do here.
+  // TODO: in some cases, we might have some verification to do here.
   if (ObjectType.isNull())
     return getDerived().TransformType(TSI);
 
@@ -3136,6 +3251,62 @@ TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSI,
   return TLB.getTypeSourceInfo(SemaRef.Context, Result);
 }
 
+template<typename Derived>
+TypeLoc
+TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
+                                                   QualType ObjectType,
+                                                   NamedDecl *UnqualLookup,
+                                                   CXXScopeSpec &SS) {
+  // FIXME: Painfully copy-paste from the above!
+  
+  // TODO: in some cases, we might have some verification to do here.
+  if (ObjectType.isNull()) {
+    TypeLocBuilder TLB;
+    TLB.reserve(TL.getFullDataSize());
+    QualType Result = getDerived().TransformType(TLB, TL);
+    if (Result.isNull())
+      return TypeLoc();
+    
+    return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc();
+  }
+  
+  QualType T = TL.getType();
+  if (getDerived().AlreadyTransformed(T))
+    return TL;
+  
+  TypeLocBuilder TLB;
+  QualType Result;
+  
+  if (isa<TemplateSpecializationType>(T)) {
+    TemplateSpecializationTypeLoc SpecTL
+      = cast<TemplateSpecializationTypeLoc>(TL);
+    
+    TemplateName Template =
+      getDerived().TransformTemplateName(SpecTL.getTypePtr()->getTemplateName(),
+                                         ObjectType, UnqualLookup);
+    if (Template.isNull()) 
+      return TypeLoc();
+    
+    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, 
+                                                              Template);
+  } else if (isa<DependentTemplateSpecializationType>(T)) {
+    DependentTemplateSpecializationTypeLoc SpecTL
+      = cast<DependentTemplateSpecializationTypeLoc>(TL);
+    
+    Result = getDerived().TransformDependentTemplateSpecializationType(TLB, 
+                                                                       SpecTL, 
+                                                             SS.getScopeRep());
+  } else {
+    // Nothing special needs to be done for these.
+    Result = getDerived().TransformType(TLB, TL);
+  }
+  
+  if (Result.isNull()) 
+    return TypeLoc();
+  
+  return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc();
+}
+
 template <class TyLoc> static inline
 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
   TyLoc NewT = TLB.push<TyLoc>(T.getType());
@@ -4351,7 +4522,8 @@ QualType TreeTransform<Derived>::
   TemplateArgumentListInfo NewTemplateArgs;
   NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
   NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
-            
+      
+  // FIXME: Nested-name-specifier source location info!
   typedef TemplateArgumentLocContainerIterator<
                             DependentTemplateSpecializationTypeLoc> ArgIterator;
   if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
index 93e36069429531dec132e4294532e097e629a728..c3953ba554dcf59cae890628f821f1ad9150ce1d 100644 (file)
@@ -4480,8 +4480,7 @@ void ASTReader::ReadDeclarationNameInfo(PerFileData &F,
 
 void ASTReader::ReadQualifierInfo(PerFileData &F, QualifierInfo &Info,
                                   const RecordData &Record, unsigned &Idx) {
-  Info.NNS = ReadNestedNameSpecifier(Record, Idx);
-  Info.NNSRange = ReadSourceRange(F, Record, Idx);
+  Info.QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
   unsigned NumTPLists = Record[Idx++];
   Info.NumTemplParamLists = NumTPLists;
   if (NumTPLists) {
index ba2494b5c51bd1d5a88d3bc0a6ed96f688f38021..383ca3dffc6cf56b2b74f232186e13040caa73cc 100644 (file)
@@ -3443,8 +3443,7 @@ void ASTWriter::AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
 
 void ASTWriter::AddQualifierInfo(const QualifierInfo &Info,
                                  RecordDataImpl &Record) {
-  AddNestedNameSpecifier(Info.NNS, Record);
-  AddSourceRange(Info.NNSRange, Record);
+  AddNestedNameSpecifierLoc(Info.QualifierLoc, Record);
   Record.push_back(Info.NumTemplParamLists);
   for (unsigned i=0, e=Info.NumTemplParamLists; i != e; ++i)
     AddTemplateParameterList(Info.TemplParamLists[i], Record);
index 13bcc98db5f2c494e3384cd5e4f147c44571db7b..6b2c9c4664af4d130a05f2c6c41481ec941565c7 100644 (file)
@@ -17,9 +17,24 @@ struct X_vector : outer_alias::inner::vector<X> {
   using outer_alias::inner::vector<X>::iterator;
 };
 
+namespace outer {
+  namespace inner {
+    template<typename T, unsigned N>
+    struct array {
+      void foo();
+      static int max_size;
+    };
+  }
+}
+
+template<typename T, unsigned N>
+void outer::inner::array<T, N>::foo() {
+}
 
+template<typename T, unsigned N>
+int outer::inner::array<T, N>::max_size = 17;
 
-// RUN: c-index-test -test-annotate-tokens=%s:13:1:19:1 %s | FileCheck %s
+// RUN: c-index-test -test-annotate-tokens=%s:13:1:36: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
@@ -40,3 +55,5 @@ struct X_vector : outer_alias::inner::vector<X> {
 // CHECK: Punctuation: ">" [17:37 - 17:38] UsingDeclaration=iterator[5:18]
 // 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.
index dfcf220ff49d75228e97683d1566d2d98e0c5ea2..425832596a95a37ece6fe6f449be433dabd3c8c0 100644 (file)
@@ -686,6 +686,11 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
     if (Visit(TSInfo->getTypeLoc()))
       return true;
 
+  // Visit the nested-name-specifier, if present.
+  if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+
   return false;
 }
 
@@ -719,8 +724,8 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
       return true;
     
     // Visit the nested-name-specifier, if present.
-    if (NestedNameSpecifier *Qualifier = ND->getQualifier())
-      if (VisitNestedNameSpecifier(Qualifier, ND->getQualifierRange()))
+    if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
+      if (VisitNestedNameSpecifierLoc(QualifierLoc))
         return true;
     
     // Visit the declaration name.
@@ -1209,7 +1214,7 @@ CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
     switch (NNS->getKind()) {
     case NestedNameSpecifier::Namespace:
       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), 
-                                       Q.getLocalSourceRange().getBegin(),
+                                       Q.getLocalBeginLoc(),
                                        TU)))
         return true;
         
@@ -1217,7 +1222,7 @@ CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
       
     case NestedNameSpecifier::NamespaceAlias:
       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 
-                                       Q.getLocalSourceRange().getBegin(),
+                                       Q.getLocalBeginLoc(),
                                        TU)))
         return true;
         
@@ -1502,6 +1507,11 @@ bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
 }
 
 bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
+  // Visit the nested-name-specifier, if present.
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
+      return true;
+
   if (D->isDefinition()) {
     for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
          E = D->bases_end(); I != E; ++I) {