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