diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-11 16:39:34 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-11 16:39:34 +0000 |
commit | 7bb87fca7d22a8a194d04188746b90f46512975f (patch) | |
tree | eb50a180a24ea30e45519b36021acd5512e3b218 /test/SemaTemplate/default-arguments.cpp | |
parent | d694485f9d6e3ea7b458df8241dfffd38f62aca8 (diff) |
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
Diffstat (limited to 'test/SemaTemplate/default-arguments.cpp')
-rw-r--r-- | test/SemaTemplate/default-arguments.cpp | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp index fc3f9fe9b9..8352afdb0d 100644 --- a/test/SemaTemplate/default-arguments.cpp +++ b/test/SemaTemplate/default-arguments.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -fsyntax-only -verify %s - template<typename T, int N = 2> struct X; // expected-note{{template is declared here}} X<int, 1> *x1; @@ -80,16 +79,31 @@ X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default X2<int>::Inner3<float>::VeryInner<> vi; X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; - template<typename T, typename U> struct is_same { static const bool value = false; }; template<typename T> struct is_same<T, T> { static const bool value = true; }; -static int array1[is_same<__typeof__(vi), +int array1[is_same<__typeof__(vi), X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1]; -static int array2[is_same<__typeof(x2_deep_nontype), - X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), +int array2[is_same<__typeof(x2_deep_nontype), + X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), sizeof(char)+sizeof(int)> >::value? 1 : -1]; + +// Template template parameter defaults +template<template<typename T> class X = X2> struct X3 { }; +int array3[is_same<X3<>, X3<X2> >::value? 1 : -1]; + +struct add_pointer { + template<typename T> + struct apply { + typedef T* type; + }; +}; + +template<typename T, template<typename> class X = T::template apply> + struct X4; +int array4[is_same<X4<add_pointer>, + X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; |