PR41111, PR5925, PR13210: Teach tentative parsing to annotate identifiers and
nested names as id-expressions, using the annot_primary_expr annotation, where
possible. This removes some redundant lookups, and also allows us to
typo-correct within tentative parsing, and to carry on disambiguating past an
identifier which we can determine will fail lookup as both a type and as a
non-type, allowing us to disambiguate more declarations (and thus offer
improved error recovery for such cases).

This also introduces to the parser the notion of a tentatively-declared name,
which is an identifier which we *might* have seen a declaration for in a
tentative parse (but only if we end up disambiguating the tokens as a
declaration). This is necessary to correctly disambiguate cases where a
variable is used within its own initializer.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162159 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Parser/cxx-casting.cpp b/test/Parser/cxx-casting.cpp
index 42ad12e..e7d05b4 100644
--- a/test/Parser/cxx-casting.cpp
+++ b/test/Parser/cxx-casting.cpp
@@ -58,9 +58,9 @@
               expected-error {{expected ']'}}
 #define LC <:
 #define C :
-  test1::A LC:B> c; // expected-error {{cannot refer to class template 'A' without a template argument list}} expected-error 2{{}} expected-note{{}}
+  test1::A LC:B> c; // expected-error {{class template test1::A requires template arguments}} expected-error 2{{}}
   (void)static_cast LC:c>(&x); // expected-error {{expected '<' after 'static_cast'}} expected-error 2{{}} expected-note{{}}
-  test1::A<:C B> d; // expected-error {{cannot refer to class template 'A' without a template argument list}} expected-error 2{{}} expected-note{{}}
+  test1::A<:C B> d; // expected-error {{class template test1::A requires template arguments}} expected-error 2{{}}
   (void)static_cast<:C c>(&x); // expected-error {{expected '<' after 'static_cast'}} expected-error 2{{}} expected-note{{}}
 
 #define LCC <::
@@ -85,8 +85,7 @@
   E< ::F>();
 
   // Make sure that parser doesn't expand '[:' to '< ::'
-  ::D[:F> A5; // expected-error {{cannot refer to class template 'D' without a template argument list}} \
+  ::D[:F> A5; // expected-error {{class template ::D requires template arguments}} \
               // expected-error {{expected expression}} \
-              // expected-error {{expected ']'}} \
-              // expected-note {{to match this '['}}
+              // expected-error {{expected unqualified-id}}
 }
diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp
index 951cd3d..30ac279 100644
--- a/test/Parser/cxx-decl.cpp
+++ b/test/Parser/cxx-decl.cpp
@@ -119,6 +119,9 @@
 
 ;
 
+// PR4111
+void f(sqrgl); // expected-error {{unknown type name 'sqrgl'}}
+
 // PR8380
 extern ""      // expected-error {{unknown linkage language}}
 test6a { ;// expected-error {{C++ requires a type specifier for all declarations}} \
diff --git a/test/Parser/cxx-template-argument.cpp b/test/Parser/cxx-template-argument.cpp
index 5479961..afe318d 100644
--- a/test/Parser/cxx-template-argument.cpp
+++ b/test/Parser/cxx-template-argument.cpp
@@ -25,3 +25,20 @@
     (void)(&t<S<int>>==p); // expected-error {{use '> >'}} expected-error {{use '> ='}}
   }
 }
+
+namespace PR5925 {
+  template <typename x>
+  class foo { // expected-note {{here}}
+  };
+  void bar(foo *X) { // expected-error {{requires template arguments}}
+  }
+}
+
+namespace PR13210 {
+  template <class T>
+  class C {}; // expected-note {{here}}
+
+  void f() {
+    new C(); // expected-error {{requires template arguments}}
+  }
+}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index 4e1abc5..b35e382 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -93,8 +93,7 @@
 }
 
 // make sure the following doesn't hit any asserts
-void f4(undef::C); // expected-error {{use of undeclared identifier 'undef'}} \
-                      expected-error {{variable has incomplete type 'void'}}
+void f4(undef::C); // expected-error {{use of undeclared identifier 'undef'}}
 
 typedef void C2::f5(int); // expected-error{{typedef declarator cannot be qualified}}
 
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 893f08a..919edca 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -116,14 +116,14 @@
 
 // Test the improved typo correction for the Parser::ParseCastExpr =>
 // Sema::ActOnIdExpression => Sema::DiagnoseEmptyLookup call path.
-class SomeNetMessage;
+class SomeNetMessage; // expected-note 2{{'SomeNetMessage'}}
 class Message {};
 void foo(Message&);
 void foo(SomeNetMessage&);
 void doit(void *data) {
   Message somenetmsg; // expected-note{{'somenetmsg' declared here}}
   foo(somenetmessage); // expected-error{{use of undeclared identifier 'somenetmessage'; did you mean 'somenetmsg'?}}
-  foo((somenetmessage)data); // expected-error{{use of undeclared identifier 'somenetmessage'; did you mean 'SomeNetMessage'?}}
+  foo((somenetmessage)data); // expected-error{{unknown type name 'somenetmessage'; did you mean 'SomeNetMessage'?}} expected-error{{incomplete type}}
 }
 
 // Test the typo-correction callback in BuildRecoveryCallExpr.
@@ -172,7 +172,7 @@
 // Sema::ActOnIdExpression by Parser::ParseCastExpression to allow type names as
 // potential corrections for template arguments.
 namespace clash {
-class ConstructExpr {}; // expected-note{{'clash::ConstructExpr' declared here}}
+class ConstructExpr {}; // expected-note 2{{'clash::ConstructExpr' declared here}}
 }
 class ClashTool {
   bool HaveConstructExpr();
@@ -180,7 +180,7 @@
 
   void test() {
     ConstructExpr *expr = // expected-error{{unknown type name 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
-        getExprAs<ConstructExpr>(); // expected-error{{use of undeclared identifier 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
+        getExprAs<ConstructExpr>(); // expected-error{{unknown type name 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
   }
 };
 
@@ -220,6 +220,8 @@
   }
 }
 
+inf f(doulbe); // expected-error{{'int'}} expected-error{{'double'}}
+
 namespace PR6325 {
 class foo { }; // expected-note{{'foo' declared here}}
 // Note that for this example (pulled from the PR), if keywords are not excluded
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
index 893e0cc..ce5972b 100644
--- a/test/SemaCXX/unknown-type-name.cpp
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -6,6 +6,8 @@
   };
 
   typedef Wibble foo;
+
+  int zeppelin; // expected-note{{declared here}}
 }
 using namespace N;
 
@@ -15,6 +17,13 @@
   foo::bar  = 4; // expected-error{{no member named 'bar' in 'N::Wibble'}}
 }
 
+int f(foo::bar); // expected-error{{no type named 'bar' in 'N::Wibble'}}
+
+int f(doulbe); // expected-error{{did you mean 'double'?}}
+
+int fun(zapotron); // expected-error{{unknown type name 'zapotron'}}
+int var(zepelin); // expected-error{{did you mean 'zeppelin'?}}
+
 template<typename T>
 struct A {
   typedef T type;
@@ -59,6 +68,20 @@
 template<typename T>
 void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
 
+int *p;
+
+// FIXME: We should assume that 'undeclared' is a type, not a parameter name
+//        here, and produce an 'unknown type name' diagnostic instead.
+int f1(undeclared, int); // expected-error{{requires a type specifier}}
+
+int f2(undeclared, 0); // expected-error{{undeclared identifier}}
+
+int f3(undeclared *p, int); // expected-error{{unknown type name 'undeclared'}}
+
+int f4(undeclared *p, 0); // expected-error{{undeclared identifier}}
+
+int *test(UnknownType *fool) { return 0; } // expected-error{{unknown type name 'UnknownType'}}
+
 template<typename T> int A<T>::n(T::value); // ok
 template<typename T>
 A<T>::type // expected-error{{missing 'typename'}}
diff --git a/test/SemaTemplate/class-template-id.cpp b/test/SemaTemplate/class-template-id.cpp
index 3b02778..b674537 100644
--- a/test/SemaTemplate/class-template-id.cpp
+++ b/test/SemaTemplate/class-template-id.cpp
@@ -40,7 +40,7 @@
 // PR5655
 template<typename T> struct Foo { }; // expected-note{{template is declared here}}
 
-void f(void) { Foo bar; } // expected-error{{without a template argument list}}
+void f(void) { Foo bar; } // expected-error{{use of class template Foo requires template arguments}}
 
 // rdar://problem/8254267
 template <typename T> class Party;
diff --git a/test/SemaTemplate/member-access-ambig.cpp b/test/SemaTemplate/member-access-ambig.cpp
index f8a01d5..5c2d761 100644
--- a/test/SemaTemplate/member-access-ambig.cpp
+++ b/test/SemaTemplate/member-access-ambig.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-comparison %s
 
 // PR8439
 class A
@@ -43,3 +43,22 @@
   };
 }
 
+namespace AddrOfMember {
+  struct A { int X; };
+  typedef int (A::*P);
+  template<typename T> struct S : T {
+    void f() {
+      P(&T::X) // expected-error {{cannot cast from type 'int *' to member pointer type 'P'}}
+          == &A::X;
+    }
+  };
+
+  void g() {
+    S<A>().f(); // ok, &T::X is 'int (A::*)', not 'int *', even though T is a base class
+  }
+
+  struct B : A { static int X; };
+  void h() {
+    S<B>().f(); // expected-note {{here}}
+  }
+}