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