Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
      2 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
      3 
      4 template<typename T>
      5 class Class {
      6  public:
      7   Class() {}
      8 };
      9 
     10 class Typename { };
     11 
     12 template<typename T>
     13 class Nested { };
     14 
     15 template<bool flag>
     16 class BoolTemplate {
     17  public:
     18   BoolTemplate() {}
     19 };
     20 
     21 template<int param>
     22 class IntTemplate {
     23  public:
     24   IntTemplate() {}
     25 };
     26 
     27 template<>
     28 class BoolTemplate<true> {
     29  public:
     30   BoolTemplate() {}
     31   template<class T> void Foo(T arg) {}
     32 };
     33 
     34 void template_mangling() {
     35   Class<Typename> c1;
     36 // CHECK: call {{.*}} @"\01??0?$Class@VTypename@@@@QAE@XZ"
     37 // X64: call {{.*}} @"\01??0?$Class@VTypename@@@@QEAA@XZ"
     38 
     39   Class<const Typename> c1_const;
     40 // CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE@XZ"
     41 // X64: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QEAA@XZ"
     42   Class<volatile Typename> c1_volatile;
     43 // CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE@XZ"
     44 // X64: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QEAA@XZ"
     45   Class<const volatile Typename> c1_cv;
     46 // CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE@XZ"
     47 // X64: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QEAA@XZ"
     48 
     49   Class<Nested<Typename> > c2;
     50 // CHECK: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ"
     51 // X64: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QEAA@XZ"
     52 
     53   Class<int * const> c_intpc;
     54 // CHECK: call {{.*}} @"\01??0?$Class@QAH@@QAE@XZ"
     55 // X64: call {{.*}} @"\01??0?$Class@QEAH@@QEAA@XZ"
     56   Class<int()> c_ft;
     57 // CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE@XZ"
     58 // X64: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QEAA@XZ"
     59   Class<int[]> c_inti;
     60 // CHECK: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QAE@XZ"
     61 // X64: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QEAA@XZ"
     62   Class<int[5]> c_int5;
     63 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE@XZ"
     64 // X64: call {{.*}} @"\01??0?$Class@$$BY04H@@QEAA@XZ"
     65   Class<const int[5]> c_intc5;
     66 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE@XZ"
     67 // X64: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QEAA@XZ"
     68   Class<int * const[5]> c_intpc5;
     69 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE@XZ"
     70 // X64: call {{.*}} @"\01??0?$Class@$$BY04QEAH@@QEAA@XZ"
     71 
     72   BoolTemplate<false> _false;
     73 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ"
     74 // X64: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QEAA@XZ"
     75 
     76   BoolTemplate<true> _true;
     77   // PR13158
     78   _true.Foo(1);
     79 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$00@@QAE@XZ"
     80 // X64: call {{.*}} @"\01??0?$BoolTemplate@$00@@QEAA@XZ"
     81 // CHECK: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QAEXH@Z"
     82 // X64: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QEAAXH@Z"
     83 
     84   IntTemplate<0> zero;
     85 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QAE@XZ"
     86 // X64: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QEAA@XZ"
     87 
     88   IntTemplate<5> five;
     89 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$04@@QAE@XZ"
     90 // X64: call {{.*}} @"\01??0?$IntTemplate@$04@@QEAA@XZ"
     91 
     92   IntTemplate<11> eleven;
     93 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QAE@XZ"
     94 // X64: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QEAA@XZ"
     95 
     96   IntTemplate<256> _256;
     97 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QAE@XZ"
     98 // X64: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QEAA@XZ"
     99 
    100   IntTemplate<513> _513;
    101 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QAE@XZ"
    102 // X64: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QEAA@XZ"
    103 
    104   IntTemplate<1026> _1026;
    105 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QAE@XZ"
    106 // X64: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QEAA@XZ"
    107 
    108   IntTemplate<65535> ffff;
    109 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE@XZ"
    110 // X64: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QEAA@XZ"
    111 }
    112 
    113 namespace space {
    114   template<class T> const T& foo(const T& l) { return l; }
    115 }
    116 // CHECK: "\01??$foo@H@space@@YAABHABH@Z"
    117 // X64: "\01??$foo@H@space@@YAAEBHAEBH@Z"
    118 
    119 void use() {
    120   space::foo(42);
    121 }
    122 
    123 // PR13455
    124 typedef void (*FunctionPointer)(void);
    125 
    126 template <FunctionPointer function>
    127 void FunctionPointerTemplate() {
    128   function();
    129 }
    130 
    131 void spam() {
    132   FunctionPointerTemplate<spam>();
    133 // CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
    134 // X64: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
    135 }
    136 
    137 // Unlike Itanium, there is no character code to indicate an argument pack.
    138 // Tested with MSVC 2013, the first version which supports variadic templates.
    139 
    140 template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
    141 void variadic_fn_instantiate() {
    142   variadic_fn_template(0, 1, 3, 4);
    143   variadic_fn_template(0, 1, 'a', "b");
    144 }
    145 // CHECK: "\01??$variadic_fn_template@HHHH@@YAXABH000@Z"
    146 // CHECK: "\01??$variadic_fn_template@HHD$$BY01D@@YAXABH0ABDAAY01$$CBD@Z"
    147 
    148 template <typename ...Ts>
    149 struct VariadicClass {
    150   VariadicClass() { }
    151   int x;
    152 };
    153 void variadic_class_instantiate() {
    154   VariadicClass<int, char, bool> a;
    155   VariadicClass<bool, char, int> b;
    156 }
    157 // CHECK: call {{.*}} @"\01??0?$VariadicClass@HD_N@@QAE@XZ"
    158 // CHECK: call {{.*}} @"\01??0?$VariadicClass@_NDH@@QAE@XZ"
    159 
    160 template <typename T>
    161 struct Second {};
    162 
    163 template <typename T, template <class> class>
    164 struct Type {};
    165 
    166 template <template <class> class T>
    167 struct Type2 {};
    168 
    169 template <template <class> class T, bool B>
    170 struct Thing;
    171 
    172 template <template <class> class T>
    173 struct Thing<T, false> { };
    174 
    175 template <template <class> class T>
    176 struct Thing<T, true> { };
    177 
    178 void template_template_fun(Type<Thing<Second, true>, Second>) { }
    179 // CHECK: "\01?template_template_fun@@YAXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z"
    180 
    181 template <typename T>
    182 void template_template_specialization();
    183 
    184 template <>
    185 void template_template_specialization<void (Type<Thing<Second, true>, Second>)>() {
    186 }
    187 // CHECK: "\01??$template_template_specialization@$$A6AXU?$Type@U?$Thing@USecond@@$00@@USecond@@@@@Z@@YAXXZ"
    188 
    189 // PR16788
    190 template <decltype(nullptr)> struct S1 {};
    191 void f(S1<nullptr>) {}
    192 // CHECK: "\01?f@@YAXU?$S1@$0A@@@@Z"
    193