1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s 2fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregor// PR5336 3fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregortemplate<typename FromCl> 4fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregorstruct isa_impl_cl { 5fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregor template<class ToCl> 6fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregor static void isa(const FromCl &Val) { } 7fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregor}; 8fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregor 9fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregortemplate<class X, class Y> 10fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregorvoid isa(const Y &Val) { return isa_impl_cl<Y>::template isa<X>(Val); } 11fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregor 12fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregorclass Value; 13fd2300e1ee0eab6c51862a92d3f3c72540b36b23Douglas Gregorvoid f0(const Value &Val) { isa<Value>(Val); } 148a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor 158a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor// Implicit template-ids. 168a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregortemplate<typename T> 178a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregorstruct X0 { 188a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor template<typename U> 198a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor void f1(); 208a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor 218a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor template<typename U> 228a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor void f2(U) { 238a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor f1<U>(); 248a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor } 258a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor}; 268a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor 278a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregorvoid test_X0_int(X0<int> xi, float f) { 288a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor xi.f2(f); 298a4386b3634065b96d08f94736bc1f953e385f50Douglas Gregor} 30ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor 31ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor// Not template-id expressions, but they almost look like it. 32ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregortemplate<typename F> 33ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregorstruct Y { 34ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor Y(const F&); 35ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor}; 36ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor 37ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregortemplate<int I> 38ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregorstruct X { 39ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor X(int, int); 40ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor void f() { 41ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor Y<X<I> >(X<I>(0, 0)); 42ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor Y<X<I> >(::X<I>(0, 0)); 43ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor } 44ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor}; 45ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregor 46ae4c77dc8a77ee89e5b2de8003283249e38075c3Douglas Gregortemplate struct X<3>; 470278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 480278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor// 'template' as a disambiguator. 490278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor// PR7030 500278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregorstruct Y0 { 510278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor template<typename U> 520278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor void f1(U); 530278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 540278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor template<typename U> 550278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor static void f2(U); 560278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 570278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor void f3(int); 580278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 590278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor static int f4(int); 600278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor template<typename U> 610278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor static void f4(U); 620278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 630278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor template<typename U> 640278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor void f() { 651a15dae8be2b28e02b6639aa92b832465c5be420Douglas Gregor Y0::template f1<U>(0); 661a15dae8be2b28e02b6639aa92b832465c5be420Douglas Gregor Y0::template f1(0); 670278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor this->template f1(0); 680278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 691a15dae8be2b28e02b6639aa92b832465c5be420Douglas Gregor Y0::template f2<U>(0); 701a15dae8be2b28e02b6639aa92b832465c5be420Douglas Gregor Y0::template f2(0); 710278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 720278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} 730278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} 740278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 750278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor int x; 760278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor x = Y0::f4(0); 770278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 781a15dae8be2b28e02b6639aa92b832465c5be420Douglas Gregor x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 790278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor 800278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor x = this->f4(0); 810278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 820278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} 830278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor } 840278e123b4606ea15dbfa717e9c5a76a5ef2bc7dDouglas Gregor}; 859d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara 869d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnarastruct A { 879d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara template<int I> 889d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara struct B { 899d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara static void b1(); 909d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara }; 919d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara}; 929d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara 939d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnaratemplate<int I> 949d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnaravoid f5() { 959d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}} 969d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara} 979d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnara 989d9922af13edf3ddf8804a41a98d997324fdd58eAbramo Bagnaratemplate void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}} 99