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
19void f();
20
21// Name not appearing in dependent
22void pf();
23
24namespace ns {
25  void g();
26
27  void pg();
28}
29
30template <typename T>
31struct S { typedef int G; };
32
33// Partially specialize
34template <typename T>
35struct S<T *> { typedef int H; };
36
37template <typename T> struct TS2;
38typedef TS2<int> TS2int;
39
40template <typename T> struct TestBaseSpecifiers { };
41template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { };
42
43template <typename T>
44struct TS3 {
45  static const int value = 0;
46  static const int value2;
47};
48template <typename T>
49const int TS3<T>::value;
50template <typename T>
51const int TS3<T>::value2 = 1;
52// Instantiate struct, but not value.
53struct instantiate : TS3<int> {};
54
55// Typedef
56typedef 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
69void f(int);
70
71// Add function with different name
72void f2();
73
74// Reopen namespace
75namespace 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
84template <>
85struct S<int> { typedef int I; };
86
87// Partially specialize
88template <typename T>
89struct S<T &> { typedef int J; };
90
91// Specialize previous partial specialization
92template <>
93struct S<int *> { typedef int K; };
94
95// Specialize the partial specialization from this file
96template <>
97struct S<int &> { typedef int L; };
98
99template <typename T> struct TS2 { };
100
101struct TestBaseSpecifiers3 { };
102struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { };
103
104struct A { };
105struct B : A { };
106
107// Instantiate TS3's members.
108static const int ts3m1 = TS3<int>::value;
109extern int arr[TS3<int>::value2];
110
111// Redefinition of typedef
112typedef int Integer;
113
114//===----------------------------------------------------------------------===//
115#else
116//===----------------------------------------------------------------------===//
117
118void 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.
143static const int ts3m2 = TS3<int>::value;
144int arr[TS3<int>::value2];
145
146//===----------------------------------------------------------------------===//
147#endif
148