summaryrefslogtreecommitdiff
path: root/clang/test/PCH/chain-cxx.cpp
blob: 0d50e61c5a956f426d538903a139bbf53eba3726 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Test C++ chained PCH functionality

// Without PCH
// RUN: %clang_cc1 -fsyntax-only -verify -include %s -include %s %s

// With PCH
// RUN: %clang_cc1 -fsyntax-only -verify %s -chain-include %s -chain-include %s

#ifndef HEADER1
#define HEADER1
//===----------------------------------------------------------------------===//
// Primary header for C++ chained PCH test

void f();

// Name not appearing in dependent
void pf();

namespace ns {
  void g();

  void pg();
}

template <typename T>
struct S { typedef int G; };

// Partially specialize
template <typename T>
struct S<T *> { typedef int H; };

template <typename T> struct TS2;
typedef TS2<int> TS2int;

template <typename T> struct TestBaseSpecifiers { };
template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { };

template <typename T>
struct TS3 {
  static const int value = 0;
  static const int value2;
};
template <typename T>
const int TS3<T>::value;
template <typename T>
const int TS3<T>::value2 = 1;
// Instantiate struct, but not value.
struct instantiate : TS3<int> {};

// Typedef
typedef int Integer;

//===----------------------------------------------------------------------===//
#elif not defined(HEADER2)
#define HEADER2
#if !defined(HEADER1)
#error Header inclusion order messed up
#endif

//===----------------------------------------------------------------------===//
// Dependent header for C++ chained PCH test

// Overload function from primary
void f(int);

// Add function with different name
void f2();

// Reopen namespace
namespace ns {
  // Overload function from primary
  void g(int);

  // Add different name
  void g2();
}

// Specialize template from primary
template <>
struct S<int> { typedef int I; };

// Partially specialize
template <typename T>
struct S<T &> { typedef int J; };

// Specialize previous partial specialization
template <>
struct S<int *> { typedef int K; };

// Specialize the partial specialization from this file
template <>
struct S<int &> { typedef int L; };

template <typename T> struct TS2 { };

struct TestBaseSpecifiers3 { };
struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { };

struct A { };
struct B : A { };

// Instantiate TS3's members.
static const int ts3m1 = TS3<int>::value;
extern int arr[TS3<int>::value2];

// Redefinition of typedef
typedef int Integer;

//===----------------------------------------------------------------------===//
#else
//===----------------------------------------------------------------------===//

void test() {
  f();
  f(1);
  pf();
  f2();

  ns::g();
  ns::g(1);
  ns::pg();
  ns::g2();

  typedef S<double>::G T1;
  typedef S<double *>::H T2;
  typedef S<int>::I T3;
  typedef S<double &>::J T4;
  typedef S<int *>::K T5;
  typedef S<int &>::L T6;

  TS2int ts2;

  B b;
  Integer i = 17;
}

// Should have remembered that there is a definition.
static const int ts3m2 = TS3<int>::value;
int arr[TS3<int>::value2];

//===----------------------------------------------------------------------===//
#endif