Mercurial > hg > CbC > CbC_llvm
view clang/test/SemaTemplate/template-id-expr.cpp @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | 1d019706d866 |
children |
line wrap: on
line source
// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++03 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // PR5336 template<typename FromCl> struct isa_impl_cl { template<class ToCl> static void isa(const FromCl &Val) { } }; template<class X, class Y> void isa(const Y &Val) { return isa_impl_cl<Y>::template isa<X>(Val); } class Value; void f0(const Value &Val) { isa<Value>(Val); } // Implicit template-ids. template<typename T> struct X0 { template<typename U> void f1(); template<typename U> void f2(U) { f1<U>(); } }; void test_X0_int(X0<int> xi, float f) { xi.f2(f); } // Not template-id expressions, but they almost look like it. template<typename F> struct Y { Y(const F&); }; template<int I> struct X { X(int, int); void f() { Y<X<I> >(X<I>(0, 0)); Y<X<I> >(::X<I>(0, 0)); } }; template struct X<3>; // 'template' as a disambiguator. // PR7030 struct Y0 { template<typename U> void f1(U); template<typename U> static void f2(U); void f3(int); // expected-note 2{{declared as a non-template here}} static int f4(int); template<typename U> static void f4(U); template<typename U> void f() { Y0::template f1<U>(0); Y0::template f1(0); this->template f1(0); Y0::template f2<U>(0); Y0::template f2(0); Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} int x; x = Y0::f4(0); x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = this->f4(0); x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} } }; template<typename U> void Y0 ::template // expected-error {{expected unqualified-id}} f1(U) {} // FIXME: error recovery is awful without this. ; template<typename T> struct Y1 { template<typename U> void f1(U); template<typename U> static void f2(U); void f3(int); // expected-note 4{{declared as a non-template here}} static int f4(int); template<typename U> static void f4(U); template<typename U> void f() { Y1::template f1<U>(0); Y1::template f1(0); this->template f1(0); Y1::template f2<U>(0); Y1::template f2(0); Y1::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} Y1::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} int x; x = Y1::f4(0); x = Y1::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = Y1::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = this->f4(0); x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} } }; void use_Y1(Y1<int> y1) { y1.f<int>(); } // expected-note {{in instantiation of}} template<typename T> struct Y2 : Y1<T> { typedef ::Y1<T> Y1; template<typename U> void f(Y1 *p) { Y1::template f1<U>(0); Y1::template f1(0); p->template f1(0); Y1::template f2<U>(0); Y1::template f2(0); Y1::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} Y1::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}} int x; x = Y1::f4(0); x = Y1::f4<int>(0); // expected-error {{use 'template'}} expected-error {{assigning to 'int' from incompatible type 'void'}} x = Y1::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} x = p->f4(0); x = p->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} expected-error {{use 'template'}} x = p->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}} } }; void use_Y2(Y2<int> y2) { y2.f<int>(0); } // expected-note {{in instantiation of}} struct A { template<int I> struct B { static void b1(); // expected-note {{declared as a non-template here}} }; }; template<int I> void f5() { A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}} } template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}} class C {}; template <template <typename> class D> class E { template class D<C>; // expected-error {{expected '<' after 'template'}} template<> class D<C>; // expected-error {{cannot specialize a template template parameter}} friend class D<C>; // expected-error {{type alias template 'D' cannot be referenced with a class specifier}} }; #if __cplusplus <= 199711L // expected-warning@+2 {{extension}} #endif template<typename T> using D = int; // expected-note {{declared here}} E<D> ed; // expected-note {{instantiation of}}