Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
      2 
      3 // CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
      4 // CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ",
      5 // CHECK:       i8* bitcast (%class.A* @"\01?foo@?$B@H@@2VA@@A" to i8*) },
      6 // CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }]
      7 
      8 struct S {
      9   S();
     10   ~S();
     11 };
     12 
     13 S s;
     14 
     15 // CHECK: define internal void @"\01??__Es@@YAXXZ"()
     16 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
     17 // CHECK: call i32 @atexit(void ()* @"\01??__Fs@@YAXXZ")
     18 // CHECK: ret void
     19 
     20 // CHECK: define internal void @"\01??__Fs@@YAXXZ"()
     21 // CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ"
     22 // CHECK: ret void
     23 
     24 // These globals should use distinct guard variables, and not different bits of
     25 // the same global.
     26 __declspec(selectany) S selectany1;
     27 __declspec(selectany) S selectany2;
     28 // CHECK: define linkonce_odr void @"\01??__Eselectany1@@YAXXZ"()
     29 // CHECK-NOT: @"\01??_Bselectany1
     30 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
     31 // CHECK: ret void
     32 // CHECK: define linkonce_odr void @"\01??__Eselectany2@@YAXXZ"()
     33 // CHECK-NOT: @"\01??_Bselectany2
     34 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
     35 // CHECK: ret void
     36 
     37 void StaticLocal() {
     38   static S TheS;
     39 }
     40 // CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"()
     41 // CHECK: load i32* @"\01?$S1@?0??StaticLocal@@YAXXZ@4IA"
     42 // CHECK: store i32 {{.*}}, i32* @"\01?$S1@?0??StaticLocal@@YAXXZ@4IA"
     43 // CHECK: ret
     44 
     45 void MultipleStatics() {
     46   static S S1;
     47   static S S2;
     48   static S S3;
     49   static S S4;
     50   static S S5;
     51   static S S6;
     52   static S S7;
     53   static S S8;
     54   static S S9;
     55   static S S10;
     56   static S S11;
     57   static S S12;
     58   static S S13;
     59   static S S14;
     60   static S S15;
     61   static S S16;
     62   static S S17;
     63   static S S18;
     64   static S S19;
     65   static S S20;
     66   static S S21;
     67   static S S22;
     68   static S S23;
     69   static S S24;
     70   static S S25;
     71   static S S26;
     72   static S S27;
     73   static S S28;
     74   static S S29;
     75   static S S30;
     76   static S S31;
     77   static S S32;
     78   static S S33;
     79   static S S34;
     80   static S S35;
     81 }
     82 // CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"()
     83 // CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ@4IA"
     84 // CHECK: and i32 {{.*}}, 1
     85 // CHECK: and i32 {{.*}}, 2
     86 // CHECK: and i32 {{.*}}, 4
     87 // CHECK: and i32 {{.*}}, 8
     88 // CHECK: and i32 {{.*}}, 16
     89 //   ...
     90 // CHECK: and i32 {{.*}}, -2147483648
     91 // CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ@4IA1"
     92 // CHECK: and i32 {{.*}}, 1
     93 // CHECK: and i32 {{.*}}, 2
     94 // CHECK: and i32 {{.*}}, 4
     95 // CHECK: ret
     96 
     97 // Force WeakODRLinkage by using templates
     98 class A {
     99  public:
    100   A() {}
    101   ~A() {}
    102   int a;
    103 };
    104 
    105 template<typename T>
    106 class B {
    107  public:
    108   static A foo;
    109 };
    110 
    111 template<typename T> A B<T>::foo;
    112 
    113 inline S &UnreachableStatic() {
    114   if (0) {
    115     static S s; // bit 1
    116     return s;
    117   }
    118   static S s; // bit 2
    119   return s;
    120 }
    121 
    122 // CHECK-LABEL: define linkonce_odr nonnull %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"()
    123 // CHECK: and i32 {{.*}}, 2
    124 // CHECK: or i32 {{.*}}, 2
    125 // CHECK: ret
    126 
    127 inline S &getS() {
    128   static S TheS;
    129   return TheS;
    130 }
    131 
    132 // CHECK-LABEL: define linkonce_odr nonnull %struct.S* @"\01?getS@@YAAAUS@@XZ"
    133 // CHECK: load i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
    134 // CHECK: and i32 {{.*}}, 1
    135 // CHECK: icmp ne i32 {{.*}}, 0
    136 // CHECK: br i1
    137 //   init:
    138 // CHECK: or i32 {{.*}}, 1
    139 // CHECK: store i32 {{.*}}, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
    140 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"(%struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A")
    141 // CHECK: call i32 @atexit(void ()* @"\01??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ")
    142 // CHECK: br label
    143 //   init.end:
    144 // CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
    145 
    146 inline int enum_in_function() {
    147   // CHECK-LABEL: define linkonce_odr i32 @"\01?enum_in_function@@YAHXZ"()
    148   static enum e { foo, bar, baz } x;
    149   // CHECK: @"\01?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A"
    150   static int y;
    151   // CHECK: @"\01?y@?1??enum_in_function@@YAHXZ@4HA"
    152   return x + y;
    153 };
    154 
    155 struct T {
    156   enum e { foo, bar, baz };
    157   int enum_in_struct() {
    158     // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01?enum_in_struct@T@@QAEHXZ"
    159     static int x;
    160     // CHECK: @"\01?x@?1??enum_in_struct@T@@QAEHXZ@4HA"
    161     return x++;
    162   }
    163 };
    164 
    165 inline int switch_test(int x) {
    166   // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x)
    167   switch (x) {
    168     static int a;
    169     // CHECK: @"\01?a@?3??switch_test@@YAHH@Z@4HA"
    170     case 0:
    171       a++;
    172       return 1;
    173     case 1:
    174       static int b;
    175       // CHECK: @"\01?b@?3??switch_test@@YAHH@Z@4HA"
    176       return b++;
    177     case 2: {
    178       static int c;
    179       // CHECK: @"\01?c@?4??switch_test@@YAHH@Z@4HA"
    180       return b + c++;
    181     }
    182   };
    183 }
    184 
    185 int f();
    186 inline void switch_test2() {
    187   // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"()
    188   // CHECK: @"\01?x@?2??switch_test2@@YAXXZ@4HA"
    189   switch (1) default: static int x = f();
    190 }
    191 
    192 namespace DynamicDLLImportInitVSMangling {
    193   // Failing to pop the ExprEvalContexts when instantiating a dllimport var with
    194   // dynamic initializer would cause subsequent static local numberings to be
    195   // incorrect.
    196   struct NonPOD { NonPOD(); };
    197   template <typename T> struct A { static NonPOD x; };
    198   template <typename T> NonPOD A<T>::x;
    199   template struct __declspec(dllimport) A<int>;
    200 
    201   inline int switch_test3() {
    202     // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"
    203     static int local;
    204     // CHECK: @"\01?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA"
    205     return local++;
    206   }
    207 }
    208 
    209 void force_usage() {
    210   UnreachableStatic();
    211   getS();
    212   (void)B<int>::foo;  // (void) - force usage
    213   enum_in_function();
    214   (void)&T::enum_in_struct;
    215   switch_test(1);
    216   switch_test2();
    217   DynamicDLLImportInitVSMangling::switch_test3();
    218 }
    219 
    220 // CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"()
    221 // CHECK-NOT: and
    222 // CHECK-NOT: ?_Bfoo@
    223 // CHECK: call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
    224 // CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ")
    225 // CHECK: ret void
    226 
    227 // CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
    228 
    229 // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"
    230 
    231 // CHECK: define internal void @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ"
    232 // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo
    233 // CHECK: ret void
    234 
    235 // CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp()
    236 // CHECK: call void @"\01??__Es@@YAXXZ"()
    237 // CHECK: ret void
    238