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 | |
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 | |
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 | |