Fix speculative parsing of dependent template names in
nested-name-specifiers so that they don't gobble the template name (or
operator-function-id) unless there is also a
template-argument-list. For example, given

  T::template apply

we would previously consume both "template" and "apply" as part of
parsing the nested-name-specifier, then error when we see that there
is no "<" starting a template argument list. Now, we parse such
constructs tentatively, and back off if the "<" is not present. This
allows us to parse dependent template names as one would use them for,
e.g., template template parameters:

  template<typename T, template<class> class X = T::template apply>
    struct MetaSomething;

Also, test default arguments for template template parameters.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86841 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp
index 1bdc7a8..e936640 100644
--- a/test/SemaTemplate/nested-name-spec-template.cpp
+++ b/test/SemaTemplate/nested-name-spec-template.cpp
@@ -28,11 +28,8 @@
 ::N::M::Promote<int>::type *ret_intptr6(int* ip) { return ip; }
 
 
-N::M::template; // expected-error{{expected template name after 'template' keyword in nested name specifier}} \
-               // expected-error{{expected unqualified-id}}
-
-N::M::template Promote; // expected-error{{expected '<' after 'template Promote' in nested name specifier}} \
-// expected-error{{C++ requires a type specifier for all declarations}}
+N::M::template; // expected-error{{expected unqualified-id}}
+N::M::template Promote; // expected-error{{expected unqualified-id}}
 
 namespace N {
   template<typename T> struct A;
@@ -49,13 +46,9 @@
   int foo;
 };
 
-#if 0
-// FIXME: the following crashes the parser, because Sema has no way to
-// communicate that the "dependent" template-name N::template B doesn't
-// actually refer to a template.
 template<typename T>
 struct TestA {
-  typedef typename N::template B<T>::type type; // xpected-error{{'B' following the 'template' keyword does not refer to a template}}
-  // FIXME: should show what B *does* refer to.
+  typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \
+                                                // expected-error{{identifier or template-id}} \
+                                                // expected-error{{expected member name}}
 };
-#endif