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