1 // RUN: %clang_cc1 -std=c++20 -verify %s
2
3 // Templates and partial and explicit specializations can't have C linkage.
4 namespace extern_c_templates {
5
6 template<typename T> struct A {
7 static int a;
8 struct b;
9 void c();
10 enum class d;
11
12 template<typename U> static int e;
13 template<typename U> struct f;
14 template<typename U> void g();
15 };
16
17 template<typename T> int B;
18 template<typename T> void C();
19
20 extern "C" { // expected-note 1+{{begins here}}
21 // templates
22 template<typename T> struct A; // expected-error {{templates must have C++ linkage}}
23 template<typename T> int B; // expected-error {{templates must have C++ linkage}}
24 template<typename T> void C(); // expected-error {{templates must have C++ linkage}}
25
26 // non-template members of a template
27 // FIXME: Should these really be valid?
28 template<typename T> int A<T>::a;
29 template<typename T> struct A<T>::b {};
c()30 template<typename T> void A<T>::c() {}
31 template<typename T> enum class A<T>::d {};
32
33 // templates
34 template<typename T> template<typename U> int A<T>::e; // expected-error {{templates must have C++ linkage}}
35 template<typename T> template<typename U> struct A<T>::f {}; // expected-error {{templates must have C++ linkage}}
g()36 template<typename T> template<typename U> void A<T>::g() {} // expected-error {{templates must have C++ linkage}}
37
38 // partial specializations
39 template<typename T> struct A<int*>; // expected-error {{templates must have C++ linkage}}
40 template<typename T> int B<int*>; // expected-error {{templates must have C++ linkage}}
41 template<typename T> template<typename U> int A<T>::e<U*>; // expected-error {{templates must have C++ linkage}}
42 template<typename T> template<typename U> struct A<T>::f<U*> {}; // expected-error {{templates must have C++ linkage}}
43
44 // explicit specializations of templates
45 template<> struct A<char> {}; // expected-error {{templates must have C++ linkage}}
46 template<> int B<char>; // expected-error {{templates must have C++ linkage}}
C()47 template<> void C<char>() {} // expected-error {{templates must have C++ linkage}}
48
49 // explicit specializations of members of a template
50 template<> int A<int>::a; // expected-error {{templates must have C++ linkage}}
51 template<> struct A<int>::b {}; // expected-error {{templates must have C++ linkage}}
c()52 template<> void A<int>::c() {} // expected-error {{templates must have C++ linkage}}
53 template<> enum class A<int>::d {}; // expected-error {{templates must have C++ linkage}}
54
55 // explicit specializations of member templates
56 template<> template<typename U> int A<int>::e; // expected-error {{templates must have C++ linkage}}
57 template<> template<typename U> struct A<int>::f {}; // expected-error {{templates must have C++ linkage}}
g()58 template<> template<typename U> void A<int>::g() {} // expected-error {{templates must have C++ linkage}}
59 }
60
61 // Provide valid definitions for the explicit instantiations below.
62 // FIXME: Our recovery from the invalid definitions above isn't very good.
63 template<typename T> template<typename U> int A<T>::e;
64 template<typename T> template<typename U> struct A<T>::f {};
g()65 template<typename T> template<typename U> void A<T>::g() {}
66
67 extern "C" {
68 // explicit instantiations
69 // FIXME: Should these really be valid?
70 template struct A<double>;
71 template int A<float>::a;
72 template struct A<float>::b;
73 template void A<float>::c();
74 template int A<float>::e<float>;
75 template struct A<float>::f<float>;
76 template void A<float>::g<float>();
77 }
78
79 }
80