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* %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 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** %{{.*}}, 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