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
diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp
index 33677aa..fc3f9fe 100644
--- a/test/SemaTemplate/default-arguments.cpp
+++ b/test/SemaTemplate/default-arguments.cpp
@@ -42,3 +42,54 @@
 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];