[cfe-commits] r126358 - in /cfe/trunk: include/clang/AST/NestedNameSpecifier.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/DeclSpec.h lib/AST/ASTContext.cpp lib/AST/ItaniumMangle.cpp lib/AST/NestedNameSpecifier.cpp lib/Frontend/DocumentXML.cpp lib/Sema/DeclSpec.cpp lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaType.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp tools/libclang/CIndex.cpp

Douglas Gregor dgregor at apple.com
Wed Feb 23 18:36:08 PST 2011


Author: dgregor
Date: Wed Feb 23 20:36:08 2011
New Revision: 126358

URL: http://llvm.org/viewvc/llvm-project?rev=126358&view=rev
Log:
Teach NestedNameSpecifier to keep track of namespace aliases the same
way it keeps track of namespaces. Previously, we would map from the
namespace alias to its underlying namespace when building a
nested-name-specifier, losing source information in the process.


Modified:
    cfe/trunk/include/clang/AST/NestedNameSpecifier.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/NestedNameSpecifier.cpp
    cfe/trunk/lib/Frontend/DocumentXML.cpp
    cfe/trunk/lib/Sema/DeclSpec.cpp
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/NestedNameSpecifier.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/NestedNameSpecifier.h?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/NestedNameSpecifier.h (original)
+++ cfe/trunk/include/clang/AST/NestedNameSpecifier.h Wed Feb 23 20:36:08 2011
@@ -25,6 +25,7 @@
 namespace clang {
 
 class ASTContext;
+class NamespaceAliasDecl;
 class NamespaceDecl;
 class IdentifierInfo;
 struct PrintingPolicy;
@@ -41,13 +42,22 @@
 /// (for dependent names), or the global specifier ('::', must be the
 /// first specifier).
 class NestedNameSpecifier : public llvm::FoldingSetNode {
+
+  /// \brief Enumeration describing
+  enum StoredSpecifierKind {
+    StoredIdentifier = 0,
+    StoredNamespaceOrAlias = 1,
+    StoredTypeSpec = 2,
+    StoredTypeSpecWithTemplate = 3
+  };
+
   /// \brief The nested name specifier that precedes this nested name
   /// specifier.
   ///
   /// The pointer is the nested-name-specifier that precedes this
   /// one. The integer stores one of the first four values of type
   /// SpecifierKind.
-  llvm::PointerIntPair<NestedNameSpecifier *, 2> Prefix;
+  llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
 
   /// \brief The last component in the nested name specifier, which
   /// can be an identifier, a declaration, or a type.
@@ -63,21 +73,23 @@
   /// specifier.
   enum SpecifierKind {
     /// \brief An identifier, stored as an IdentifierInfo*.
-    Identifier = 0,
-    /// \brief A namespace, stored as a Namespace*.
-    Namespace = 1,
+    Identifier,
+    /// \brief A namespace, stored as a NamespaceDecl*.
+    Namespace,
+    /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
+    NamespaceAlias,
     /// \brief A type, stored as a Type*.
-    TypeSpec = 2,
+    TypeSpec,
     /// \brief A type that was preceded by the 'template' keyword,
     /// stored as a Type*.
-    TypeSpecWithTemplate = 3,
+    TypeSpecWithTemplate,
     /// \brief The global specifier '::'. There is no stored value.
-    Global = 4
+    Global
   };
 
 private:
   /// \brief Builds the global specifier.
-  NestedNameSpecifier() : Prefix(0, 0), Specifier(0) { }
+  NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
 
   /// \brief Copy constructor used internally to clone nested name
   /// specifiers.
@@ -108,6 +120,11 @@
                                      NestedNameSpecifier *Prefix,
                                      NamespaceDecl *NS);
 
+  /// \brief Builds a nested name specifier that names a namespace alias.
+  static NestedNameSpecifier *Create(const ASTContext &Context,
+                                     NestedNameSpecifier *Prefix,
+                                     NamespaceAliasDecl *Alias);
+
   /// \brief Builds a nested name specifier that names a type.
   static NestedNameSpecifier *Create(const ASTContext &Context,
                                      NestedNameSpecifier *Prefix,
@@ -136,16 +153,12 @@
   NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
 
   /// \brief Determine what kind of nested name specifier is stored.
-  SpecifierKind getKind() const {
-    if (Specifier == 0)
-      return Global;
-    return (SpecifierKind)Prefix.getInt();
-  }
+  SpecifierKind getKind() const;
 
   /// \brief Retrieve the identifier stored in this nested name
   /// specifier.
   IdentifierInfo *getAsIdentifier() const {
-    if (Prefix.getInt() == Identifier)
+    if (Prefix.getInt() == StoredIdentifier)
       return (IdentifierInfo *)Specifier;
 
     return 0;
@@ -153,17 +166,16 @@
 
   /// \brief Retrieve the namespace stored in this nested name
   /// specifier.
-  NamespaceDecl *getAsNamespace() const {
-    if (Prefix.getInt() == Namespace)
-      return (NamespaceDecl *)Specifier;
+  NamespaceDecl *getAsNamespace() const;
 
-    return 0;
-  }
+  /// \brief Retrieve the namespace alias stored in this nested name
+  /// specifier.
+  NamespaceAliasDecl *getAsNamespaceAlias() const;
 
   /// \brief Retrieve the type stored in this nested name specifier.
   const Type *getAsType() const {
-    if (Prefix.getInt() == TypeSpec ||
-        Prefix.getInt() == TypeSpecWithTemplate)
+    if (Prefix.getInt() == StoredTypeSpec ||
+        Prefix.getInt() == StoredTypeSpecWithTemplate)
       return (const Type *)Specifier;
 
     return 0;

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Feb 23 20:36:08 2011
@@ -502,6 +502,7 @@
   switch (NNS->getKind()) {
   case NestedNameSpecifier::Identifier:
   case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
   case NestedNameSpecifier::Global:
     return true;
 

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Wed Feb 23 20:36:08 2011
@@ -34,6 +34,7 @@
   class LangOptions;
   class Diagnostic;
   class IdentifierInfo;
+  class NamespaceAliasDecl;
   class NamespaceDecl;
   class NestedNameSpecifier;
   class Preprocessor;
@@ -96,21 +97,34 @@
               SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
 
   /// \brief Extend the current nested-name-specifier by another 
-  /// nested-name-specifier component of the form 'namespace-or-alias::'.
+  /// nested-name-specifier component of the form 'namespace::'.
   ///
   /// \param Context The AST context in which this nested-name-specifier
   /// resides.
   ///
   /// \param Namespace The namespace.
-  /// FIXME: This should also permit a namespace alias.
   ///
-  /// \param NamespaceLoc The location of the namespace or namespace alias 
-  /// name.
+  /// \param NamespaceLoc The location of the namespace name.
   ///
   /// \param ColonColonLoc The location of the trailing '::'.
   void Extend(ASTContext &Context, NamespaceDecl *Namespace,
               SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
 
+  /// \brief Extend the current nested-name-specifier by another 
+  /// nested-name-specifier component of the form 'namespace-alias::'.
+  ///
+  /// \param Context The AST context in which this nested-name-specifier
+  /// resides.
+  ///
+  /// \param Alias The namespace alias.
+  ///
+  /// \param AliasLoc The location of the namespace alias 
+  /// name.
+  ///
+  /// \param ColonColonLoc The location of the trailing '::'.
+  void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
+              SourceLocation AliasLoc, SourceLocation ColonColonLoc);
+
   /// \brief Turn this (empty) nested-name-specifier into the global
   /// nested-name-specifier '::'.
   void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Feb 23 20:36:08 2011
@@ -2981,7 +2981,15 @@
   case NestedNameSpecifier::Namespace:
     // A namespace is canonical; build a nested-name-specifier with
     // this namespace and no prefix.
-    return NestedNameSpecifier::Create(*this, 0, NNS->getAsNamespace());
+    return NestedNameSpecifier::Create(*this, 0, 
+                                 NNS->getAsNamespace()->getOriginalNamespace());
+
+  case NestedNameSpecifier::NamespaceAlias:
+    // A namespace is canonical; build a nested-name-specifier with
+    // this namespace and no prefix.
+    return NestedNameSpecifier::Create(*this, 0, 
+                                    NNS->getAsNamespaceAlias()->getNamespace()
+                                                      ->getOriginalNamespace());
 
   case NestedNameSpecifier::TypeSpec:
   case NestedNameSpecifier::TypeSpecWithTemplate: {

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Feb 23 20:36:08 2011
@@ -606,6 +606,9 @@
   case NestedNameSpecifier::Namespace:
     mangleName(Qualifier->getAsNamespace());
     break;
+  case NestedNameSpecifier::NamespaceAlias:
+    mangleName(Qualifier->getAsNamespaceAlias()->getNamespace());
+    break;
   case NestedNameSpecifier::TypeSpec:
   case NestedNameSpecifier::TypeSpecWithTemplate: {
     const Type *QTy = Qualifier->getAsType();

Modified: cfe/trunk/lib/AST/NestedNameSpecifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NestedNameSpecifier.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/AST/NestedNameSpecifier.cpp (original)
+++ cfe/trunk/lib/AST/NestedNameSpecifier.cpp Wed Feb 23 20:36:08 2011
@@ -14,6 +14,7 @@
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/Type.h"
 #include "llvm/Support/raw_ostream.h"
@@ -46,7 +47,7 @@
 
   NestedNameSpecifier Mockup;
   Mockup.Prefix.setPointer(Prefix);
-  Mockup.Prefix.setInt(Identifier);
+  Mockup.Prefix.setInt(StoredIdentifier);
   Mockup.Specifier = II;
   return FindOrInsert(Context, Mockup);
 }
@@ -60,19 +61,34 @@
          "Broken nested name specifier");
   NestedNameSpecifier Mockup;
   Mockup.Prefix.setPointer(Prefix);
-  Mockup.Prefix.setInt(Namespace);
+  Mockup.Prefix.setInt(StoredNamespaceOrAlias);
   Mockup.Specifier = NS;
   return FindOrInsert(Context, Mockup);
 }
 
 NestedNameSpecifier *
 NestedNameSpecifier::Create(const ASTContext &Context,
+                            NestedNameSpecifier *Prefix, 
+                            NamespaceAliasDecl *Alias) {
+  assert(Alias && "Namespace alias cannot be NULL");
+  assert((!Prefix ||
+          (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
+         "Broken nested name specifier");
+  NestedNameSpecifier Mockup;
+  Mockup.Prefix.setPointer(Prefix);
+  Mockup.Prefix.setInt(StoredNamespaceOrAlias);
+  Mockup.Specifier = Alias;
+  return FindOrInsert(Context, Mockup);
+}
+
+NestedNameSpecifier *
+NestedNameSpecifier::Create(const ASTContext &Context,
                             NestedNameSpecifier *Prefix,
                             bool Template, const Type *T) {
   assert(T && "Type cannot be NULL");
   NestedNameSpecifier Mockup;
   Mockup.Prefix.setPointer(Prefix);
-  Mockup.Prefix.setInt(Template? TypeSpecWithTemplate : TypeSpec);
+  Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
   Mockup.Specifier = const_cast<Type*>(T);
   return FindOrInsert(Context, Mockup);
 }
@@ -82,7 +98,7 @@
   assert(II && "Identifier cannot be NULL");
   NestedNameSpecifier Mockup;
   Mockup.Prefix.setPointer(0);
-  Mockup.Prefix.setInt(Identifier);
+  Mockup.Prefix.setInt(StoredIdentifier);
   Mockup.Specifier = II;
   return FindOrInsert(Context, Mockup);
 }
@@ -94,6 +110,47 @@
   return Context.GlobalNestedNameSpecifier;
 }
 
+NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
+  if (Specifier == 0)
+    return Global;
+
+  switch (Prefix.getInt()) {
+  case StoredIdentifier:
+    return Identifier;
+
+  case StoredNamespaceOrAlias:
+    return isa<NamespaceDecl>(static_cast<NamedDecl *>(Specifier))? Namespace
+                                                            : NamespaceAlias;
+
+  case StoredTypeSpec:
+    return TypeSpec;
+
+  case StoredTypeSpecWithTemplate:
+    return TypeSpecWithTemplate;
+  }
+
+  return Global;
+}
+
+/// \brief Retrieve the namespace stored in this nested name
+/// specifier.
+NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
+  if (Prefix.getInt() == StoredNamespaceOrAlias)
+    return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
+
+  return 0;
+}
+
+/// \brief Retrieve the namespace alias stored in this nested name
+/// specifier.
+NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
+  if (Prefix.getInt() == StoredNamespaceOrAlias)
+    return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
+
+  return 0;
+}
+
+
 /// \brief Whether this nested name specifier refers to a dependent
 /// type or not.
 bool NestedNameSpecifier::isDependent() const {
@@ -103,6 +160,7 @@
     return true;
 
   case Namespace:
+  case NamespaceAlias:
   case Global:
     return false;
 
@@ -121,6 +179,7 @@
     return getPrefix() && getPrefix()->containsUnexpandedParameterPack();
 
   case Namespace:
+  case NamespaceAlias:
   case Global:
     return false;
 
@@ -147,7 +206,11 @@
     break;
 
   case Namespace:
-    OS << getAsNamespace()->getIdentifier()->getName();
+    OS << getAsNamespace()->getName();
+    break;
+
+  case NamespaceAlias:
+    OS << getAsNamespaceAlias()->getName();
     break;
 
   case Global:

Modified: cfe/trunk/lib/Frontend/DocumentXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DocumentXML.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/DocumentXML.cpp (original)
+++ cfe/trunk/lib/Frontend/DocumentXML.cpp Wed Feb 23 20:36:08 2011
@@ -14,6 +14,7 @@
 
 #include "clang/Frontend/DocumentXML.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringExtras.h"
@@ -218,6 +219,10 @@
     addPtrAttribute(pAttributeName, pNNS->getAsNamespace());
     break;
   }
+  case NestedNameSpecifier::NamespaceAlias: {
+    addPtrAttribute(pAttributeName, pNNS->getAsNamespaceAlias());
+    break;
+  }
   case NestedNameSpecifier::TypeSpec: {
     addPtrAttribute(pAttributeName, pNNS->getAsType());
     break;

Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Wed Feb 23 20:36:08 2011
@@ -74,6 +74,15 @@
   Range.setEnd(ColonColonLoc);
 }
 
+void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
+                          SourceLocation AliasLoc, 
+                          SourceLocation ColonColonLoc) {
+  ScopeRep = NestedNameSpecifier::Create(Context, ScopeRep, Alias);
+  if (Range.getBegin().isInvalid())
+    Range.setBegin(AliasLoc);
+  Range.setEnd(ColonColonLoc);
+}
+
 void CXXScopeSpec::MakeGlobal(ASTContext &Context, 
                               SourceLocation ColonColonLoc) {
   assert(!ScopeRep && "Already have a nested-name-specifier!?");

Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Wed Feb 23 20:36:08 2011
@@ -139,6 +139,9 @@
   case NestedNameSpecifier::Namespace:
     return NNS->getAsNamespace();
 
+  case NestedNameSpecifier::NamespaceAlias:
+    return NNS->getAsNamespaceAlias()->getNamespace();
+
   case NestedNameSpecifier::TypeSpec:
   case NestedNameSpecifier::TypeSpecWithTemplate: {
     const TagType *Tag = NNS->getAsType()->getAs<TagType>();
@@ -532,11 +535,8 @@
       return false;
     }
 
-    // FIXME: It would be nice to maintain the namespace alias name, then
-    // see through that alias when resolving the nested-name-specifier down to
-    // a declaration context.
     if (NamespaceAliasDecl *Alias = dyn_cast<NamespaceAliasDecl>(SD)) {
-      SS.Extend(Context, Alias->getNamespace(), IdentifierLoc, CCLoc);
+      SS.Extend(Context, Alias, IdentifierLoc, CCLoc);
       return false;
     }
 
@@ -681,6 +681,7 @@
   switch (Qualifier->getKind()) {
   case NestedNameSpecifier::Global:
   case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
     // These are always namespace scopes.  We never want to enter a
     // namespace scope from anything but a file context.
     return CurContext->getRedeclContext()->isFileContext();

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Feb 23 20:36:08 2011
@@ -2868,6 +2868,7 @@
   switch (NNS->getKind()) {
   case NestedNameSpecifier::Identifier:
   case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
   case NestedNameSpecifier::Global:
     return false;
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Feb 23 20:36:08 2011
@@ -1895,6 +1895,7 @@
           break;
 
         case NestedNameSpecifier::Namespace:
+        case NestedNameSpecifier::NamespaceAlias:
         case NestedNameSpecifier::Global:
           llvm_unreachable("Nested-name-specifier must name a type");
           break;

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Feb 23 20:36:08 2011
@@ -877,6 +877,16 @@
                                                   NamespaceDecl *NS);
 
   /// \brief Build a new nested-name-specifier given the prefix and the
+  /// namespace alias named in the next step in the nested-name-specifier.
+  ///
+  /// By default, performs semantic analysis when building the new
+  /// nested-name-specifier. Subclasses may override this routine to provide
+  /// different behavior.
+  NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                  SourceRange Range,
+                                                  NamespaceAliasDecl *Alias);
+
+  /// \brief Build a new nested-name-specifier given the prefix and the
   /// type named in the next step in the nested-name-specifier.
   ///
   /// By default, performs semantic analysis when building the new
@@ -2450,6 +2460,19 @@
     return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
   }
 
+  case NestedNameSpecifier::NamespaceAlias: {
+    NamespaceAliasDecl *Alias
+      = cast_or_null<NamespaceAliasDecl>(
+                                    getDerived().TransformDecl(Range.getBegin(),
+                                                    NNS->getAsNamespaceAlias()));
+    if (!getDerived().AlwaysRebuild() &&
+        Prefix == NNS->getPrefix() &&
+        Alias == NNS->getAsNamespaceAlias())
+      return NNS;
+
+    return getDerived().RebuildNestedNameSpecifier(Prefix, Range, Alias);
+  }
+
   case NestedNameSpecifier::Global:
     // There is no meaningful transformation that one could perform on the
     // global scope.
@@ -7571,6 +7594,14 @@
 NestedNameSpecifier *
 TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
                                                    SourceRange Range,
+                                                   NamespaceAliasDecl *Alias) {
+  return NestedNameSpecifier::Create(SemaRef.Context, Prefix, Alias);
+}
+
+template<typename Derived>
+NestedNameSpecifier *
+TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
+                                                   SourceRange Range,
                                                    bool TemplateKW,
                                                    QualType T) {
   if (T->isDependentType() || T->isRecordType() ||

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Feb 23 20:36:08 2011
@@ -4730,6 +4730,13 @@
       break;
     }
 
+    case NestedNameSpecifier::NamespaceAlias: {
+      NamespaceAliasDecl *Alias
+        = cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
+      NNS = NestedNameSpecifier::Create(*Context, Prev, Alias);
+      break;
+    }
+
     case NestedNameSpecifier::TypeSpec:
     case NestedNameSpecifier::TypeSpecWithTemplate: {
       const Type *T = GetType(Record[Idx++]).getTypePtrOrNull();

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Feb 23 20:36:08 2011
@@ -3470,6 +3470,10 @@
       AddDeclRef(NNS->getAsNamespace(), Record);
       break;
 
+    case NestedNameSpecifier::NamespaceAlias:
+      AddDeclRef(NNS->getAsNamespaceAlias(), Record);
+      break;
+
     case NestedNameSpecifier::TypeSpec:
     case NestedNameSpecifier::TypeSpecWithTemplate:
       AddTypeRef(QualType(NNS->getAsType(), 0), Record);

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=126358&r1=126357&r2=126358&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Feb 23 20:36:08 2011
@@ -1163,11 +1163,13 @@
   
   switch (NNS->getKind()) {
   case NestedNameSpecifier::Namespace:
-    // FIXME: The token at this source location might actually have been a
-    // namespace alias, but we don't model that. Lame!
     return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
                                         TU));
 
+  case NestedNameSpecifier::NamespaceAlias:
+    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 
+                                        Range.getBegin(), TU));
+
   case NestedNameSpecifier::TypeSpec: {
     // If the type has a form where we know that the beginning of the source
     // range matches up with a reference cursor. Visit the appropriate reference





More information about the cfe-commits mailing list