Home | History | Annotate | Download | only in CodeGen
      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