[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Parser / cxx1z-class-template-argument-deduction.cpp
blob2f0e948022fbf09f8c78cc48c1902fe65a0ecaab
1 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
3 template <typename T> struct A { // expected-note 38{{declared here}}
4 constexpr A() {}
5 constexpr A(int) {}
6 constexpr operator int() { return 0; }
7 };
8 A() -> A<int>;
9 A(int) -> A<int>;
11 // Make sure we still correctly parse cases where a template can appear without arguments.
12 namespace template_template_arg {
13 template<template<typename> typename> struct X {};
14 template<typename> struct Y {};
16 X<A> xa;
17 Y<A> ya; // expected-error {{requires template arguments}}
18 X<::A> xcca;
19 Y<::A> ycca; // expected-error {{requires template arguments}}
20 X<A*> xap; // expected-error {{requires template arguments}}
21 X<const A> xca; // expected-error {{requires template arguments}}
22 X<A const> xac; // expected-error {{requires template arguments}}
23 // FIXME: This should not parse as a template template argument due to the
24 // trailing attributes.
25 X<A [[]]> xa_attr;
27 template<template<typename> typename = A> struct XD {};
28 template<typename = A> struct YD {}; // expected-error {{requires template arguments}}
29 template<template<typename> typename = ::A> struct XCCD {};
30 template<typename = ::A> struct YCCD {}; // expected-error {{requires template arguments}}
32 // FIXME: replacing the invalid type with 'int' here is horrible
33 template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}}
34 template<typename T = A> struct G { }; // expected-error {{requires template arguments}}
37 namespace template_template_arg_pack {
38 template<template<typename> typename...> struct XP {};
39 template<typename...> struct YP {};
41 struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}}
43 template<typename T> using ZId = Z;
45 template<typename ...Ts> struct A {
46 XP<ZId<Ts>::Q...> xe;
47 YP<ZId<Ts>::Q...> ye; // expected-error {{requires template arguments}}
49 XP<ZId<Ts>::Q> xp; // expected-error {{unexpanded parameter pack}}
50 YP<ZId<Ts>::Q> yp; // expected-error {{requires template arguments}}
54 namespace injected_class_name {
55 template<typename T> struct A {
56 A(T);
57 void f(int) { // expected-note {{previous}}
58 A a = 1;
59 injected_class_name::A b = 1; // expected-note {{in instantiation of template class 'injected_class_name::A<int>'}}
61 void f(T); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (int)}}
63 A<short> ai = 1;
64 A<double>::A b(1); // expected-error {{constructor name}}
67 struct member {
68 A a; // expected-error {{requires template arguments}}
69 A *b; // expected-error {{requires template arguments}}
70 const A c; // expected-error {{requires template arguments}}
72 void f() throw (A); // expected-error {{requires template arguments}}
74 friend A; // expected-error {{requires template arguments; argument deduction not allowed in friend declaration}}
76 operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
78 static A x; // expected-error {{declaration of variable 'x' with deduced type 'A' requires an initializer}}
79 static constexpr A y = 0;
82 namespace in_typedef {
83 typedef A *AutoPtr; // expected-error {{requires template arguments; argument deduction not allowed in typedef}}
84 typedef A (*PFun)(int a); // expected-error{{requires template arguments; argument deduction not allowed in typedef}}
85 typedef A Fun(int a) -> decltype(a + a); // expected-error{{requires template arguments; argument deduction not allowed in function return type}}
88 namespace stmt {
89 void g(A a) { // expected-error{{requires template arguments; argument deduction not allowed in function prototype}}
90 try { }
91 catch (A &a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
92 catch (const A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
93 try { } catch (A a) { } // expected-error{{requires template arguments; argument deduction not allowed in exception declaration}}
95 // FIXME: The standard only permits class template argument deduction in a
96 // simple-declaration or cast. We also permit it in conditions,
97 // for-range-declarations, member-declarations for static data members, and
98 // new-expressions, because not doing so would be bizarre.
99 A local = 0;
100 static A local_static = 0;
101 static thread_local A thread_local_static = 0;
102 if (A a = 0) {}
103 if (A a = 0; a) {}
104 switch (A a = 0) {} // expected-warning {{no case matching constant switch condition '0'}}
105 switch (A a = 0; a) {} // expected-warning {{no case matching constant switch condition '0'}}
106 for (A a = 0; a; /**/) {}
107 for (/**/; A a = 0; /**/) {}
108 while (A a = 0) {}
109 int arr[3];
110 for (A a : arr) {}
113 namespace std {
114 class type_info;
118 namespace expr {
119 template<typename T> struct U {};
120 void j() {
121 (void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
122 (void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
123 (void)__alignof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
125 U<A> v; // expected-error {{requires template arguments}}
127 int n;
128 (void)dynamic_cast<A&>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
129 (void)static_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
130 (void)reinterpret_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
131 (void)const_cast<A>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
132 (void)*(A*)(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
133 (void)(A)(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
134 (void)(A){n}; // expected-error{{requires template arguments; argument deduction not allowed here}}
136 (void)A(n);
137 (void)A{n};
138 (void)new A(n);
139 (void)new A{n};
140 (void)new A;
144 namespace decl {
145 enum E : A {}; // expected-error{{requires template arguments; argument deduction not allowed here}}
146 struct F : A {}; // expected-error{{expected class name}}
148 using B = A; // expected-error{{requires template arguments}}
150 auto k() -> A; // expected-error{{requires template arguments}}
152 A a;
153 A b = 0;
154 const A c = 0;
155 A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
156 A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
157 A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
158 A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
159 A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
160 A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
161 A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{type 'A<int>' decomposes into 0 elements, but 2 names were provided}}
164 namespace typename_specifier {
165 struct F {};
167 void e() {
168 (void) typename ::A(0);
169 (void) typename ::A{0};
170 new typename ::A(0);
171 new typename ::A{0};
172 typename ::A a = 0;
173 const typename ::A b = 0;
174 if (typename ::A a = 0) {}
175 for (typename ::A a = 0; typename ::A b = 0; /**/) {}
177 (void)(typename ::A)(0); // expected-error{{requires template arguments; argument deduction not allowed here}}
178 (void)(typename ::A){0}; // expected-error{{requires template arguments; argument deduction not allowed here}}
180 typename ::A a = 0;
181 const typename ::A b = 0;
182 typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
183 typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
184 typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
185 typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
186 typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
187 typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
188 typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A<int>' (aka 'A<int>') decomposes into 0}}
190 struct X { template<typename T> struct A { A(T); }; }; // expected-note 8{{declared here}}
192 template<typename T> void f() {
193 (void) typename T::A(0);
194 (void) typename T::A{0};
195 new typename T::A(0);
196 new typename T::A{0};
197 typename T::A a = 0;
198 const typename T::A b = 0;
199 if (typename T::A a = 0) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
200 for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
202 {(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
203 {(void)(typename T::A){0};} // expected-error{{refers to class template member}}
204 {typename T::A (parens) = 0;} // expected-error {{refers to class template member in 'typename_specifier::X'; argument deduction not allowed here}}
205 // expected-warning@-1 {{disambiguated as redundant parentheses around declaration of variable named 'parens'}} expected-note@-1 {{add a variable name}} expected-note@-1{{remove parentheses}} expected-note@-1 {{add enclosing parentheses}}
206 {typename T::A *p = 0;} // expected-error {{refers to class template member}}
207 {typename T::A &r = *p;} // expected-error {{refers to class template member}}
208 {typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
209 {typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
210 {typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
211 {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') decomposes into 0}}
213 template void f<X>(); // expected-note {{instantiation of}}
215 template<typename T> void g(typename T::A = 0); // expected-note {{refers to class template member}}
216 void h() { g<X>(); } // expected-error {{no matching function}}
219 namespace parenthesized {
220 template<typename T> struct X { X(T); };
221 auto n = (X([]{}));
224 namespace within_template_arg_list {
225 template<typename T> struct X { constexpr X(T v) : v(v) {} T v; };
226 template<int N = X(1).v> struct Y {};
227 using T = Y<>;
228 using T = Y<X(1).v>;
229 using T = Y<within_template_arg_list::X(1).v>;
231 template<int ...N> struct Z { Y<X(N)...> y; };
234 namespace PR49735 {
235 // Ensure that we do not crash when parsing code which looks like an invalid
236 // deduction guide declaration.
237 template<class> struct B; // expected-note 2{{template is declared here}}
238 struct A1 {
239 B() noexcept(false); // expected-error {{deduction guide must be declared in the same scope as template 'PR49735::B'}} \
240 // expected-error {{deduction guide declaration without trailing return type}}
243 struct A2 {
244 template <typename Ty> // expected-note {{non-deducible template parameter 'Ty'}}
245 B() noexcept(false); // expected-error {{deduction guide must be declared in the same scope as template 'PR49735::B'}} \
246 // expected-error {{deduction guide template contains a template parameter that cannot be deduced}} \
247 // expected-error {{deduction guide declaration without trailing return type}}