aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate/default-arguments.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-09 19:17:50 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-09 19:17:50 +0000
commit0f8716b7bb25d61a82f699b3975167451f7b5a68 (patch)
tree14553c111b4a3ce70343f638e95df7fd7378d073 /test/SemaTemplate/default-arguments.cpp
parent62cf322cf16dfbe58c56daecabb9cbcbb2bf38f7 (diff)
Improve instantiation of default template arguments for nested
templates. The instantiation of these default arguments must be (and now, is) delayed until the template argument is actually used, at which point we substitute all levels of template arguments concurrently. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaTemplate/default-arguments.cpp')
-rw-r--r--test/SemaTemplate/default-arguments.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp
index 33677aab73..fc3f9fe9b9 100644
--- a/test/SemaTemplate/default-arguments.cpp
+++ b/test/SemaTemplate/default-arguments.cpp
@@ -42,3 +42,54 @@ template<>
struct B<void> {
typedef B<void*> type;
};
+
+// Nested default arguments for template parameters.
+template<typename T> struct X1 { };
+
+template<typename T>
+struct X2 {
+ template<typename U = typename X1<T>::type> // expected-error{{no type named}}
+ struct Inner1 { };
+
+ template<T Value = X1<T>::value> // expected-error{{no member named 'value'}}
+ struct NonType1 { };
+
+ template<T Value>
+ struct Inner2 { };
+
+ template<typename U>
+ struct Inner3 {
+ template<typename X = T, typename V = U>
+ struct VeryInner { };
+
+ template<T Value1 = sizeof(T), T Value2 = sizeof(U),
+ T Value3 = Value1 + Value2>
+ struct NonType2 { };
+ };
+};
+
+X2<int> x2i;
+X2<int>::Inner1<float> x2iif;
+
+X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}}
+
+X2<int>::NonType1<'a'> x2_nontype1;
+X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}}
+
+// Check multi-level substitution into template type arguments
+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),
+ 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),
+ sizeof(char)+sizeof(int)> >::value? 1 : -1];