Let using directives refer to namespace aliases. Fixes PR5479.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89657 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 94621aa..4001988 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -886,12 +886,21 @@
                                                SourceRange QualifierRange,
                                                NestedNameSpecifier *Qualifier,
                                                SourceLocation IdentLoc,
-                                               NamespaceDecl *Used,
+                                               NamedDecl *Used,
                                                DeclContext *CommonAncestor) {
+  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
+    Used = NS->getOriginalNamespace();
   return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange,
                                     Qualifier, IdentLoc, Used, CommonAncestor);
 }
 
+NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
+  if (NamespaceAliasDecl *NA =
+        dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
+    return NA->getNamespace();
+  return cast_or_null<NamespaceDecl>(NominatedNamespace);
+}
+
 NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
                                                SourceLocation L,
                                                SourceLocation AliasLoc,
@@ -900,6 +909,8 @@
                                                NestedNameSpecifier *Qualifier,
                                                SourceLocation IdentLoc,
                                                NamedDecl *Namespace) {
+  if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
+    Namespace = NS->getOriginalNamespace();
   return new (C) NamespaceAliasDecl(DC, L, AliasLoc, Alias, QualifierRange,
                                     Qualifier, IdentLoc, Namespace);
 }
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 864f114..24d3da4 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -505,7 +505,7 @@
   Out << "using namespace ";
   if (D->getQualifier())
     D->getQualifier()->print(Out, Policy);
-  Out << D->getNominatedNamespace()->getNameAsString();
+  Out << D->getNominatedNamespaceAsWritten()->getNameAsString();
 }
 
 void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 3ff9144..58fe97a 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2722,6 +2722,14 @@
   return DeclPtrTy::make(Namespc);
 }
 
+/// getNamespaceDecl - Returns the namespace a decl represents. If the decl
+/// is a namespace alias, returns the namespace it points to.
+static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) {
+  if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D))
+    return AD->getNamespace();
+  return dyn_cast_or_null<NamespaceDecl>(D);
+}
+
 /// ActOnFinishNamespaceDef - This callback is called after a namespace is
 /// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef.
 void Sema::ActOnFinishNamespaceDef(DeclPtrTy D, SourceLocation RBrace) {
@@ -2753,9 +2761,9 @@
     return DeclPtrTy();
 
   if (!R.empty()) {
-    NamedDecl *NS = R.getFoundDecl();
-    // FIXME: Namespace aliases!
-    assert(isa<NamespaceDecl>(NS) && "expected namespace decl");
+    NamedDecl *Named = R.getFoundDecl();
+    assert((isa<NamespaceDecl>(Named) || isa<NamespaceAliasDecl>(Named))
+        && "expected namespace decl");
     // C++ [namespace.udir]p1:
     //   A using-directive specifies that the names in the nominated
     //   namespace can be used in the scope in which the
@@ -2768,18 +2776,15 @@
 
     // Find enclosing context containing both using-directive and
     // nominated namespace.
+    NamespaceDecl *NS = getNamespaceDecl(Named);
     DeclContext *CommonAncestor = cast<DeclContext>(NS);
     while (CommonAncestor && !CommonAncestor->Encloses(CurContext))
       CommonAncestor = CommonAncestor->getParent();
 
-    UDir = UsingDirectiveDecl::Create(Context,
-                                      CurContext, UsingLoc,
-                                      NamespcLoc,
+    UDir = UsingDirectiveDecl::Create(Context, CurContext, UsingLoc, NamespcLoc,
                                       SS.getRange(),
                                       (NestedNameSpecifier *)SS.getScopeRep(),
-                                      IdentLoc,
-                                      cast<NamespaceDecl>(NS),
-                                      CommonAncestor);
+                                      IdentLoc, Named, CommonAncestor);
     PushUsingDirective(S, UDir);
   } else {
     Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange();
@@ -3006,14 +3011,6 @@
   return UD;
 }
 
-/// getNamespaceDecl - Returns the namespace a decl represents. If the decl
-/// is a namespace alias, returns the namespace it points to.
-static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) {
-  if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D))
-    return AD->getNamespace();
-  return dyn_cast_or_null<NamespaceDecl>(D);
-}
-
 Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
                                              SourceLocation NamespaceLoc,
                                              SourceLocation AliasLoc,