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