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/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();