14848f3bfSNicolas Lesser // RUN: %clang_cc1 -std=c++20 -pedantic -verify %s 24848f3bfSNicolas Lesser 34848f3bfSNicolas Lesser struct X { 44848f3bfSNicolas Lesser using type = int; 54848f3bfSNicolas Lesser static constexpr int value = 1; 64848f3bfSNicolas Lesser class tclass {}; 74848f3bfSNicolas Lesser }; 84848f3bfSNicolas Lesser 94848f3bfSNicolas Lesser template <typename T> 104848f3bfSNicolas Lesser void f() { 114848f3bfSNicolas Lesser // it is a qualified name in a type-id-only context (see below), or 124848f3bfSNicolas Lesser // [its smallest enclosing [/new/defining/]-type-id is]: 134848f3bfSNicolas Lesser // - a new-type-id 144848f3bfSNicolas Lesser auto *Ptr = new T::type(); 154848f3bfSNicolas Lesser // - a defining-type-id 164848f3bfSNicolas Lesser class T::tclass Empty1; 174848f3bfSNicolas Lesser T::tclass Empty2; // expected-error{{missing 'typename'}} 184848f3bfSNicolas Lesser // - a trailing-return-type 194848f3bfSNicolas Lesser auto f()->T::type; 204848f3bfSNicolas Lesser // - default argument of a type-parameter of a template [see below] 214848f3bfSNicolas Lesser 224848f3bfSNicolas Lesser // - type-id of a 234848f3bfSNicolas Lesser // static_cast, 244848f3bfSNicolas Lesser auto StaticCast = static_cast<T::type>(1.2); 254848f3bfSNicolas Lesser // const_cast, 264848f3bfSNicolas Lesser const auto *ConstCast = const_cast<const T::type *>(Ptr); 274848f3bfSNicolas Lesser // reinterpret_cast, 284848f3bfSNicolas Lesser int ReinterpretCast = reinterpret_cast<T::type>(4); 294848f3bfSNicolas Lesser // dynamic_cast 304848f3bfSNicolas Lesser struct B { 314848f3bfSNicolas Lesser virtual ~B() = default; 324848f3bfSNicolas Lesser }; 334848f3bfSNicolas Lesser struct D : T::tclass {}; 344848f3bfSNicolas Lesser auto *Base = dynamic_cast<T::tclass *>(new B); 354848f3bfSNicolas Lesser 364848f3bfSNicolas Lesser T::type Invalid; // expected-error{{missing 'typename'}} 374848f3bfSNicolas Lesser } 384848f3bfSNicolas Lesser 394848f3bfSNicolas Lesser template void f<X>(); 404848f3bfSNicolas Lesser 414848f3bfSNicolas Lesser // As default argument. 424848f3bfSNicolas Lesser template <typename T, typename = T::type> 434848f3bfSNicolas Lesser struct DefaultArg {}; 444848f3bfSNicolas Lesser 454848f3bfSNicolas Lesser template struct DefaultArg<X>; 464848f3bfSNicolas Lesser 474848f3bfSNicolas Lesser // it is a decl-specifier of the decl-specifier-seq of a 484848f3bfSNicolas Lesser // - simple-declaration or a function-definition in namespace scope 494848f3bfSNicolas Lesser template <typename T> 504848f3bfSNicolas Lesser T::type VarTemp = 1; 514848f3bfSNicolas Lesser 524848f3bfSNicolas Lesser template int VarTemp<X>; 534848f3bfSNicolas Lesser 544848f3bfSNicolas Lesser template <typename T> 554848f3bfSNicolas Lesser T::type FuncDef() { return 1; } 564848f3bfSNicolas Lesser 574848f3bfSNicolas Lesser template int FuncDef<X>(); 584848f3bfSNicolas Lesser 594848f3bfSNicolas Lesser template <typename T> 604848f3bfSNicolas Lesser T::type funcDecl(); 614848f3bfSNicolas Lesser 624848f3bfSNicolas Lesser template <typename T> 634848f3bfSNicolas Lesser void FuncParam(T::type); // ok, but variable template 644848f3bfSNicolas Lesser // expected-error@-1{{variable has incomplete type 'void'}} 654848f3bfSNicolas Lesser 664848f3bfSNicolas Lesser template <typename T> 674848f3bfSNicolas Lesser void FuncParam2(const T::type, int); // expected-error{{missing 'typename'}} 684848f3bfSNicolas Lesser 694848f3bfSNicolas Lesser template <typename T> 704848f3bfSNicolas Lesser struct MemberDecl { 714848f3bfSNicolas Lesser // member-declaration, 724848f3bfSNicolas Lesser T::type Member; 734848f3bfSNicolas Lesser 744848f3bfSNicolas Lesser // parameter-declaration in a member-declaration, unless that 754848f3bfSNicolas Lesser // parameter-declaration appears in a default argument 764848f3bfSNicolas Lesser void NoDefault(T::type); 774848f3bfSNicolas Lesser void Default(int A = T::value); 784848f3bfSNicolas Lesser }; 794848f3bfSNicolas Lesser 804848f3bfSNicolas Lesser template struct MemberDecl<X>; 814848f3bfSNicolas Lesser 824848f3bfSNicolas Lesser // parameter-declaration in a declarator of a function or function template 834848f3bfSNicolas Lesser // declaration where the declarator-id is qualified, unless that 844848f3bfSNicolas Lesser // parameter-declaration appears in a default argument, 854848f3bfSNicolas Lesser struct QualifiedFunc { 864848f3bfSNicolas Lesser template <typename T> 874848f3bfSNicolas Lesser void foo(typename T::type); 884848f3bfSNicolas Lesser template <typename T> 894848f3bfSNicolas Lesser void bar(T::type); 904848f3bfSNicolas Lesser }; 914848f3bfSNicolas Lesser 924848f3bfSNicolas Lesser template <typename T> 934848f3bfSNicolas Lesser void QualifiedFunc::foo(T::type) {} 944848f3bfSNicolas Lesser template <typename T> 954848f3bfSNicolas Lesser void QualifiedFunc::bar(typename T::type) {} 964848f3bfSNicolas Lesser 974848f3bfSNicolas Lesser template <typename T> 984848f3bfSNicolas Lesser void g() { 994848f3bfSNicolas Lesser // parameter-declaration in a lambda-declarator, unless that 1004848f3bfSNicolas Lesser // parameter-declaration appears in a default argument, or 1014848f3bfSNicolas Lesser auto Lambda1 = [](T::type) {}; 1024848f3bfSNicolas Lesser auto Lambda2 = [](int A = T::value) {}; 1034848f3bfSNicolas Lesser } 1044848f3bfSNicolas Lesser 1054848f3bfSNicolas Lesser template void g<X>(); 1064848f3bfSNicolas Lesser 1074848f3bfSNicolas Lesser // parameter-declaration of a (non-type) template-parameter. 1084848f3bfSNicolas Lesser template <typename T, T::type> 1094848f3bfSNicolas Lesser void NonTypeArg() {} 1104848f3bfSNicolas Lesser 1114848f3bfSNicolas Lesser template void NonTypeArg<X, 0>(); 1124848f3bfSNicolas Lesser 1134848f3bfSNicolas Lesser template <typename T> 1144848f3bfSNicolas Lesser void f(T::type) {} // expected-error {{missing 'typename'}} 1154848f3bfSNicolas Lesser 1164848f3bfSNicolas Lesser namespace N { 1174848f3bfSNicolas Lesser template <typename T> 1184848f3bfSNicolas Lesser int f(typename T::type); 1194848f3bfSNicolas Lesser template <typename T> 1204848f3bfSNicolas Lesser extern int Var; 1214848f3bfSNicolas Lesser } 1224848f3bfSNicolas Lesser 1234848f3bfSNicolas Lesser template <typename T> 1244848f3bfSNicolas Lesser int N::f(T::type); // ok, function 1254848f3bfSNicolas Lesser template <typename T> 1264848f3bfSNicolas Lesser int N::Var(T::value); // ok, variable 1274848f3bfSNicolas Lesser 1284848f3bfSNicolas Lesser int h() { 1294848f3bfSNicolas Lesser return N::f<X>(10) + N::Var<X>; 1304848f3bfSNicolas Lesser } 1314848f3bfSNicolas Lesser 1324848f3bfSNicolas Lesser namespace NN { 1334848f3bfSNicolas Lesser inline namespace A { template <typename T> int f(typename T::type); } // expected-note{{previous definition is here}} 1344848f3bfSNicolas Lesser inline namespace B { template <typename T> int f(T::type); } 1354848f3bfSNicolas Lesser } 1364848f3bfSNicolas Lesser 1374848f3bfSNicolas Lesser template <typename T> 1384848f3bfSNicolas Lesser int NN::f(T::type); // expected-error{{redefinition of 'f' as different kind of symbol}} 1394848f3bfSNicolas Lesser 1404848f3bfSNicolas Lesser template <auto V> 1414848f3bfSNicolas Lesser struct videntity { 1424848f3bfSNicolas Lesser static constexpr auto value = V; 1434848f3bfSNicolas Lesser }; 1444848f3bfSNicolas Lesser 1454848f3bfSNicolas Lesser template <typename T, 1464848f3bfSNicolas Lesser bool = T::value, 1474848f3bfSNicolas Lesser bool = bool(T::value), 1484848f3bfSNicolas Lesser bool = videntity<bool(T::value)>::value> 1494848f3bfSNicolas Lesser void f(int = T::value) {} 1504848f3bfSNicolas Lesser 1514848f3bfSNicolas Lesser template <typename> int test() = delete; 1524848f3bfSNicolas Lesser template <auto> int test(); 1534848f3bfSNicolas Lesser 1544848f3bfSNicolas Lesser template <typename T> 1554848f3bfSNicolas Lesser int Test = test<int(T::value)>(); 1564848f3bfSNicolas Lesser template int Test<X>; 1574848f3bfSNicolas Lesser 1584848f3bfSNicolas Lesser template<typename T> struct A { 1594848f3bfSNicolas Lesser enum E : T::type {}; // expected-error{{missing 'typename'}} 1604848f3bfSNicolas Lesser operator T::type() {} // expected-error{{missing 'typename'}} 1614848f3bfSNicolas Lesser void f() { this->operator T::type(); } // expected-error{{missing 'typename'}} 1624848f3bfSNicolas Lesser }; 1634848f3bfSNicolas Lesser 1644848f3bfSNicolas Lesser template<typename T> 1654848f3bfSNicolas Lesser struct C { 1664848f3bfSNicolas Lesser C(T::type); // implicit typename context 1674848f3bfSNicolas Lesser friend C (T::fn)(); // not implicit typename context, declarator-id of friend declaration 1684848f3bfSNicolas Lesser C(T::type::*x)[3]; // not implicit typename context, pointer-to-member type 1694848f3bfSNicolas Lesser }; 1704848f3bfSNicolas Lesser 1714848f3bfSNicolas Lesser template <typename T> 1724848f3bfSNicolas Lesser C<T>::C(T::type) {} 173d9be8a8aSCorentin Jabot 174d9be8a8aSCorentin Jabot namespace GH63119 { 175d9be8a8aSCorentin Jabot struct X { 176d9be8a8aSCorentin Jabot X(int); 177d9be8a8aSCorentin Jabot X(auto); 178d9be8a8aSCorentin Jabot void f(int); 179d9be8a8aSCorentin Jabot }; 180d9be8a8aSCorentin Jabot template<typename T> struct S { 181d9be8a8aSCorentin Jabot friend X::X(T::type); 182d9be8a8aSCorentin Jabot friend X::X(T::type = (int)(void(*)(typename T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}} 183d9be8a8aSCorentin Jabot friend X::X(T::type = (int)(void(*)(T::type))(nullptr)); // expected-error {{friend declaration specifying a default argument must be a definition}} \ 184d9be8a8aSCorentin Jabot // expected-error {{expected expression}} 185d9be8a8aSCorentin Jabot friend void X::f(T::type); 186d9be8a8aSCorentin Jabot }; 187d9be8a8aSCorentin Jabot } 188*9daf10ffSOleksandr T. 189*9daf10ffSOleksandr T. namespace GH113324 { 190*9daf10ffSOleksandr T. template <typename = int> struct S1 { 191*9daf10ffSOleksandr T. friend void f1(S1, int = 0); // expected-error {{friend declaration specifying a default argument must be a definition}} 192*9daf10ffSOleksandr T. friend void f2(S1 a, S1 = decltype(a){}); // expected-error {{friend declaration specifying a default argument must be a definition}} 193*9daf10ffSOleksandr T. }; 194*9daf10ffSOleksandr T. 195*9daf10ffSOleksandr T. template <class T> using alias = int; 196*9daf10ffSOleksandr T. template <typename T> struct S2 { 197*9daf10ffSOleksandr T. // FIXME: We miss diagnosing the default argument instantiation failure 198*9daf10ffSOleksandr T. // (forming reference to void) 199*9daf10ffSOleksandr T. friend void f3(S2, int a = alias<T &>(1)); // expected-error {{friend declaration specifying a default argument must be a definition}} 200*9daf10ffSOleksandr T. }; 201*9daf10ffSOleksandr T. 202*9daf10ffSOleksandr T. void test() { 203*9daf10ffSOleksandr T. f1(S1<>{}); 204*9daf10ffSOleksandr T. f2(S1<>{}); 205*9daf10ffSOleksandr T. f3(S2<void>()); 206*9daf10ffSOleksandr T. } 207*9daf10ffSOleksandr T. } // namespace GH113324 208