Make parsing a semantic analysis a little more robust following Sema
failures that involve malformed types, e.g., "typename X::foo" where
"foo" isn't a type, or "std::vector<void>" that doens't instantiate
properly.

Similarly, be a bit smarter in our handling of ambiguities that occur
in Sema::getTypeName, to eliminate duplicate error messages about
ambiguous name lookup.

This eliminates two XFAILs in test/SemaCXX, one of which was crying
out to us, trying to tell us that we were producing repeated error
messages.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68251 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/member-name-lookup.cpp b/test/SemaCXX/member-name-lookup.cpp
index 871bc99..9fcd922 100644
--- a/test/SemaCXX/member-name-lookup.cpp
+++ b/test/SemaCXX/member-name-lookup.cpp
@@ -1,36 +1,33 @@
 // RUN: clang-cc -fsyntax-only -verify %s
-// XFAIL
-// fails due to exact diagnostic matching
-
 struct A { 
-  int a;  // expected-note{{member found by ambiguous name lookup}}
+  int a;  // expected-note 4{{member found by ambiguous name lookup}}
   static int b;
-  static int c; // expected-note{{member found by ambiguous name lookup}}
+  static int c; // expected-note 4{{member found by ambiguous name lookup}}
 
   enum E { enumerator };
 
   typedef int type;
 
   static void f(int);
-  void f(float); // expected-note{{member found by ambiguous name lookup}}
+  void f(float); // expected-note 2{{member found by ambiguous name lookup}}
 
   static void static_f(int);
   static void static_f(double);
 };
 
 struct B : A {
-  int d; // expected-note{{member found by ambiguous name lookup}}
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
 
   enum E2 { enumerator2 };
 
-  enum E3 { enumerator3 }; // expected-note{{member found by ambiguous name lookup}}
+  enum E3 { enumerator3 }; // expected-note 2{{member found by ambiguous name lookup}}
 };
 
 struct C : A {
-  int c; // expected-note{{member found by ambiguous name lookup}}
-  int d; // expected-note{{member found by ambiguous name lookup}}
+  int c; // expected-note 2{{member found by ambiguous name lookup}}
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
 
-  enum E3 { enumerator3_2 }; // expected-note{{member found by ambiguous name lookup}}
+  enum E3 { enumerator3_2 }; // expected-note 2{{member found by ambiguous name lookup}}
 };
 
 struct D : B, C {
@@ -50,7 +47,7 @@
 
   D::E2 e2 = D::enumerator2; // okay
 
-  D::E3 e3; // expected-error{{member 'E3' found in multiple base classes of different types}}
+  D::E3 e3; // expected-error{{multiple base classes}}
 }
 
 void D::test_lookup() {
@@ -70,18 +67,18 @@
 }
 
 struct B2 : virtual A {
-  int d; // expected-note{{member found by ambiguous name lookup}}
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
 
   enum E2 { enumerator2 };
 
-  enum E3 { enumerator3 }; // expected-note{{member found by ambiguous name lookup}}
+  enum E3 { enumerator3 }; // expected-note 2 {{member found by ambiguous name lookup}}
 };
 
 struct C2 : virtual A {
-  int c; // expected-note{{member found by ambiguous name lookup}}
-  int d; // expected-note{{member found by ambiguous name lookup}}
+  int c; // expected-note 2{{member found by ambiguous name lookup}}
+  int d; // expected-note 2{{member found by ambiguous name lookup}}
 
-  enum E3 { enumerator3_2 }; // expected-note{{member found by ambiguous name lookup}}
+  enum E3 { enumerator3_2 }; // expected-note 2{{member found by ambiguous name lookup}}
 };
 
 struct D2 : B2, C2 { 
@@ -147,6 +144,5 @@
 };
 
 struct UsesAmbigMemberType : HasMemberType1, HasMemberType2 {
-  type t; // expected-error{{member 'type' found in multiple base classes of different types}} \
-          // expected-error{{expected ';' at end of declaration list}}
+  type t; // expected-error{{member 'type' found in multiple base classes of different types}}
 };
diff --git a/test/SemaCXX/using-directive.cpp b/test/SemaCXX/using-directive.cpp
index 767b49b..324052f 100644
--- a/test/SemaCXX/using-directive.cpp
+++ b/test/SemaCXX/using-directive.cpp
@@ -1,9 +1,7 @@
 // RUN: clang-cc -fsyntax-only -verify %s
-// XFAIL
-// fails due to exact diagnostic matching
 
 namespace A {
-  short i; // expected-note{{candidate found by name lookup is 'A::i'}}
+  short i; // expected-note 2{{candidate found by name lookup is 'A::i'}}
   namespace B {
     long i; // expected-note{{candidate found by name lookup is 'A::B::i'}}
     void f() {} // expected-note{{candidate function}}
@@ -58,7 +56,7 @@
 
 // FIXME: Do we want err_ovl_no_viable_function_in_init here?
 struct K2 k2; // expected-error{{reference to 'K2' is ambiguous}} \
-                 expected-error{{no matching constructor}}
+                 expected-error{{incomplete type}}
 
 // FIXME: This case is incorrectly diagnosed!
 //K2 k3;
@@ -66,7 +64,7 @@
 
 class X { // expected-note{{candidate found by name lookup is 'X'}}
   // FIXME: produce a suitable error message for this
-  using namespace A; // expected-error{{expected unqualified-id}}
+  using namespace A; // expected-error{{expected member name or}}
 };
 
 namespace N {
@@ -96,7 +94,8 @@
 }
 
 namespace TwoTag {
-  struct X; // expected-note{{candidate found by name lookup is 'TwoTag::X'}}
+  struct X; // expected-note{{candidate found by name lookup is 'TwoTag::X'}} \
+  // expected-note{{forward declaration}}
 }
 
 namespace FuncHidesTagAmbiguity {
@@ -105,6 +104,7 @@
   using namespace TwoTag;
 
   void test() {
-    (void)X(); // expected-error{{reference to 'X' is ambiguous}}
+    (void)X(); // expected-error{{reference to 'X' is ambiguous}} \
+      // FIXME: expected-error{{invalid use of incomplete type}}
   }
 }
diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp
index 6df2ca6..7805040 100644
--- a/test/SemaTemplate/nested-name-spec-template.cpp
+++ b/test/SemaTemplate/nested-name-spec-template.cpp
@@ -52,7 +52,7 @@
 
 #if 0
 // FIXME: the following crashes the parser, because Sema has no way to
-// community that the "dependent" template-name N::template B doesn't
+// communicate that the "dependent" template-name N::template B doesn't
 // actually refer to a template.
 template<typename T>
 struct TestA {