1 // RUN: %clang_cc1 -triple i686-mingw32 -ast-dump %s | FileCheck %s
2 // RUN: %clang_cc1 -triple i686-mingw32 -std=c++1z -ast-dump %s | FileCheck %s -check-prefix=CHECK-1Z
3 
4 template<class T>
5 class P {
6  public:
7   P(T* t) {}
8 };
9 
10 namespace foo {
11 class A { public: A(int = 0) {} };
12 enum B {};
13 typedef int C;
14 }
15 
16 // CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:[[@LINE+1]]:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]'
17 static foo::A ImplicitConstrArray[2];
18 
19 int main() {
20   // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::A *'
21   P<foo::A> p14 = new foo::A;
22   // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::B *'
23   P<foo::B> p24 = new foo::B;
24   // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::C *'
25   P<foo::C> pr4 = new foo::C;
26 }
27 
28 foo::A getName() {
29   // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A'
30   return foo::A();
31 }
32 
33 void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
34   // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A
35   a1->~A();
36   // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A
37   a2->foo::A::~A();
38   // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
39   p1->~P<int>();
40 }
41 
42 struct D {
43   D(int);
44   ~D();
45 };
46 
47 void construct() {
48   using namespace foo;
49   A a = A(12);
50   // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'foo::A' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
51   D d = D(12);
52   // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'D' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
53 }
54 
55 namespace PR38987 {
56 struct A { A(); };
57 template <class T> void f() { T{}; }
58 template void f<A>();
59 // CHECK: CXXTemporaryObjectExpr {{.*}} <col:31, col:33> 'PR38987::A':'PR38987::A'
60 }
61 
62 void abort() __attribute__((noreturn));
63 
64 namespace std {
65 typedef decltype(sizeof(int)) size_t;
66 
67 template <typename E> struct initializer_list {
68   const E *p;
69   size_t n;
70   initializer_list(const E *p, size_t n) : p(p), n(n) {}
71 };
72 
73 template <typename F, typename S> struct pair {
74   F f;
75   S s;
76   pair(const F &f, const S &s) : f(f), s(s) {}
77 };
78 
79 struct string {
80   const char *str;
81   string() { abort(); }
82   string(const char *S) : str(S) {}
83   ~string() { abort(); }
84 };
85 
86 template<typename K, typename V>
87 struct map {
88   using T = pair<K, V>;
89   map(initializer_list<T> i, const string &s = string()) {}
90   ~map() { abort(); }
91 };
92 
93 }; // namespace std
94 
95 // CHECK: NamespaceDecl {{.*}} attributed_decl
96 namespace attributed_decl {
97   void f() {
98     // CHECK: DeclStmt {{.*}} <line:[[@LINE+1]]:5, col:28>
99     [[maybe_unused]] int i1;
100     // CHECK: DeclStmt {{.*}} <line:[[@LINE+1]]:5, col:35>
101     __attribute__((unused)) int i2;
102     // CHECK: DeclStmt {{.*}} <line:[[@LINE+1]]:5, col:35>
103     int __attribute__((unused)) i3;
104     // CHECK: DeclStmt {{.*}} <<built-in>:{{.*}}, {{.*}}:[[@LINE+1]]:40>
105     __declspec(dllexport) extern int i4;
106     // CHECK: DeclStmt {{.*}} <line:[[@LINE+1]]:5, col:40>
107     extern int __declspec(dllexport) i5;
108   }
109 }
110 
111 #if __cplusplus >= 201703L
112 // CHECK-1Z: FunctionDecl {{.*}} construct_with_init_list
113 std::map<int, int> construct_with_init_list() {
114   // CHECK-1Z-NEXT: CompoundStmt
115   // CHECK-1Z-NEXT: ReturnStmt {{.*}} <line:[[@LINE+5]]:3, col:35
116   // CHECK-1Z-NEXT: ExprWithCleanups {{.*}} <col:10, col:35
117   // CHECK-1Z-NEXT: CXXBindTemporaryExpr {{.*}} <col:10, col:35
118   // CHECK-1Z-NEXT: CXXTemporaryObjectExpr {{.*}} <col:10, col:35
119   // CHECK-1Z-NEXT: CXXStdInitializerListExpr {{.*}} <col:28, col:35
120   return std::map<int, int>{{0, 0}};
121 }
122 
123 // CHECK-1Z: NamespaceDecl {{.*}} in_class_init
124 namespace in_class_init {
125   struct A {};
126 
127   // CHECK-1Z: CXXRecordDecl {{.*}} struct B definition
128   struct B {
129     // CHECK-1Z: FieldDecl {{.*}} a 'in_class_init::A'
130     // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:11, col:12
131     A a = {};
132   };
133 }
134 
135 // CHECK-1Z: NamespaceDecl {{.*}} delegating_constructor_init
136 namespace delegating_constructor_init {
137   struct A {};
138 
139   struct B : A {
140     A a;
141     B(A a) : a(a) {}
142   };
143 
144   // CHECK-1Z: CXXRecordDecl {{.*}} struct C definition
145   struct C : B {
146     // CHECK-1Z: CXXConstructorDecl {{.*}} C
147     // CHECK-1Z-NEXT: CXXCtorInitializer 'delegating_constructor_init::B'
148     // CHECK-1Z-NEXT: CXXConstructExpr {{.*}} <col:11, col:15
149     // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:13, col:14
150     C() : B({}) {};
151   };
152 }
153 
154 // CHECK-1Z: NamespaceDecl {{.*}} new_init
155 namespace new_init {
156   void A() {
157     // CHECK-1Z: CXXNewExpr {{.*}} <line:[[@LINE+2]]:5, col:14
158     // CHECK-1Z-NEXT: InitListExpr {{.*}} <col:12, col:14
159     new int{0};
160   }
161 }
162 #endif
163