Printing for using directives, e.g.,

  using namespace std::debug;

Extended UsingDirectiveDecl to store the nested-name-specifier that
precedes the nominated namespace.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72614 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 19adc6d..7a5233a 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -878,6 +878,14 @@
   /// SourceLocation - Location of 'namespace' token.
   SourceLocation NamespaceLoc;
 
+  /// \brief The source range that covers the nested-name-specifier
+  /// preceding the namespace name.
+  SourceRange QualifierRange;
+
+  /// \brief The nested-name-specifier that precedes the namespace
+  /// name, if any.
+  NestedNameSpecifier *Qualifier;
+
   /// IdentLoc - Location of nominated namespace-name identifier.
   // FIXME: We don't store location of scope specifier.
   SourceLocation IdentLoc;
@@ -898,16 +906,27 @@
 
   UsingDirectiveDecl(DeclContext *DC, SourceLocation L,
                      SourceLocation NamespcLoc,
+                     SourceRange QualifierRange,
+                     NestedNameSpecifier *Qualifier,
                      SourceLocation IdentLoc,
                      NamespaceDecl *Nominated,
                      DeclContext *CommonAncestor)
     : NamedDecl(Decl::UsingDirective, DC, L, getName()),
-      NamespaceLoc(NamespcLoc), IdentLoc(IdentLoc),
+      NamespaceLoc(NamespcLoc), QualifierRange(QualifierRange), 
+      Qualifier(Qualifier), IdentLoc(IdentLoc), 
       NominatedNamespace(Nominated? Nominated->getOriginalNamespace() : 0),
       CommonAncestor(CommonAncestor) {
   }
 
 public:
+  /// \brief Retrieve the source range of the nested-name-specifier
+  /// that qualifiers the namespace name.
+  SourceRange getQualifierRange() const { return QualifierRange; }
+
+  /// \brief Retrieve the nested-name-specifier that qualifies the
+  /// name of the namespace.
+  NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
   /// getNominatedNamespace - Returns namespace nominated by using-directive.
   NamespaceDecl *getNominatedNamespace() { return NominatedNamespace; }
 
@@ -929,6 +948,8 @@
   static UsingDirectiveDecl *Create(ASTContext &C, DeclContext *DC,
                                     SourceLocation L,
                                     SourceLocation NamespaceLoc,
+                                    SourceRange QualifierRange,
+                                    NestedNameSpecifier *Qualifier,
                                     SourceLocation IdentLoc,
                                     NamespaceDecl *Nominated,
                                     DeclContext *CommonAncestor);
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 5b806fa..5fb2a01 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -402,11 +402,13 @@
 UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
                                                SourceLocation L,
                                                SourceLocation NamespaceLoc,
+                                               SourceRange QualifierRange,
+                                               NestedNameSpecifier *Qualifier,
                                                SourceLocation IdentLoc,
                                                NamespaceDecl *Used,
                                                DeclContext *CommonAncestor) {
-  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, IdentLoc,
-                                    Used, CommonAncestor);
+  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, 
+                                    Qualifier, IdentLoc, Used, CommonAncestor);
 }
 
 NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, 
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 6412f75..bfd3dca 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -51,12 +51,15 @@
     void VisitFieldDecl(FieldDecl *D);
     void VisitVarDecl(VarDecl *D);
     void VisitParmVarDecl(ParmVarDecl *D);
+    void VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
     void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
+    void VisitOverloadedFunctionDecl(OverloadedFunctionDecl *D);
+    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
     void VisitNamespaceDecl(NamespaceDecl *D);
     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
     void VisitTemplateDecl(TemplateDecl *D);
-    void VisitObjCClassDecl(ObjCClassDecl *D);
     void VisitObjCMethodDecl(ObjCMethodDecl *D);
+    void VisitObjCClassDecl(ObjCClassDecl *D);
     void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
     void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
@@ -402,6 +405,10 @@
   VisitVarDecl(D);
 }
 
+void DeclPrinter::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
+  VisitVarDecl(D);
+}
+
 void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
   Out << "__asm (";
   D->getAsmString()->printPretty(Out, Context, 0, Policy, Indentation);
@@ -411,6 +418,18 @@
 //----------------------------------------------------------------------------
 // C++ declarations
 //----------------------------------------------------------------------------
+void DeclPrinter::VisitOverloadedFunctionDecl(OverloadedFunctionDecl *D) {
+  assert(false && 
+         "OverloadedFunctionDecls aren't really decls and are never printed");
+}
+
+void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+  Out << "using namespace ";
+  if (D->getQualifier())
+    D->getQualifier()->print(Out, Policy);
+  Out << D->getNominatedNamespace()->getNameAsString();
+}
+
 void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
   Out << "namespace " << D->getNameAsString() << " {\n";
   VisitDeclContext(D);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 0bf97f5..cd722fe 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1711,8 +1711,12 @@
     while (CommonAncestor && !CommonAncestor->Encloses(CurContext))
       CommonAncestor = CommonAncestor->getParent();
 
-    UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc,
-                                      NamespcLoc, IdentLoc,
+    UDir = UsingDirectiveDecl::Create(Context, 
+                                      CurContext, UsingLoc,
+                                      NamespcLoc, 
+                                      SS.getRange(),
+                                      (NestedNameSpecifier *)SS.getScopeRep(),
+                                      IdentLoc,
                                       cast<NamespaceDecl>(NS),
                                       CommonAncestor);
     PushUsingDirective(S, UDir);
diff --git a/test/Coverage/ast-printing.cpp b/test/Coverage/ast-printing.cpp
new file mode 100644
index 0000000..10d01c7
--- /dev/null
+++ b/test/Coverage/ast-printing.cpp
@@ -0,0 +1,6 @@
+// RUN: clang-cc --fsyntax-only %s &&
+// RUN: clang-cc --ast-print %s &&
+// RUN: clang-cc --ast-dump %s
+// FIXME: clang-cc --ast-print-xml -o %t %s
+
+#include "cxx-language-features.inc"
diff --git a/test/Coverage/c-language-features.inc b/test/Coverage/c-language-features.inc
index 5258040..bcf4127 100644
--- a/test/Coverage/c-language-features.inc
+++ b/test/Coverage/c-language-features.inc
@@ -140,6 +140,7 @@
   int t32 = __real (t32_cond ? t32_a : t32_b);
 
   struct { int x, y; } t33, *t34, t35[12], t36(int, float);
+  float t37, *t38, t39[9], t40(double);
 }
 
 // Extended vectors
diff --git a/test/Coverage/cxx-language-features.inc b/test/Coverage/cxx-language-features.inc
new file mode 100644
index 0000000..92c9fd6
--- /dev/null
+++ b/test/Coverage/cxx-language-features.inc
@@ -0,0 +1,12 @@
+//-*- C++ -*-
+
+// Intended to exercise all syntactic parts of the C++ language that
+// aren't part of C.
+
+namespace std {
+  namespace debug {
+  }
+}
+
+using namespace std::debug;
+using namespace std;