diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-08-17 19:43:40 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-08-17 19:43:40 +0000 |
commit | f9a5d5f04a86a4bd9b907f17da88c94b8cea214e (patch) | |
tree | 0bfcf06fd91dd6655689eee73a0c511e875a5285 /clang/test | |
parent | 30161dc28da6a336542cfd828f79568130795763 (diff) | |
download | bcm5719-llvm-f9a5d5f04a86a4bd9b907f17da88c94b8cea214e.tar.gz bcm5719-llvm-f9a5d5f04a86a4bd9b907f17da88c94b8cea214e.zip |
Improve diagnostic for missing comma in template parameter list.
Given 'typename T typename U', we would correctly diagnose the missing
comma, but incorrectly disambiguate the first parameter as being a
non-type parameter and complain that the 'T' is not a qualified-id.
See also gcc.gnu.org/PR86998.
llvm-svn: 340074
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CXX/temp/temp.param/p2.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/clang/test/CXX/temp/temp.param/p2.cpp b/clang/test/CXX/temp/temp.param/p2.cpp index 656bd26ff08..c70b1d354f7 100644 --- a/clang/test/CXX/temp/temp.param/p2.cpp +++ b/clang/test/CXX/temp/temp.param/p2.cpp @@ -8,14 +8,17 @@ template<class T> struct X; template<typename T> struct X; -// typename followed by aqualified-id denotes the type in a non-type +// typename followed by a qualified-id denotes the type in a non-type // parameter-declaration. template<typename T, typename T::type Value> struct Y0; template<typename T, typename X<T>::type Value> struct Y1; +template<typename T typename U> struct Y2; // expected-error{{expected ',' or '>'}} +template<typename T U> struct Y3; // expected-error{{expected a qualified name after 'typename'}} expected-error{{expected ',' or '>'}} +template<typedef T typename U> struct Y4; // expected-error{{expected template parameter}} expected-note {{did you mean to use 'typename'?}} expected-error{{expected ',' or '>'}} // A storage class shall not be specified in a template-parameter declaration. template<static int Value> struct Z; //expected-error{{invalid declaration specifier}} -template<typedef int Value> struct Z0; //expected-error{{expected template parameter}} expected-error{{expected identifier}} expected-error{{extraneous 'template<>' in declaration of struct 'Z0'}} expected-note{{did you mean to use 'typename'?}} +template<typedef int Value> struct Z0; //expected-error{{invalid declaration specifier}} template<extern inline int Value> struct Z1; //expected-error2{{invalid declaration specifier}} template<virtual int Value> struct Z2; //expected-error{{invalid declaration specifier}} template<explicit int Value> struct Z3; //expected-error{{invalid declaration specifier}} @@ -43,6 +46,6 @@ template<auto> struct Z13; // OK // Make sure that we properly disambiguate non-type template parameters that // start with 'class'. class X1 { }; -template<class X1 *xptr> struct Y2 { }; +template<class X1 *xptr> struct X2 { }; // FIXME: add the example from p2 |