xref: /llvm-project/clang/test/CXX/temp/temp.pre/p6.cpp (revision a64883431369f28f3fac311c496a4dfad480058f)
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