Semantic analysis, ASTs, and unqualified name lookup support for C++
using directives, from Piotr Rak!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63646 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d7c5fa6..39747b6 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -42,6 +42,8 @@
       // FIXME: In the event of an ambiguous lookup, we could visit all of
       // the entities found to determine whether they are all types. This
       // might provide better diagnostics.
+    case LookupResult::AmbiguousReference:
+    // FIXME: We need source location of identifier to diagnose more correctly.
       return 0;
     case LookupResult::Found:
       IIDecl = Result.getAsDecl();
@@ -2813,7 +2815,7 @@
     SearchDC = DC;
     // Look-up name inside 'foo::'.
     PrevDecl = dyn_cast_or_null<TagDecl>(
-                     LookupQualifiedName(DC, Name, LookupTagName).getAsDecl());
+                 LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl());
 
     // A tag 'foo::bar' must already exist.
     if (PrevDecl == 0) {
@@ -2824,8 +2826,23 @@
   } else if (Name) {
     // If this is a named struct, check to see if there was a previous forward
     // declaration or definition.
-    Decl *D = LookupName(S, Name, LookupTagName);
-    PrevDecl = dyn_cast_or_null<NamedDecl>(D);
+    // FIXME: We're looking into outer scopes here, even when we
+    // shouldn't be. Doing so can result in ambiguities that we
+    // shouldn't be diagnosing.
+    LookupResult R = LookupName(S, Name, LookupTagName);
+    if (R.isAmbiguous()) {
+      DiagnoseAmbiguousLookup(R, Name, NameLoc);
+      // FIXME: This is not best way to recover from case like:
+      //
+      // struct S s;
+      //
+      // causes needless err_ovl_no_viable_function_in_init latter.
+      Name = 0;
+      PrevDecl = 0;
+      Invalid = true;
+    }
+    else
+      PrevDecl = dyn_cast_or_null<NamedDecl>(static_cast<Decl*>(R));
 
     if (!getLangOptions().CPlusPlus && TK != TK_Reference) {
       // FIXME: This makes sure that we ignore the contexts associated