PR16519, PR18009: When checking a partial specialization for uses of its own
template parameters, don't look for parameters of outer templates. If a problem
is found in a default template argument, point the diagnostic at the partial
specialization (with a note pointing at the default argument) instead of
pointing it at the default argument and leaving it unclear which partial
specialization os problematic.

llvm-svn: 201031
diff --git a/clang/test/SemaTemplate/class-template-spec.cpp b/clang/test/SemaTemplate/class-template-spec.cpp
index e82537a..0292c1b 100644
--- a/clang/test/SemaTemplate/class-template-spec.cpp
+++ b/clang/test/SemaTemplate/class-template-spec.cpp
@@ -119,3 +119,61 @@
   };
 
 }
+
+namespace PR18009 {
+  template <typename T> struct A {
+    template <int N, int M> struct S;
+    template <int N> struct S<N, sizeof(T)> {};
+  };
+  A<int>::S<8, sizeof(int)> a; // ok
+
+  template <typename T> struct B {
+    template <int N, int M> struct S; // expected-note {{declared here}}
+    template <int N> struct S<N, sizeof(T) +
+        N // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
+        > {};
+  };
+  B<int>::S<8, sizeof(int) + 8> s; // expected-error {{undefined}}
+
+  template<int A> struct outer {
+    template<int B, int C> struct inner {};
+    template<int C> struct inner<A * 2, C> {};
+  };
+}
+
+namespace PR16519 {
+  template<typename T, T...N> struct integer_sequence { typedef T value_type; }; // expected-warning {{extension}}
+
+  template<typename T> struct __make_integer_sequence;
+  template<typename T, T N> using make_integer_sequence = typename __make_integer_sequence<T>::template make<N, N % 2>::type; // expected-warning {{extension}}
+
+  template<typename T, typename T::value_type ...Extra> struct __make_integer_sequence_impl; // expected-warning {{extension}}
+  template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> { // expected-warning 2{{extension}}
+    typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;
+  };
+
+  template<typename T> struct __make_integer_sequence {
+    template<T N, T Parity, typename = void> struct make;
+    template<typename Dummy> struct make<0, 0, Dummy> { typedef integer_sequence<T> type; };
+    template<typename Dummy> struct make<1, 1, Dummy> { typedef integer_sequence<T, 0> type; };
+    template<T N, typename Dummy> struct make<N, 0, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2> > {};
+    template<T N, typename Dummy> struct make<N, 1, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2>, N - 1> {};
+  };
+
+  using X = make_integer_sequence<int, 5>; // expected-warning {{extension}}
+  using X = integer_sequence<int, 0, 1, 2, 3, 4>; // expected-warning {{extension}}
+}
+
+namespace DefaultArgVsPartialSpec {
+  // Check that the diagnostic points at the partial specialization, not just at
+  // the default argument.
+  template<typename T, int N =
+      sizeof(T) // expected-note {{template parameter is used in default argument declared here}}
+  > struct X {};
+  template<typename T> struct X<T> {}; // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
+
+  template<typename T,
+      T N = 0 // expected-note {{template parameter is declared here}}
+  > struct S;
+  template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
+}