1// RUN: %clang_cc1 -fms-extensions -emit-llvm -o - %s | FileCheck %s
2
3// CHECK: %struct.test = type { i32, %struct.nested2, i32 }
4// CHECK: %struct.nested2 = type { i32, %struct.nested1, i32 }
5// CHECK: %struct.nested1 = type { i32, i32 }
6typedef struct nested1 {
7    int a1;
8    int b1;
9} NESTED1;
10
11struct nested2 {
12    int a;
13    NESTED1;
14    int b;
15};
16
17struct test {
18    int    x;
19    struct nested2;
20    int    y;
21};
22
23
24void foo()
25{
26  // CHECK: %var = alloca %struct.test, align 4
27  struct test var;
28
29  // CHECK: getelementptr inbounds %struct.test* %var, i32 0, i32 1
30  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0
31  // CHECK-NEXT: load i32* %{{.*}}, align 4
32  var.a;
33
34  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1
35  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2
36  // CHECK-NEXT: load i32* %{{.*}}, align 4
37  var.b;
38
39  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 1
40  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
41  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0
42  // CHECK-NEXT: load i32* %{{.*}}, align 4
43  var.a1;
44
45  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}var, i32 0, i32 1
46  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
47  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1
48  // CHECK-NEXT: load i32* %{{.*}}, align 4
49  var.b1;
50
51  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 0
52  // CHECK-NEXT: load i32* %{{.*}}, align 4
53  var.x;
54
55  // CHECK-NEXT: getelementptr inbounds %struct.test* %var, i32 0, i32 2
56  // CHECK-NEXT: load i32* %{{.*}}, align 4
57  var.y;
58}
59
60void foo2(struct test* var)
61{
62  // CHECK: alloca %struct.test*, align
63  // CHECK-NEXT: store %struct.test* %var, %struct.test** %{{.*}}, align
64  // CHECK-NEXT: load %struct.test** %{{.*}}, align
65  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
66  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 0
67  // CHECK-NEXT: load i32* %{{.*}}, align 4
68  var->a;
69
70  // CHECK-NEXT: load %struct.test** %{{.*}}, align
71  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
72  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 2
73  // CHECK-NEXT: load i32* %{{.*}}, align 4
74  var->b;
75
76  // CHECK-NEXT: load %struct.test** %{{.*}}, align
77  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
78  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
79  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 0
80  // CHECK-NEXT: load i32* %{{.*}}, align 4
81  var->a1;
82
83  // CHECK-NEXT: load %struct.test** %{{.*}}, align
84  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 1
85  // CHECK-NEXT: getelementptr inbounds %struct.nested2* %{{.*}}, i32 0, i32 1
86  // CHECK-NEXT: getelementptr inbounds %struct.nested1* %{{.*}}, i32 0, i32 1
87  // CHECK-NEXT: load i32* %{{.*}}, align 4
88  var->b1;
89
90  // CHECK-NEXT: load %struct.test** %{{.*}}, align
91  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 0
92  // CHECK-NEXT: load i32* %{{.*}}, align 4
93  var->x;
94
95  // CHECK-NEXT: load %struct.test** %{{.*}}, align
96  // CHECK-NEXT: getelementptr inbounds %struct.test* %{{.*}}, i32 0, i32 2
97  // CHECK-NEXT: load i32* %{{.*}}, align 4
98  var->y;
99}
100