Clang Project

clang_source_code/test/SemaTemplate/extern-templates.cpp
1// RUN: %clang_cc1 -triple i686-pc-win32 -fsyntax-only -verify %s -DMS
2// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu-pc-win32 -fsyntax-only -verify %s
3
4template<typename T>
5class X0 {
6public:
7  void f(T t);
8  
9  struct Inner {
10    void g(T t);
11  };
12};
13
14template<typename T>
15void X0<T>::f(T t) {
16  t = 17; // expected-error{{incompatible}}
17}
18
19extern template class X0<int>;
20
21extern template class X0<int*>;
22
23template<typename T>
24void X0<T>::Inner::g(T t) {
25#ifdef MS
26  t = 17; // expected-error{{assigning to 'long *' from incompatible}} expected-error{{assigning to 'int *' from incompatible}}
27#else
28  t = 17; // expected-error{{assigning to 'long *' from incompatible}}
29#endif
30}
31
32void test_intptr(X0<int*> xi, X0<int*>::Inner xii) {
33  xi.f(0);
34#ifdef MS
35  xii.g(0); // expected-note {{instantiation}}
36#else
37  xii.g(0);
38#endif
39}
40
41extern template class X0<long*>; 
42
43void test_longptr(X0<long*> xl, X0<long*>::Inner xli) {
44  xl.f(0);
45  xli.g(0);
46}
47
48template class X0<long*>; // expected-note 2{{instantiation}}
49
50template<typename T>
51class X1 {
52public:
53  void f(T t) { t += 2; }
54  
55  void g(T t);
56};
57
58template<typename T>
59void X1<T>::g(T t) { 
60  t += 2; 
61}
62
63extern template class X1<void*>;
64
65void g_X1(X1<void*> x1, void *ptr) {
66  x1.g(ptr);
67}
68
69extern template void X1<const void*>::g(const void*);
70
71void g_X1_2(X1<const void *> x1, const void *ptr) {
72  x1.g(ptr);
73}
74
75namespace static_const_member {
76  template <typename T> struct A { static const int n; };
77  template <typename T> const int A<T>::n = 3;
78  extern template struct A<int>;
79  int arr[A<int>::n];
80}
81