1 // Test C++ chained PCH functionality
2 
3 // Without PCH
4 // RUN: %clang_cc1 -fsyntax-only -verify -include %s -include %s %s
5 
6 // With PCH
7 // RUN: %clang_cc1 -fsyntax-only -verify %s -chain-include %s -chain-include %s
8 
9 // With modules
10 // RUN: %clang_cc1 -fsyntax-only -verify -fmodules %s -chain-include %s -chain-include %s
11 
12 // expected-no-diagnostics
13 
14 #ifndef HEADER1
15 #define HEADER1
16 //===----------------------------------------------------------------------===//
17 // Primary header for C++ chained PCH test
18 
19 void f();
20 
21 // Name not appearing in dependent
22 void pf();
23 
24 namespace ns {
25   void g();
26 
27   void pg();
28 }
29 
30 template <typename T>
31 struct S { typedef int G; };
32 
33 // Partially specialize
34 template <typename T>
35 struct S<T *> { typedef int H; };
36 
37 template <typename T> struct TS2;
38 typedef TS2<int> TS2int;
39 
40 template <typename T> struct TestBaseSpecifiers { };
41 template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { };
42 
43 template <typename T>
44 struct TS3 {
45   static const int value = 0;
46   static const int value2;
47 };
48 template <typename T>
49 const int TS3<T>::value;
50 template <typename T>
51 const int TS3<T>::value2 = 1;
52 // Instantiate struct, but not value.
53 struct instantiate : TS3<int> {};
54 
55 // Typedef
56 typedef int Integer;
57 
58 //===----------------------------------------------------------------------===//
59 #elif not defined(HEADER2)
60 #define HEADER2
61 #if !defined(HEADER1)
62 #error Header inclusion order messed up
63 #endif
64 
65 //===----------------------------------------------------------------------===//
66 // Dependent header for C++ chained PCH test
67 
68 // Overload function from primary
69 void f(int);
70 
71 // Add function with different name
72 void f2();
73 
74 // Reopen namespace
75 namespace ns {
76   // Overload function from primary
77   void g(int);
78 
79   // Add different name
80   void g2();
81 }
82 
83 // Specialize template from primary
84 template <>
85 struct S<int> { typedef int I; };
86 
87 // Partially specialize
88 template <typename T>
89 struct S<T &> { typedef int J; };
90 
91 // Specialize previous partial specialization
92 template <>
93 struct S<int *> { typedef int K; };
94 
95 // Specialize the partial specialization from this file
96 template <>
97 struct S<int &> { typedef int L; };
98 
99 template <typename T> struct TS2 { };
100 
101 struct TestBaseSpecifiers3 { };
102 struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { };
103 
104 struct A { };
105 struct B : A { };
106 
107 // Instantiate TS3's members.
108 static const int ts3m1 = TS3<int>::value;
109 extern int arr[TS3<int>::value2];
110 
111 // Redefinition of typedef
112 typedef int Integer;
113 
114 //===----------------------------------------------------------------------===//
115 #else
116 //===----------------------------------------------------------------------===//
117 
118 void test() {
119   f();
120   f(1);
121   pf();
122   f2();
123 
124   ns::g();
125   ns::g(1);
126   ns::pg();
127   ns::g2();
128 
129   typedef S<double>::G T1;
130   typedef S<double *>::H T2;
131   typedef S<int>::I T3;
132   typedef S<double &>::J T4;
133   typedef S<int *>::K T5;
134   typedef S<int &>::L T6;
135 
136   TS2int ts2;
137 
138   B b;
139   Integer i = 17;
140 }
141 
142 // Should have remembered that there is a definition.
143 static const int ts3m2 = TS3<int>::value;
144 int arr[TS3<int>::value2];
145 
146 //===----------------------------------------------------------------------===//
147 #endif
148