165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali// RUN: %clang_cc1 -std=c++1y -verify %s
265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali// RUN: %clang_cc1 -std=c++1y -verify %s -fdelayed-template-parsing
365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valinamespace nested_local_templates_1 {
565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valitemplate <class T> struct Outer {
765efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  template <class U> int outer_mem(T t, U u) {
865efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    struct Inner {
965efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      template <class V> int inner_mem(T t, U u, V v) {
1065efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        struct InnerInner {
1165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali          template <class W> int inner_inner_mem(W w, T t, U u, V v) {
1265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali            return 0;
1365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali          }
1465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        };
1565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        InnerInner().inner_inner_mem("abc", t, u, v);
1665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        return 0;
1765efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      }
1865efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    };
1965efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    Inner i;
2065efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    i.inner_mem(t, u, 3.14);
2165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    return 0;
2265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  }
2365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
2465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  template <class U> int outer_mem(T t, U *u);
2565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali};
2665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
2765efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valitemplate int Outer<int>::outer_mem(int, char);
2865efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
2965efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valitemplate <class T> template <class U> int Outer<T>::outer_mem(T t, U *u) {
3065efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  struct Inner {
3165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    template <class V>
3265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    int inner_mem(T t, U u, V v) { //expected-note{{candidate function}}
3365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      struct InnerInner {
3465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        template <class W> int inner_inner_mem(W w, T t, U u, V v) { return 0; }
3565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      };
3665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      InnerInner().inner_inner_mem("abc", t, u, v);
3765efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      return 0;
3865efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    }
3965efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  };
4065efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  Inner i;
4165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  i.inner_mem(t, U{}, i);
4265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  i.inner_mem(t, u, 3.14); //expected-error{{no matching member function for call to 'inner}}
4365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  return 0;
4465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali}
4565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
4665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valitemplate int Outer<int>::outer_mem(int, char *); //expected-note{{in instantiation of function}}
4765efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
4865efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali} // end ns
4965efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
5065efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valinamespace nested_local_templates_2 {
5165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
5265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valitemplate <class T> struct Outer {
5365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  template <class U> void outer_mem(T t, U u) {
5465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    struct Inner {
5565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      template <class V> struct InnerTemplateClass {
5665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        template <class W>
5765efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        void itc_mem(T t, U u, V v, W w) { //expected-note{{candidate function}}
5865efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali          struct InnerInnerInner {
5965efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali            template <class X> void iii_mem(X x) {}
6065efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali          };
6165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali          InnerInnerInner i;
6265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali          i.iii_mem("abc");
6365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali        }
6465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali      };
6565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    };
6665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    Inner i;
6765efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    typename Inner::template InnerTemplateClass<Inner> ii;
6865efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    ii.itc_mem(t, u, i, "jim");
6965efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali    ii.itc_mem(t, u, 0, "abd"); //expected-error{{no matching member function}}
7065efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali  }
7165efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali};
7265efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
7365efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Valitemplate void
7465efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal ValiOuter<int>::outer_mem(int, char); //expected-note{{in instantiation of}}
7565efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali
7665efd10a5f54e4ffa23996d3779fd9318f01c4b7Faisal Vali}
77688f9866c7d35725c947b080fb17055446912390Faisal Vali
78688f9866c7d35725c947b080fb17055446912390Faisal Valinamespace more_nested_local_templates {
79688f9866c7d35725c947b080fb17055446912390Faisal Vali
80688f9866c7d35725c947b080fb17055446912390Faisal Valiint test() {
81688f9866c7d35725c947b080fb17055446912390Faisal Vali  struct Local {
82688f9866c7d35725c947b080fb17055446912390Faisal Vali    template<class U> void foo(U u) {
83688f9866c7d35725c947b080fb17055446912390Faisal Vali      struct Inner {
84688f9866c7d35725c947b080fb17055446912390Faisal Vali        template<class A>
85688f9866c7d35725c947b080fb17055446912390Faisal Vali        auto operator()(A a, U u2) -> U {
86688f9866c7d35725c947b080fb17055446912390Faisal Vali          return u2;
87688f9866c7d35725c947b080fb17055446912390Faisal Vali        };
88688f9866c7d35725c947b080fb17055446912390Faisal Vali      };
89688f9866c7d35725c947b080fb17055446912390Faisal Vali      Inner GL;
90688f9866c7d35725c947b080fb17055446912390Faisal Vali      GL('a', u );
91688f9866c7d35725c947b080fb17055446912390Faisal Vali      GL(3.14, u );
92688f9866c7d35725c947b080fb17055446912390Faisal Vali    }
93688f9866c7d35725c947b080fb17055446912390Faisal Vali  };
94688f9866c7d35725c947b080fb17055446912390Faisal Vali  Local l;
95688f9866c7d35725c947b080fb17055446912390Faisal Vali  l.foo("nmabc");
96688f9866c7d35725c947b080fb17055446912390Faisal Vali  return 0;
97688f9866c7d35725c947b080fb17055446912390Faisal Vali}
98688f9866c7d35725c947b080fb17055446912390Faisal Valiint t = test();
99688f9866c7d35725c947b080fb17055446912390Faisal Vali}