Update UsingDecl, UnresolvedUsingTypenameDecl, and
UnresolvedUsingValueDecl to use NestedNameSpecifierLoc rather than the
extremely-lossy NestedNameSpecifier/SourceRange pair it used to use,
improving source-location information.

Various infrastructure updates to support NestedNameSpecifierLoc:
  - AST/PCH (de-)serialization
  - Recursive AST visitor
  - libclang traversal (including the first tests of this
    functionality)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126459 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index d11ee8f..7e8bc44 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -2002,15 +2002,11 @@
 /// UsingDecl - Represents a C++ using-declaration. For example:
 ///    using someNameSpace::someIdentifier;
 class UsingDecl : public NamedDecl {
-  /// \brief The source range that covers the nested-name-specifier
-  /// preceding the declaration name.
-  SourceRange NestedNameRange;
-
   /// \brief The source location of the "using" location itself.
   SourceLocation UsingLocation;
 
-  /// \brief Target nested name specifier.
-  NestedNameSpecifier* TargetNestedName;
+  /// \brief The nested-name-specifier that precedes the name.
+  NestedNameSpecifierLoc QualifierLoc;
 
   /// DNLoc - Provides source/type location info for the
   /// declaration name embedded in the ValueDecl base class.
@@ -2023,37 +2019,34 @@
   // \brief Has 'typename' keyword.
   bool IsTypeName;
 
-  UsingDecl(DeclContext *DC, SourceRange NNR,
-            SourceLocation UL, NestedNameSpecifier* TargetNNS,
+  UsingDecl(DeclContext *DC, SourceLocation UL, 
+            NestedNameSpecifierLoc QualifierLoc,
             const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
     : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
-      NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
+      UsingLocation(UL), QualifierLoc(QualifierLoc),
       DNLoc(NameInfo.getInfo()), FirstUsingShadow(0),IsTypeName(IsTypeNameArg) {
   }
 
 public:
-  /// \brief Returns the source range that covers the nested-name-specifier
-  /// preceding the namespace name.
-  SourceRange getNestedNameRange() const { return NestedNameRange; }
-
-  /// \brief Set the source range of the nested-name-specifier.
-  void setNestedNameRange(SourceRange R) { NestedNameRange = R; }
-
-  // FIXME: Naming is inconsistent with other get*Loc functions.
   /// \brief Returns the source location of the "using" keyword.
   SourceLocation getUsingLocation() const { return UsingLocation; }
 
   /// \brief Set the source location of the 'using' keyword.
   void setUsingLocation(SourceLocation L) { UsingLocation = L; }
 
-  /// \brief Get the target nested name declaration.
-  NestedNameSpecifier* getTargetNestedNameDecl() const {
-    return TargetNestedName;
+  /// \brief Retrieve the nested-name-specifier that qualifies the name,
+  /// with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name.
+  NestedNameSpecifier *getQualifier() const { 
+    return QualifierLoc.getNestedNameSpecifier(); 
   }
 
-  /// \brief Set the target nested name declaration.
-  void setTargetNestedNameDecl(NestedNameSpecifier *NNS) {
-    TargetNestedName = NNS;
+  /// \brief Retrieve the source range of the nested-name-specifier
+  /// that qualifies the name.
+  SourceRange getQualifierRange() const { 
+    return QualifierLoc.getSourceRange();
   }
 
   DeclarationNameInfo getNameInfo() const {
@@ -2119,8 +2112,8 @@
   void removeShadowDecl(UsingShadowDecl *S);
 
   static UsingDecl *Create(ASTContext &C, DeclContext *DC,
-                           SourceRange NNR, SourceLocation UsingL,
-                           NestedNameSpecifier* TargetNNS,
+                           SourceLocation UsingL,
+                           NestedNameSpecifierLoc QualifierLoc,
                            const DeclarationNameInfo &NameInfo,
                            bool IsTypeNameArg);
 
@@ -2145,61 +2138,55 @@
 ///   using Base<T>::foo;
 /// };
 class UnresolvedUsingValueDecl : public ValueDecl {
-  /// \brief The source range that covers the nested-name-specifier
-  /// preceding the declaration name.
-  SourceRange TargetNestedNameRange;
-
   /// \brief The source location of the 'using' keyword
   SourceLocation UsingLocation;
 
-  NestedNameSpecifier *TargetNestedNameSpecifier;
+  /// \brief The nested-name-specifier that precedes the name.
+  NestedNameSpecifierLoc QualifierLoc;
 
   /// DNLoc - Provides source/type location info for the
   /// declaration name embedded in the ValueDecl base class.
   DeclarationNameLoc DNLoc;
 
   UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
-                           SourceLocation UsingLoc, SourceRange TargetNNR,
-                           NestedNameSpecifier *TargetNNS,
+                           SourceLocation UsingLoc, 
+                           NestedNameSpecifierLoc QualifierLoc,
                            const DeclarationNameInfo &NameInfo)
     : ValueDecl(UnresolvedUsingValue, DC,
                 NameInfo.getLoc(), NameInfo.getName(), Ty),
-      TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
-      TargetNestedNameSpecifier(TargetNNS), DNLoc(NameInfo.getInfo())
+      UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),
+      DNLoc(NameInfo.getInfo())
   { }
 
 public:
-  /// \brief Returns the source range that covers the nested-name-specifier
-  /// preceding the namespace name.
-  SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
-
-  /// \brief Set the source range coverting the nested-name-specifier preceding
-  /// the namespace name.
-  void setTargetNestedNameRange(SourceRange R) { TargetNestedNameRange = R; }
-
-  /// \brief Get target nested name declaration.
-  NestedNameSpecifier* getTargetNestedNameSpecifier() const {
-    return TargetNestedNameSpecifier;
-  }
-
-  /// \brief Set the nested name declaration.
-  void setTargetNestedNameSpecifier(NestedNameSpecifier* NNS) {
-    TargetNestedNameSpecifier = NNS;
-  }
-
   /// \brief Returns the source location of the 'using' keyword.
   SourceLocation getUsingLoc() const { return UsingLocation; }
 
   /// \brief Set the source location of the 'using' keyword.
   void setUsingLoc(SourceLocation L) { UsingLocation = L; }
 
+  /// \brief Retrieve the nested-name-specifier that qualifies the name,
+  /// with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name.
+  NestedNameSpecifier *getQualifier() const { 
+    return QualifierLoc.getNestedNameSpecifier(); 
+  }
+  
+  /// \brief Retrieve the source range of the nested-name-specifier
+  /// that qualifies the name.
+  SourceRange getQualifierRange() const { 
+    return QualifierLoc.getSourceRange();
+  }
+
   DeclarationNameInfo getNameInfo() const {
     return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
   }
 
   static UnresolvedUsingValueDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
-           SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+           NestedNameSpecifierLoc QualifierLoc, 
            const DeclarationNameInfo &NameInfo);
 
   SourceRange getSourceRange() const {
@@ -2224,49 +2211,52 @@
 /// The type associated with a unresolved using typename decl is
 /// currently always a typename type.
 class UnresolvedUsingTypenameDecl : public TypeDecl {
-  /// \brief The source range that covers the nested-name-specifier
-  /// preceding the declaration name.
-  SourceRange TargetNestedNameRange;
-
   /// \brief The source location of the 'using' keyword
   SourceLocation UsingLocation;
 
   /// \brief The source location of the 'typename' keyword
   SourceLocation TypenameLocation;
 
-  NestedNameSpecifier *TargetNestedNameSpecifier;
+  /// \brief The nested-name-specifier that precedes the name.
+  NestedNameSpecifierLoc QualifierLoc;
 
   UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
-                    SourceLocation TypenameLoc,
-                    SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
-                    SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
+                              SourceLocation TypenameLoc,
+                              NestedNameSpecifierLoc QualifierLoc,
+                              SourceLocation TargetNameLoc, 
+                              IdentifierInfo *TargetName)
   : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
-    TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
-    TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
-  { }
+    UsingLocation(UsingLoc), TypenameLocation(TypenameLoc), 
+    QualifierLoc(QualifierLoc) { }
 
   friend class ASTDeclReader;
   
 public:
-  /// \brief Returns the source range that covers the nested-name-specifier
-  /// preceding the namespace name.
-  SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
-
-  /// \brief Get target nested name declaration.
-  NestedNameSpecifier* getTargetNestedNameSpecifier() {
-    return TargetNestedNameSpecifier;
-  }
-
   /// \brief Returns the source location of the 'using' keyword.
   SourceLocation getUsingLoc() const { return UsingLocation; }
 
   /// \brief Returns the source location of the 'typename' keyword.
   SourceLocation getTypenameLoc() const { return TypenameLocation; }
 
+  /// \brief Retrieve the nested-name-specifier that qualifies the name,
+  /// with source-location information.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the name.
+  NestedNameSpecifier *getQualifier() const { 
+    return QualifierLoc.getNestedNameSpecifier(); 
+  }
+
+  /// \brief Retrieve the source range of the nested-name-specifier
+  /// that qualifies the name.
+  SourceRange getQualifierRange() const { 
+    return QualifierLoc.getSourceRange();
+  }
+
+  // FIXME: DeclarationNameInfo
   static UnresolvedUsingTypenameDecl *
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
-           SourceLocation TypenameLoc,
-           SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+           SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,
            SourceLocation TargetNameLoc, DeclarationName TargetName);
 
   SourceRange getSourceRange() const {
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 6d1798c..2803f51 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -30,6 +30,7 @@
 class IdentifierInfo;
 struct PrintingPolicy;
 class Type;
+class TypeLoc;
 class LangOptions;
 
 /// \brief Represents a C++ nested name specifier, such as
@@ -245,7 +246,7 @@
   /// For example, if this instance refers to a nested-name-specifier
   /// \c ::std::vector<int>::, the returned source range would cover
   /// from the initial '::' to the last '::'.
-  SourceRange getSourceRange();
+  SourceRange getSourceRange() const;
 
   /// \brief Retrieve the source range covering just the last part of
   /// this nested-name-specifier, not including the prefix.
@@ -253,7 +254,19 @@
   /// For example, if this instance refers to a nested-name-specifier
   /// \c ::std::vector<int>::, the returned source range would cover
   /// from "vector" to the last '::'.
-  SourceRange getLocalSourceRange();
+  SourceRange getLocalSourceRange() const;
+
+  /// \brief Retrieve the location of the beginning of this
+  /// nested-name-specifier.
+  SourceLocation getBeginLoc() const { 
+    return getSourceRange().getBegin();
+  }
+
+  /// \brief Retrieve the location of the end of this
+  /// nested-name-specifier.
+  SourceLocation getEndLoc() const { 
+    return getSourceRange().getEnd();
+  }
 
   /// \brief Return the prefix of this nested-name-specifier.
   ///
@@ -267,7 +280,11 @@
 
     return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
   }
-  
+
+  /// \brief For a nested-name-specifier that refers to a type,
+  /// retrieve the type with source-location information.
+  TypeLoc getTypeLoc() const;
+
   /// \brief Determines the data length for the entire
   /// nested-name-specifier.
   unsigned getDataLength() const { return getDataLength(Qualifier); }
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 328a737..6359241 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -181,6 +181,12 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
 
+  /// \brief Recursively visit a C++ nested-name-specifier with location 
+  /// information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
   /// \brief Recursively visit a template name and dispatch to the
   /// appropriate method.
   ///
@@ -515,6 +521,31 @@
 }
 
 template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
+                                                  NestedNameSpecifierLoc NNS) {
+  if (!NNS)
+    return true;
+  
+   if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+     TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+           
+  switch (NNS.getNestedNameSpecifier()->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+  case NestedNameSpecifier::Global:
+    return true;
+     
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
+    break;
+  }
+  
+  return true;
+}
+
+template<typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
     TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
@@ -1143,7 +1174,7 @@
   })
 
 DEF_TRAVERSE_DECL(UsingDecl, {
-    TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameDecl()));
+    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
   })
 
 DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
@@ -1313,7 +1344,7 @@
 DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
     // A dependent using declaration which was marked with 'typename'.
     //   template<class T> class A : public B<T> { using typename B<T>::foo; };
-    TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
+    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
     // We shouldn't traverse D->getTypeForDecl(); it's a result of
     // declaring the type, not something that was written in the
     // source.
@@ -1426,7 +1457,7 @@
 DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
     // Like UnresolvedUsingTypenameDecl, but without the 'typename':
     //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
-    TRY_TO(TraverseNestedNameSpecifier(D->getTargetNestedNameSpecifier()));
+    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
   })
 
 DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def
index 1b158fd..58f7e55 100644
--- a/include/clang/Frontend/DeclXML.def
+++ b/include/clang/Frontend/DeclXML.def
@@ -349,7 +349,7 @@
   ID_ATTRIBUTE_XML
   ATTRIBUTE_FILE_LOCATION_XML
   ATTRIBUTE_XML(getDeclContext(), "context")
-  ATTRIBUTE_XML(getTargetNestedNameDecl(), "target_nested_namespace_decl")
+  ATTRIBUTE_XML(getQualifier(), "target_nested_namespace_decl")
   ATTRIBUTE_XML(isTypeName(), "is_typename")
 END_NODE_XML
 
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 94b65cc..424e78c 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -1133,6 +1133,10 @@
   NestedNameSpecifier *ReadNestedNameSpecifier(const RecordData &Record,
                                                unsigned &Idx);
 
+  NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(PerFileData &F, 
+                                                    const RecordData &Record,
+                                                    unsigned &Idx);
+
   /// \brief Read a template name.
   TemplateName ReadTemplateName(PerFileData &F, const RecordData &Record, 
                                 unsigned &Idx);
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index beb4936..04ad93f 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -443,6 +443,9 @@
   /// \brief Emits a reference to a declarator info.
   void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record);
 
+  /// \brief Emits a type with source-location information.
+  void AddTypeLoc(TypeLoc TL, RecordDataImpl &Record);
+
   /// \brief Emits a template argument location info.
   void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
                                   const TemplateArgumentLocInfo &Arg,
@@ -474,6 +477,10 @@
 
   /// \brief Emit a nested name specifier.
   void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record);
+
+  /// \brief Emit a nested name specifier with source-location information.
+  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, 
+                                 RecordDataImpl &Record);
   
   /// \brief Emit a template name.
   void AddTemplateName(TemplateName Name, RecordDataImpl &Record);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c0300c5..ccc883e 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -868,9 +868,13 @@
     return cast<UsingShadowDecl>(this)->getTargetDecl() ==
            cast<UsingShadowDecl>(OldD)->getTargetDecl();
 
-  if (isa<UsingDecl>(this) && isa<UsingDecl>(OldD))
-    return cast<UsingDecl>(this)->getTargetNestedNameDecl() ==
-           cast<UsingDecl>(OldD)->getTargetNestedNameDecl();
+  if (isa<UsingDecl>(this) && isa<UsingDecl>(OldD)) {
+    ASTContext &Context = getASTContext();
+    return Context.getCanonicalNestedNameSpecifier(
+                                     cast<UsingDecl>(this)->getQualifier()) ==
+           Context.getCanonicalNestedNameSpecifier(
+                                        cast<UsingDecl>(OldD)->getQualifier());
+  }
 
   // For non-function declarations, if the declarations are of the
   // same kind then this must be a redeclaration, or semantic analysis
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index fba73f5..a1d6cc3 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1337,35 +1337,31 @@
   S->UsingOrNextShadow = this;
 }
 
-UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
-                             SourceRange NNR, SourceLocation UL,
-                             NestedNameSpecifier* TargetNNS,
+UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
+                             NestedNameSpecifierLoc QualifierLoc,
                              const DeclarationNameInfo &NameInfo,
                              bool IsTypeNameArg) {
-  return new (C) UsingDecl(DC, NNR, UL, TargetNNS, NameInfo, IsTypeNameArg);
+  return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, IsTypeNameArg);
 }
 
 UnresolvedUsingValueDecl *
 UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation UsingLoc,
-                                 SourceRange TargetNNR,
-                                 NestedNameSpecifier *TargetNNS,
+                                 NestedNameSpecifierLoc QualifierLoc,
                                  const DeclarationNameInfo &NameInfo) {
   return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
-                                          TargetNNR, TargetNNS, NameInfo);
+                                          QualifierLoc, NameInfo);
 }
 
 UnresolvedUsingTypenameDecl *
 UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
                                     SourceLocation UsingLoc,
                                     SourceLocation TypenameLoc,
-                                    SourceRange TargetNNR,
-                                    NestedNameSpecifier *TargetNNS,
+                                    NestedNameSpecifierLoc QualifierLoc,
                                     SourceLocation TargetNameLoc,
                                     DeclarationName TargetName) {
   return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
-                                             TargetNNR, TargetNNS,
-                                             TargetNameLoc,
+                                             QualifierLoc, TargetNameLoc,
                                              TargetName.getAsIdentifierInfo());
 }
 
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 77b4257..c6ae128 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -918,20 +918,20 @@
 
 void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
   Out << "using ";
-  D->getTargetNestedNameDecl()->print(Out, Policy);
+  D->getQualifier()->print(Out, Policy);
   Out << D;
 }
 
 void
 DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
   Out << "using typename ";
-  D->getTargetNestedNameSpecifier()->print(Out, Policy);
+  D->getQualifier()->print(Out, Policy);
   Out << D->getDeclName();
 }
 
 void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
   Out << "using ";
-  D->getTargetNestedNameSpecifier()->print(Out, Policy);
+  D->getQualifier()->print(Out, Policy);
   Out << D->getDeclName();
 }
 
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index da12aa7..0689ae1 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -320,7 +320,7 @@
   }
 }
 
-SourceRange NestedNameSpecifierLoc::getSourceRange() {
+SourceRange NestedNameSpecifierLoc::getSourceRange() const {
   NestedNameSpecifierLoc First = *this;
   while (NestedNameSpecifierLoc Prefix= First.getPrefix())
     First = Prefix;
@@ -329,7 +329,7 @@
                      getLocalSourceRange().getEnd());
 }
 
-SourceRange NestedNameSpecifierLoc::getLocalSourceRange() {
+SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
   unsigned Offset = getDataLength(Qualifier->getPrefix());
   switch (Qualifier->getKind()) {
   case NestedNameSpecifier::Global:
@@ -354,3 +354,14 @@
   
   return SourceRange();
 }
+
+TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
+  assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
+          Qualifier->getKind() == NestedNameSpecifier::TypeSpecWithTemplate) &&
+         "Nested-name-specifier location is not a type");
+
+  // The "void*" that points at the TypeLoc data.
+  unsigned Offset = getDataLength(Qualifier->getPrefix());
+  void *TypeData = LoadPointer(Data, Offset);
+  return TypeLoc(Qualifier->getAsType(), TypeData);
+}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 846bd4c..5c7dbb3 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -279,8 +279,8 @@
     // print using decl (e.g. "using std::string;")
     const char *tn = UD->isTypeName() ? "typename " : "";
     OS << '"' << UD->getDeclKindName() << tn;
-    UD->getTargetNestedNameDecl()->print(OS,
-        PrintingPolicy(UD->getASTContext().getLangOptions()));
+    UD->getQualifier()->print(OS,
+                        PrintingPolicy(UD->getASTContext().getLangOptions()));
     OS << ";\"";
   } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
     OS << "label " << LD->getNameAsString();
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8e1792b..89b2263 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3919,16 +3919,16 @@
       if (OrigDC == CurContext) {
         Diag(Using->getLocation(),
              diag::err_using_decl_nested_name_specifier_is_current_class)
-          << Using->getNestedNameRange();
+          << Using->getQualifierLoc().getSourceRange();
         Diag(Orig->getLocation(), diag::note_using_decl_target);
         return true;
       }
 
-      Diag(Using->getNestedNameRange().getBegin(),
+      Diag(Using->getQualifierLoc().getBeginLoc(),
            diag::err_using_decl_nested_name_specifier_is_not_base_class)
-        << Using->getTargetNestedNameDecl()
+        << Using->getQualifier()
         << cast<CXXRecordDecl>(CurContext)
-        << Using->getNestedNameRange();
+        << Using->getQualifierLoc().getSourceRange();
       Diag(Orig->getLocation(), diag::note_using_decl_target);
       return true;
     }
@@ -4134,8 +4134,6 @@
     LookupQualifiedName(Previous, CurContext);
   }
 
-  NestedNameSpecifier *NNS = SS.getScopeRep();
-
   // Check for invalid redeclarations.
   if (CheckUsingDeclRedeclaration(UsingLoc, IsTypeName, SS, IdentLoc, Previous))
     return 0;
@@ -4146,22 +4144,21 @@
 
   DeclContext *LookupContext = computeDeclContext(SS);
   NamedDecl *D;
+  NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
   if (!LookupContext) {
     if (IsTypeName) {
       // FIXME: not all declaration name kinds are legal here
       D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
                                               UsingLoc, TypenameLoc,
-                                              SS.getRange(), NNS,
+                                              QualifierLoc,
                                               IdentLoc, NameInfo.getName());
     } else {
-      D = UnresolvedUsingValueDecl::Create(Context, CurContext,
-                                           UsingLoc, SS.getRange(),
-                                           NNS, NameInfo);
+      D = UnresolvedUsingValueDecl::Create(Context, CurContext, UsingLoc, 
+                                           QualifierLoc, NameInfo);
     }
   } else {
-    D = UsingDecl::Create(Context, CurContext,
-                          SS.getRange(), UsingLoc, NNS, NameInfo,
-                          IsTypeName);
+    D = UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc,
+                          NameInfo, IsTypeName);
   }
   D->setAccess(AS);
   CurContext->addDecl(D);
@@ -4252,7 +4249,7 @@
     return true;
   }
 
-  const Type *SourceType = UD->getTargetNestedNameDecl()->getAsType();
+  const Type *SourceType = UD->getQualifier()->getAsType();
   assert(SourceType &&
          "Using decl naming constructor doesn't have type in scope spec.");
   CXXRecordDecl *TargetClass = cast<CXXRecordDecl>(CurContext);
@@ -4309,15 +4306,15 @@
     NestedNameSpecifier *DQual;
     if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
       DTypename = UD->isTypeName();
-      DQual = UD->getTargetNestedNameDecl();
+      DQual = UD->getQualifier();
     } else if (UnresolvedUsingValueDecl *UD
                  = dyn_cast<UnresolvedUsingValueDecl>(D)) {
       DTypename = false;
-      DQual = UD->getTargetNestedNameSpecifier();
+      DQual = UD->getQualifier();
     } else if (UnresolvedUsingTypenameDecl *UD
                  = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
       DTypename = true;
-      DQual = UD->getTargetNestedNameSpecifier();
+      DQual = UD->getQualifier();
     } else continue;
 
     // using decls differ if one says 'typename' and the other doesn't.
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 474a18d..8f7b7da 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -6036,7 +6036,7 @@
       << Name << Ctx << FullRange;
     if (UnresolvedUsingValueDecl *Using
           = dyn_cast<UnresolvedUsingValueDecl>(Result.getRepresentativeDecl())){
-      SourceLocation Loc = Using->getTargetNestedNameRange().getBegin();
+      SourceLocation Loc = Using->getQualifierLoc().getBeginLoc();
       Diag(Loc, diag::note_using_value_decl_missing_typename)
         << FixItHint::CreateInsertion(Loc, "typename ");
     }
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index de4cd46..e1a7065 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1661,12 +1661,12 @@
   //     template struct t<int>;
   // Here, in using s1::f1, s1 refers to t<T>::s1;
   // we need to substitute for t<int>::s1.
-  NestedNameSpecifier *NNS =
-      SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameDecl(),
-      D->getNestedNameRange(),
-      TemplateArgs);
+  NestedNameSpecifier *NNS 
+    = SemaRef.SubstNestedNameSpecifier(D->getQualifier(), 
+                                       D->getQualifierRange(),
+                                       TemplateArgs);
   if (!NNS)
-      return 0;
+    return 0;
 
   // The name info is non-dependent, so no transformation
   // is required.
@@ -1680,16 +1680,18 @@
   LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
                     Sema::ForRedeclaration);
 
+  CXXScopeSpec SS;
+  if (NNS == D->getQualifier())
+    SS.Adopt(D->getQualifierLoc());
+  else
+    SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
+
   UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
-                                       D->getNestedNameRange(),
                                        D->getUsingLocation(),
-                                       NNS,
+                                       SS.getWithLocInContext(SemaRef.Context),
                                        NameInfo,
                                        D->isTypeName());
 
-  CXXScopeSpec SS;
-  SS.MakeTrivial(SemaRef.Context, NNS, D->getNestedNameRange());
-
   if (CheckRedeclaration) {
     Prev.setHideTags(false);
     SemaRef.LookupQualifiedName(Prev, Owner);
@@ -1749,14 +1751,13 @@
 Decl * TemplateDeclInstantiator
     ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
   NestedNameSpecifier *NNS =
-    SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
-                                     D->getTargetNestedNameRange(),
+    SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(),
                                      TemplateArgs);
   if (!NNS)
     return 0;
 
   CXXScopeSpec SS;
-  SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
+  SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
 
   // Since NameInfo refers to a typename, it cannot be a C++ special name.
   // Hence, no tranformation is required for it.
@@ -1775,14 +1776,13 @@
 Decl * TemplateDeclInstantiator
     ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
   NestedNameSpecifier *NNS =
-    SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
-                                     D->getTargetNestedNameRange(),
+    SemaRef.SubstNestedNameSpecifier(D->getQualifier(), D->getQualifierRange(),
                                      TemplateArgs);
   if (!NNS)
     return 0;
 
   CXXScopeSpec SS;
-  SS.MakeTrivial(SemaRef.Context, NNS, D->getTargetNestedNameRange());
+  SS.MakeTrivial(SemaRef.Context, NNS, D->getQualifierRange());
 
   DeclarationNameInfo NameInfo
     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 6f8856c..93e3606 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4759,6 +4759,109 @@
   return NNS;
 }
 
+NestedNameSpecifierLoc
+ASTReader::ReadNestedNameSpecifierLoc(PerFileData &F, const RecordData &Record, 
+                                      unsigned &Idx) {
+  unsigned N = Record[Idx++];
+  NestedNameSpecifier *NNS = 0, *Prev = 0;
+  llvm::SmallVector<char, 32> LocationData;
+  for (unsigned I = 0; I != N; ++I) {
+    NestedNameSpecifier::SpecifierKind Kind
+      = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
+    switch (Kind) {
+    case NestedNameSpecifier::Identifier: {
+      // Nested-name-specifier
+      IdentifierInfo *II = GetIdentifierInfo(Record, Idx);
+      NNS = NestedNameSpecifier::Create(*Context, Prev, II);
+      
+      // Location information
+      SourceRange Range = ReadSourceRange(F, Record, Idx);
+      unsigned RawStart = Range.getBegin().getRawEncoding();
+      unsigned RawEnd = Range.getEnd().getRawEncoding();
+      LocationData.append(reinterpret_cast<char*>(&RawStart),
+                          reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
+      LocationData.append(reinterpret_cast<char*>(&RawEnd),
+                          reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+      break;
+    }
+
+    case NestedNameSpecifier::Namespace: {
+      // Nested-name-specifier
+      NamespaceDecl *NS = cast<NamespaceDecl>(GetDecl(Record[Idx++]));
+      NNS = NestedNameSpecifier::Create(*Context, Prev, NS);
+
+      // Location information
+      SourceRange Range = ReadSourceRange(F, Record, Idx);
+      unsigned RawStart = Range.getBegin().getRawEncoding();
+      unsigned RawEnd = Range.getEnd().getRawEncoding();
+      LocationData.append(reinterpret_cast<char*>(&RawStart),
+                          reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
+      LocationData.append(reinterpret_cast<char*>(&RawEnd),
+                          reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+      break;
+    }
+
+    case NestedNameSpecifier::NamespaceAlias: {
+      // Nested-name-specifier
+      NamespaceAliasDecl *Alias
+        = cast<NamespaceAliasDecl>(GetDecl(Record[Idx++]));
+      NNS = NestedNameSpecifier::Create(*Context, Prev, Alias);
+      
+      // Location information
+      SourceRange Range = ReadSourceRange(F, Record, Idx);
+      unsigned RawStart = Range.getBegin().getRawEncoding();
+      unsigned RawEnd = Range.getEnd().getRawEncoding();
+      LocationData.append(reinterpret_cast<char*>(&RawStart),
+                          reinterpret_cast<char*>(&RawStart) +sizeof(unsigned));
+      LocationData.append(reinterpret_cast<char*>(&RawEnd),
+                          reinterpret_cast<char*>(&RawEnd) + sizeof(unsigned));
+
+      break;
+    }
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate: {
+      // Nested-name-specifier
+      bool Template = Record[Idx++];
+      TypeSourceInfo *T = GetTypeSourceInfo(F, Record, Idx);
+      if (!T)
+        return NestedNameSpecifierLoc();
+      NNS = NestedNameSpecifier::Create(*Context, Prev, Template, 
+                                        T->getType().getTypePtr());
+
+      // Location information.
+      SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
+      unsigned RawLocation = ColonColonLoc.getRawEncoding();
+      void *OpaqueTypeData = T->getTypeLoc().getOpaqueData();
+      LocationData.append(reinterpret_cast<char*>(&OpaqueTypeData),
+                          (reinterpret_cast<char*>(&OpaqueTypeData) 
+                             + sizeof(void *)));
+      LocationData.append(reinterpret_cast<char*>(&RawLocation),
+                          (reinterpret_cast<char*>(&RawLocation) +
+                             sizeof(unsigned)));
+      break;
+    }
+
+    case NestedNameSpecifier::Global: {
+      // Nested-name-specifier
+      NNS = NestedNameSpecifier::GlobalSpecifier(*Context);
+
+      SourceLocation ColonColonLoc = ReadSourceLocation(F, Record, Idx);
+      unsigned RawLocation = ColonColonLoc.getRawEncoding();
+      LocationData.append(reinterpret_cast<char*>(&RawLocation),
+                          (reinterpret_cast<char*>(&RawLocation) +
+                             sizeof(unsigned)));
+      break;
+    }
+    }
+    Prev = NNS;
+  }
+  
+  void *Mem = Context->Allocate(LocationData.size(), llvm::alignOf<void*>());
+  memcpy(Mem, LocationData.data(), LocationData.size());
+  return NestedNameSpecifierLoc(NNS, Mem);
+}
+
 SourceRange
 ASTReader::ReadSourceRange(PerFileData &F, const RecordData &Record,
                            unsigned &Idx) {
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index dec15dd..caa5132 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -753,8 +753,7 @@
 void ASTDeclReader::VisitUsingDecl(UsingDecl *D) {
   VisitNamedDecl(D);
   D->setUsingLocation(ReadSourceLocation(Record, Idx));
-  D->setNestedNameRange(ReadSourceRange(Record, Idx));
-  D->setTargetNestedNameDecl(Reader.ReadNestedNameSpecifier(Record, Idx));
+  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
   ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
   D->FirstUsingShadow = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]));
   D->setTypeName(Record[Idx++]);
@@ -785,19 +784,17 @@
 
 void ASTDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
   VisitValueDecl(D);
-  D->setTargetNestedNameRange(ReadSourceRange(Record, Idx));
   D->setUsingLoc(ReadSourceLocation(Record, Idx));
-  D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));
+  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
   ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx);
 }
 
 void ASTDeclReader::VisitUnresolvedUsingTypenameDecl(
                                                UnresolvedUsingTypenameDecl *D) {
   VisitTypeDecl(D);
-  D->TargetNestedNameRange = ReadSourceRange(Record, Idx);
   D->UsingLocation = ReadSourceLocation(Record, Idx);
   D->TypenameLocation = ReadSourceLocation(Record, Idx);
-  D->TargetNestedNameSpecifier = Reader.ReadNestedNameSpecifier(Record, Idx);
+  D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
 }
 
 void ASTDeclReader::ReadCXXDefinitionData(
@@ -1436,8 +1433,9 @@
                                    SourceLocation(), 0);
     break;
   case DECL_USING:
-    D = UsingDecl::Create(*Context, 0, SourceRange(), SourceLocation(),
-                          0, DeclarationNameInfo(), false);
+    D = UsingDecl::Create(*Context, 0, SourceLocation(),
+                          NestedNameSpecifierLoc(), DeclarationNameInfo(), 
+                          false);
     break;
   case DECL_USING_SHADOW:
     D = UsingShadowDecl::Create(*Context, 0, SourceLocation(), 0, 0);
@@ -1449,13 +1447,14 @@
     break;
   case DECL_UNRESOLVED_USING_VALUE:
     D = UnresolvedUsingValueDecl::Create(*Context, 0, SourceLocation(),
-                                         SourceRange(), 0,
+                                         NestedNameSpecifierLoc(), 
                                          DeclarationNameInfo());
     break;
   case DECL_UNRESOLVED_USING_TYPENAME:
     D = UnresolvedUsingTypenameDecl::Create(*Context, 0, SourceLocation(),
-                                            SourceLocation(), SourceRange(),
-                                            0, SourceLocation(),
+                                            SourceLocation(), 
+                                            NestedNameSpecifierLoc(),
+                                            SourceLocation(),
                                             DeclarationName());
     break;
   case DECL_CXX_RECORD:
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 42ca293..ba2494b 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -3276,15 +3276,21 @@
                              Record);
 }
 
-void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record) {
+void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, 
+                                  RecordDataImpl &Record) {
   if (TInfo == 0) {
     AddTypeRef(QualType(), Record);
     return;
   }
 
-  AddTypeRef(TInfo->getType(), Record);
+  AddTypeLoc(TInfo->getTypeLoc(), Record);
+}
+
+void ASTWriter::AddTypeLoc(TypeLoc TL, RecordDataImpl &Record) {
+  AddTypeRef(TL.getType(), Record);
+
   TypeLocWriter TLW(*this, Record);
-  for (TypeLoc TL = TInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
+  for (; !TL.isNull(); TL = TL.getNextTypeLoc())
     TLW.Visit(TL);
 }
 
@@ -3487,6 +3493,55 @@
   }
 }
 
+void ASTWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
+                                          RecordDataImpl &Record) {
+  // Nested name specifiers usually aren't too long. I think that 8 would
+  // typically accomodate the vast majority.
+  llvm::SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
+
+  // Push each of the nested-name-specifiers's onto a stack for
+  // serialization in reverse order.
+  while (NNS) {
+    NestedNames.push_back(NNS);
+    NNS = NNS.getPrefix();
+  }
+
+  Record.push_back(NestedNames.size());
+  while(!NestedNames.empty()) {
+    NNS = NestedNames.pop_back_val();
+    NestedNameSpecifier::SpecifierKind Kind
+      = NNS.getNestedNameSpecifier()->getKind();
+    Record.push_back(Kind);
+    switch (Kind) {
+    case NestedNameSpecifier::Identifier:
+      AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier(), Record);
+      AddSourceRange(NNS.getLocalSourceRange(), Record);
+      break;
+
+    case NestedNameSpecifier::Namespace:
+      AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace(), Record);
+      AddSourceRange(NNS.getLocalSourceRange(), Record);
+      break;
+
+    case NestedNameSpecifier::NamespaceAlias:
+      AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(), Record);
+      AddSourceRange(NNS.getLocalSourceRange(), Record);
+      break;
+
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate:
+      Record.push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate);
+      AddTypeLoc(NNS.getTypeLoc(), Record);
+      AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
+      break;
+
+    case NestedNameSpecifier::Global:
+      AddSourceLocation(NNS.getLocalSourceRange().getEnd(), Record);
+      break;
+    }
+  }
+}
+
 void ASTWriter::AddTemplateName(TemplateName Name, RecordDataImpl &Record) {
   TemplateName::NameKind Kind = Name.getKind();
   Record.push_back(Kind);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index ce07e13..5d0514f 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -706,9 +706,8 @@
 
 void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) {
   VisitNamedDecl(D);
-  Writer.AddSourceRange(D->getNestedNameRange(), Record);
   Writer.AddSourceLocation(D->getUsingLocation(), Record);
-  Writer.AddNestedNameSpecifier(D->getTargetNestedNameDecl(), Record);
+  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
   Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
   Writer.AddDeclRef(D->FirstUsingShadow, Record);
   Record.push_back(D->isTypeName());
@@ -737,9 +736,8 @@
 
 void ASTDeclWriter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
   VisitValueDecl(D);
-  Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
   Writer.AddSourceLocation(D->getUsingLoc(), Record);
-  Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
   Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record);
   Code = serialization::DECL_UNRESOLVED_USING_VALUE;
 }
@@ -747,10 +745,9 @@
 void ASTDeclWriter::VisitUnresolvedUsingTypenameDecl(
                                                UnresolvedUsingTypenameDecl *D) {
   VisitTypeDecl(D);
-  Writer.AddSourceRange(D->getTargetNestedNameRange(), Record);
   Writer.AddSourceLocation(D->getUsingLoc(), Record);
   Writer.AddSourceLocation(D->getTypenameLoc(), Record);
-  Writer.AddNestedNameSpecifier(D->getTargetNestedNameSpecifier(), Record);
+  Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record);
   Code = serialization::DECL_UNRESOLVED_USING_TYPENAME;
 }
 
diff --git a/test/Index/annotate-nested-name-specifier.cpp b/test/Index/annotate-nested-name-specifier.cpp
new file mode 100644
index 0000000..13bcc98
--- /dev/null
+++ b/test/Index/annotate-nested-name-specifier.cpp
@@ -0,0 +1,42 @@
+namespace outer {
+  namespace inner {
+    template<typename T>
+    struct vector {
+      typedef T* iterator;
+    };
+  }
+}
+
+namespace outer_alias = outer;
+
+struct X { };
+
+using outer_alias::inner::vector;
+
+struct X_vector : outer_alias::inner::vector<X> {
+  using outer_alias::inner::vector<X>::iterator;
+};
+
+
+
+// RUN: c-index-test -test-annotate-tokens=%s:13:1:19: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
+// CHECK: Punctuation: "::" [14:18 - 14:20] UsingDeclaration=vector[4:12]
+// CHECK: Identifier: "inner" [14:20 - 14:25] NamespaceRef=inner:2:13
+// CHECK: Punctuation: "::" [14:25 - 14:27] UsingDeclaration=vector[4:12]
+// CHECK: Identifier: "vector" [14:27 - 14:33] OverloadedDeclRef=vector[4:12]
+// CHECK: Punctuation: ";" [14:33 - 14:34]
+// FIXME: Base specifiers, too
+// CHECK: Keyword: "using" [17:3 - 17:8] UsingDeclaration=iterator[5:18]
+// CHECK: Identifier: "outer_alias" [17:9 - 17:20] NamespaceRef=outer_alias:10:11
+// CHECK: Punctuation: "::" [17:20 - 17:22] UsingDeclaration=iterator[5:18]
+// CHECK: Identifier: "inner" [17:22 - 17:27] NamespaceRef=inner:2:13
+// CHECK: Punctuation: "::" [17:27 - 17:29] UsingDeclaration=iterator[5:18]
+// CHECK: Identifier: "vector" [17:29 - 17:35] TemplateRef=vector:4:12
+// CHECK: Punctuation: "<" [17:35 - 17:36] UsingDeclaration=iterator[5:18]
+// CHECK: Identifier: "X" [17:36 - 17:37] TypeRef=struct X:12:8
+// 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]
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index c57a489..dfcf220 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -310,6 +310,7 @@
   // Name visitor
   bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
   bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
+  bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
   
   // Template visitors
   bool VisitTemplateParameters(const TemplateParameterList *Params);
@@ -1084,9 +1085,10 @@
 
 bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
   // Visit nested-name-specifier.
-  if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameDecl())
-    if (VisitNestedNameSpecifier(Qualifier, D->getNestedNameRange()))
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
       return true;
+  }
   
   if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
     return true;
@@ -1106,9 +1108,10 @@
 
 bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
   // Visit nested-name-specifier.
-  if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier())
-    if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange()))
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
       return true;
+  }
 
   return VisitDeclarationNameInfo(D->getNameInfo());
 }
@@ -1116,8 +1119,8 @@
 bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
                                                UnresolvedUsingTypenameDecl *D) {
   // Visit nested-name-specifier.
-  if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier())
-    if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange()))
+  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
+    if (VisitNestedNameSpecifierLoc(QualifierLoc))
       return true;
   
   return false;
@@ -1194,6 +1197,48 @@
   return false;
 }
 
+bool 
+CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
+  llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
+  for (; Qualifier; Qualifier = Qualifier.getPrefix())
+    Qualifiers.push_back(Qualifier);
+  
+  while (!Qualifiers.empty()) {
+    NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
+    NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
+    switch (NNS->getKind()) {
+    case NestedNameSpecifier::Namespace:
+      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), 
+                                       Q.getLocalSourceRange().getBegin(),
+                                       TU)))
+        return true;
+        
+      break;
+      
+    case NestedNameSpecifier::NamespaceAlias:
+      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 
+                                       Q.getLocalSourceRange().getBegin(),
+                                       TU)))
+        return true;
+        
+      break;
+        
+    case NestedNameSpecifier::TypeSpec:
+    case NestedNameSpecifier::TypeSpecWithTemplate:
+      if (Visit(Q.getTypeLoc()))
+        return true;
+        
+      break;
+        
+    case NestedNameSpecifier::Global:
+    case NestedNameSpecifier::Identifier:
+      break;              
+    }
+  }
+  
+  return false;
+}
+
 bool CursorVisitor::VisitTemplateParameters(
                                           const TemplateParameterList *Params) {
   if (!Params)