1 // RUN: %clang_cc1 -std=c++20 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s 2 // RUN: %clang_cc1 -std=c++20 %s -triple x86_64-windows -emit-llvm -o - | FileCheck %s --check-prefix=MSABI 3 4 #define fold(x) (__builtin_constant_p(x) ? (x) : (x)) 5 6 struct A { int a; const int b; }; 7 template<A> void f() {} 8 9 // CHECK: define weak_odr void @_Z1fIXtl1ALi1ELi2EEEEvv( 10 // MSABI: define {{.*}} @"??$f@$2UA@@H00$$CBH01@@@YAXXZ" 11 template void f<A{1, 2}>(); 12 13 struct B { const int *p; int k; }; 14 template<B> void f() {} 15 16 int n = 0; 17 // CHECK: define weak_odr void @_Z1fIXtl1BadL_Z1nEEEEvv( 18 // MSABI: define {{.*}} @"??$f@$2UB@@PEBH1?n@@3HAH0A@@@@YAXXZ" 19 template void f<B{&n}>(); 20 // CHECK: define weak_odr void @_Z1fIXtl1BLPKi0ELi1EEEEvv( 21 // MSABI: define {{.*}} @"??$f@$2UB@@PEBH0A@H00@@@YAXXZ" 22 template void f<B{nullptr, 1}>(); 23 // CHECK: define weak_odr void @_Z1fIXtl1BEEEvv( 24 // MSABI: define {{.*}} @"??$f@$2UB@@PEBH0A@H0A@@@@YAXXZ" 25 template void f<B{nullptr}>(); 26 #ifndef _WIN32 27 // FIXME: MSVC crashes on the first of these and mangles the second the same as 28 // the nullptr version. Check the output is correct once we have a reference to 29 // compare against. 30 // CHECK: define weak_odr void @_Z1fIXtl1BLPKi32EEEEvv( 31 template void f<B{fold((int*)32)}>(); 32 // CHECK: define weak_odr void @_Z1fIXtl1BrcPKiLi0EEEEvv( 33 template void f<B{fold(reinterpret_cast<int*>(0))}>(); 34 #endif 35 36 // Pointers to subobjects. 37 struct Nested { union { int k; int arr[2]; }; } nested[2]; 38 struct Derived : A, Nested { int z; } extern derived; 39 #ifndef _WIN32 40 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE_EEEEvv 41 // FIXME: MSVC generates the garbage mangling ??$f@$2UB@@PEAH0A@H0A@@@@YAXXZ 42 // for this. 43 template void f<B{&nested[0].k}>(); 44 // FIXME: MSVC crashes on these. 45 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z6nestedE16_0pEEEEvv 46 template void f<B{&nested[1].arr[2]}>(); 47 // CHECK: define weak_odr void @_Z1fIXtl1BadsoKiL_Z7derivedE8pEEEEvv 48 template void f<B{&derived.b + 1}>(); 49 // CHECK: define weak_odr void @_Z1fIXtl1BcvPKiplcvPcadL_Z7derivedELl16EEEEvv 50 template void f<B{fold(&derived.b + 3)}>(); 51 #endif 52 53 // References to subobjects. 54 struct BR { const int &r; }; 55 template<BR> void f() {} 56 #ifndef _WIN32 57 // FIXME: MSVC produces garbage manglings for these. 58 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE_EEEEvv 59 template void f<BR{nested[0].k}>(); 60 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z6nestedE12_0EEEEvv 61 template void f<BR{nested[1].arr[1]}>(); 62 // CHECK: define weak_odr void @_Z1fIXtl2BRsoKiL_Z7derivedE4EEEEvv 63 template void f<BR{derived.b}>(); 64 // FIXME: Crashes MSVC. 65 // CHECK: define weak_odr void @_Z1fIXtl2BRdecvPKiplcvPcadL_Z7derivedELl16EEEEvv 66 template void f<BR{fold(*(&derived.b + 3))}>(); 67 #endif 68 69 // Qualification conversions. 70 struct C { const int *p; }; 71 template<C> void f() {} 72 #ifndef _WIN32 73 // FIXME: MSVC produces a garbage mangling for this. 74 // CHECK: define weak_odr void @_Z1fIXtl1CadsoKiL_Z7derivedE4EEEEvv 75 template void f<C{&derived.b}>(); 76 #endif 77 78 // Pointers to members. 79 struct D { const int Derived::*p; int k; }; 80 template<D> void f() {} 81 // CHECK: define weak_odr void @_Z1fIXtl1DLM7DerivedKi0ELi1EEEEvv 82 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0?0H00@@@YAXXZ" 83 template void f<D{nullptr, 1}>(); 84 // CHECK: define weak_odr void @_Z1fIXtl1DEEEvv 85 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0?0H0A@@@@YAXXZ" 86 template void f<D{nullptr}>(); 87 // CHECK: define weak_odr void @_Z1fIXtl1DadL_ZN7Derived1zEEEEEvv 88 // MSABI: define {{.*}} @"??$f@$2UD@@PERDerived@@H0BA@H0A@@@@YAXXZ" 89 template void f<D{&Derived::z}>(); 90 #ifndef _WIN32 91 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1aEEEEEEvv 92 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0A@H0A@@@@YAXXZ" 93 template void f<D{&A::a}>(); 94 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN1A1bEEEEEEvv 95 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H03H0A@@@@YAXXZ" 96 template void f<D{&A::b}>(); 97 // FIXME: Is the Ut_1 mangling here correct? 98 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN6NestedUt_1kEE8ELi2EEEEvv 99 // FIXME: This mangles the same as &A::a (bug in the MS ABI). 100 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0A@H01@@@YAXXZ" 101 template void f<D{&Nested::k, 2}>(); 102 struct MoreDerived : A, Derived { int z; }; 103 // CHECK: define weak_odr void @_Z1fIXtl1DmcM7DerivedKiadL_ZN11MoreDerived1zEEn8EEEEvv 104 // MSABI-FIXME: define {{.*}} @"??$f@$2UD@@PERDerived@@H0BI@H0A@@@@YAXXZ" 105 template void f<D{(int Derived::*)&MoreDerived::z}>(); 106 #endif 107 108 // FIXME: Pointers to member functions. 109 110 union E { 111 int n; 112 float f; 113 constexpr E() {} 114 constexpr E(int n) : n(n) {} 115 constexpr E(float f) : f(f) {} 116 }; 117 template<E> void f() {} 118 119 // Union members. 120 // CHECK: define weak_odr void @_Z1fIXL1EEEEvv( 121 // FIXME: MSVC rejects this; check this is the mangling MSVC uses when they 122 // start accepting. 123 // MSABI: define {{.*}} @"??$f@$2TE@@@@@YAXXZ" 124 template void f<E{}>(); 125 // CHECK: define weak_odr void @_Z1fIXtl1EEEEvv( 126 // MSABI: define {{.*}} @"??$f@$2TE@@H0A@@@@YAXXZ" 127 template void f<E(0)>(); 128 // CHECK: define weak_odr void @_Z1fIXtl1Edi1nLi42EEEEvv( 129 // MSABI: define {{.*}} @"??$f@$2TE@@H0CK@@@@YAXXZ" 130 template void f<E(42)>(); 131 // CHECK: define weak_odr void @_Z1fIXtl1Edi1fLf00000000EEEEvv( 132 // MSABI: define {{.*}} @"??$f@$2TE@@MAA@@@@YAXXZ" 133 template void f<E(0.f)>(); 134 135 // immintrin.h vector types. 136 typedef float __m128 __attribute__((__vector_size__(16))); 137 typedef double __m128d __attribute__((__vector_size__(16))); 138 typedef long long __m128i __attribute__((__vector_size__(16))); 139 struct M128 { __m128 a; }; 140 struct M128D { __m128d b; }; 141 struct M128I { __m128i c; }; 142 template<M128> void f() {} 143 template<M128D> void f() {} 144 template<M128I> void f() {} 145 // MSABI: define {{.*}} @"??$f@$2UM128@@2T__m128@@3MADPIAAAAA@@AEAAAAAAA@@AEAEAAAAA@@AEAIAAAAA@@@@@@@YAXXZ" 146 template void f<M128{1, 2, 3, 4}>(); 147 // MSABI: define {{.*}} @"??$f@$2UM128D@@2U__m128d@@3NBDPPAAAAAAAAAAAAA@@BEAAAAAAAAAAAAAAA@@@@@@@YAXXZ" 148 template void f<M128D{1, 2}>(); 149 // FIXME: We define __m128i as a vector of long long, whereas MSVC appears to 150 // mangle it as if it were a vector of char. 151 // MSABI-FIXME: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3D00@01@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@@@@@@YAXXZ" 152 // MSABI: define {{.*}} @"??$f@$2UM128I@@2T__m128i@@3_J00@01@@@@@@YAXXZ" 153 template void f<M128I{1, 2}>(); 154 155 // Extensions, and dropping trailing zero-initialized elements of 'tl' 156 // manglings. 157 typedef int __attribute__((ext_vector_type(3))) VI3; 158 struct F { VI3 v; _Complex int ci; _Complex float cf; }; 159 template<F> void f() {} 160 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000ELf40e00000EEEEEvv 161 // MSABI: define {{.*}} @"??$f@$2UF@@2T?$__vector@H$02@__clang@@3H00@01@02@@@2U?$_Complex@H@3@0304@2U?$_Complex@M@3@AEAMAAAAA@AEAOAAAAA@@@@@YAXXZ" 162 template void f<F{{1, 2, 3}, {4, 5}, {6, 7}}>(); 163 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEtlCfLf40c00000EEEEEvv 164 template void f<F{{1, 2, 3}, {4, 5}, {6, 0}}>(); 165 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4ELi5EEEEEvv 166 template void f<F{{1, 2, 3}, {4, 5}, {0, 0}}>(); 167 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEtlCiLi4EEEEEvv 168 template void f<F{{1, 2, 3}, {4, 0}, {0, 0}}>(); 169 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2ELi3EEEEEvv 170 template void f<F{{1, 2, 3}, {0, 0}, {0, 0}}>(); 171 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1ELi2EEEEEvv 172 template void f<F{{1, 2, 0}, {0, 0}, {0, 0}}>(); 173 // CHECK: define weak_odr void @_Z1fIXtl1FtlDv3_iLi1EEEEEvv 174 template void f<F{{1, 0, 0}, {0, 0}, {0, 0}}>(); 175 // CHECK: define weak_odr void @_Z1fIXtl1FEEEvv 176 // MSABI: define {{.*}} @"??$f@$2UF@@2T?$__vector@H$02@__clang@@3H0A@@0A@@0A@@@@2U?$_Complex@H@3@0A@0A@@2U?$_Complex@M@3@AA@AA@@@@@YAXXZ" 177 template void f<F{{0, 0, 0}, {0, 0}, {0, 0}}>(); 178 179 // Unnamed bit-fields. 180 struct G { 181 int : 3; 182 int a : 4; 183 int : 5; 184 int b : 6; 185 int : 7; 186 }; 187 template<G> void f() {} 188 // CHECK: define weak_odr void @_Z1fIXtl1GEEEvv 189 // MSABI: define {{.*}} @"??$f@$2UG@@H0A@H0A@@@@YAXXZ" 190 template void f<(G())>(); 191 // CHECK: define weak_odr void @_Z1fIXtl1GLi1EEEEvv 192 // MSABI: define {{.*}} @"??$f@$2UG@@H00H0A@@@@YAXXZ" 193 template void f<G{1}>(); 194 // CHECK: define weak_odr void @_Z1fIXtl1GLi1ELi2EEEEvv 195 // MSABI: define {{.*}} @"??$f@$2UG@@H00H01@@@YAXXZ" 196 template void f<G{1, 2}>(); 197 // CHECK: define weak_odr void @_Z1fIXtl1GLin8ELin32EEEEvv 198 // MSABI: define {{.*}} @"??$f@$2UG@@H0?7H0?CA@@@@YAXXZ" 199 template void f<G{-8, -32}>(); 200 201 // Empty and nearly-empty unions. 202 // Some of the MSVC manglings here are our invention, because MSVC rejects, but 203 // seem likely to be right. 204 union H1 {}; 205 union H2 { int : 1, : 2, : 3; }; 206 union H3 { int : 1, a, : 2, b, : 3; }; 207 struct H4 { H2 h2; }; 208 template<H1> void f() {} 209 template<H2> void f() {} 210 template<H3> void f() {} 211 template<H4> void f() {} 212 // CHECK: define weak_odr void @_Z1fIXL2H1EEEvv 213 // MSABI: define {{.*}} @"??$f@$2TH1@@@@@YAXXZ" 214 template void f<H1{}>(); 215 // CHECK: define weak_odr void @_Z1fIXL2H2EEEvv 216 // MSABI: define {{.*}} @"??$f@$2TH2@@@@@YAXXZ" 217 template void f<H2{}>(); 218 // CHECK: define weak_odr void @_Z1fIXtl2H3EEEvv 219 // MSABI: define {{.*}} @"??$f@$2TH3@@H0A@@@@YAXXZ" 220 template void f<H3{.a = 0}>(); 221 // CHECK: define weak_odr void @_Z1fIXtl2H3di1aLi1EEEEvv 222 // MSABI: define {{.*}} @"??$f@$2TH3@@H00@@@YAXXZ" 223 template void f<H3{.a = 1}>(); 224 // FIXME: Leads to mangling collision under MS ABI; same mangling as the {.a = 0} case. 225 #ifndef _WIN32 226 // CHECK: define weak_odr void @_Z1fIXtl2H3di1bLi0EEEEvv 227 template void f<H3{.b = 0}>(); 228 #endif 229 // CHECK: define weak_odr void @_Z1fIXtl2H4EEEvv 230 // MSABI: define {{.*}} @"??$f@$2UH4@@2TH2@@@@@@YAXXZ" 231 template void f<H4{}>(); 232 233 // Floating-point. 234 struct I { 235 float f; 236 double d; 237 long double ld; 238 }; 239 template<I> void f() {} 240 // CHECK: define weak_odr void @_Z1fIXtl1IEEEvv 241 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OBA@@@@YAXXZ" 242 template void f<I{0.0, 0.0, 0.0}>(); 243 // CHECK: define weak_odr void @_Z1fIXtl1ILf80000000ELd8000000000000000ELe80000000000000000000EEEEvv 244 // MSABI: define {{.*}} @"??$f@$2UI@@MAIAAAAAAA@NBIAAAAAAAAAAAAAAA@OBIAAAAAAAAAAAAAAA@@@@YAXXZ" 245 template void f<I{-0.0, -0.0, -0.0}>(); 246 // CHECK: define weak_odr void @_Z1fIXtl1ILf3f800000ELd4000000000000000ELec000c000000000000000EEEEvv 247 // MSABI: define {{.*}} @"??$f@$2UI@@MADPIAAAAA@NBEAAAAAAAAAAAAAAA@OBMAAIAAAAAAAAAAAA@@@@YAXXZ" 248 template void f<I{1.0, 2.0, -3.0}>(); 249 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000000ELe3bcd8000000000000000EEEEvv 250 // Note that "small integer" special-case manglings 'A@', '0', '1', ... are 251 // used here and represent tiny denormal values! 252 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NBA@OB0@@@YAXXZ" 253 template void f<I{0.0, 0.2e-323, 0.5e-323}>(); 254 // CHECK: define {{.*}} @_Z1fIXtl1ILf00000000ELd0000000000000002ELebbce8000000000000000EEEEvv 255 // ... but the special-case '?' mangling for bit 63 being set is not used. 256 // MSABI: define {{.*}} @"??$f@$2UI@@MAA@NB1OBIAAAAAAAAAAAAAAC@@@@YAXXZ" 257 template void f<I{0.0, 1.0e-323, -1.0e-323}>(); 258 259 // Base classes and members of class type. 260 struct J1 { int a, b; }; 261 struct JEmpty {}; 262 struct J2 { int c, d; }; 263 struct J : J1, JEmpty, J2 { int e; }; 264 template<J> void f() {} 265 // CHECK: define weak_odr void @_Z1fIXtl1JEEEvv 266 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H0A@H0A@@2UJEmpty@@@2UJ2@@H0A@H0A@@H0A@@@@YAXXZ" 267 template void f<J{}>(); 268 // CHECK: define weak_odr void @_Z1fIXtl1Jtl2J1Li1ELi2EEtl6JEmptyEtl2J2Li3ELi4EELi5EEEEvv 269 // MSABI: define {{.*}} @"??$f@$2UJ@@2UJ1@@H00H01@2UJEmpty@@@2UJ2@@H02H03@H04@@@YAXXZ" 270 template void f<J{{1, 2}, {}, {3, 4}, 5}>(); 271 272 struct J3 { J1 j1; }; 273 template<J3> void f() {} 274 // CHECK: define {{.*}} @_Z1fIXtl2J3tl2J1Li1ELi2EEEEEvv 275 // MSABI: define {{.*}} @"??$f@$2UJ3@@2UJ1@@H00H01@@@@YAXXZ" 276 template void f<J3{1, 2}>(); 277 278 // Arrays. 279 struct K { int n[2][3]; }; 280 template<K> void f() {} 281 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2EEEEEEvv 282 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@0A@@@@3H0A@@0A@@0A@@@@@@@@YAXXZ" 283 template void f<K{1, 2}>(); 284 // CHECK: define {{.*}} @_Z1fIXtl1KtlA2_A3_itlS1_Li1ELi2ELi3EEtlS1_Li4ELi5ELi6EEEEEEvv 285 // MSABI: define {{.*}} @"??$f@$2UK@@3$$BY02H3H00@01@02@@@3H03@04@05@@@@@@@YAXXZ" 286 template void f<K{1, 2, 3, 4, 5, 6}>(); 287 288 struct K1 { int a, b; }; 289 struct K2 : K1 { int c; }; 290 struct K3 { K2 k2[2]; }; 291 template<K3> void f() {} 292 // CHECK: define {{.*}} @_Z1fIXtl2K3tlA2_2K2tlS1_tl2K1Li1EEEEEEEvv 293 // MSABI: define {{.*}} @"??$f@$2UK3@@3UK2@@2U2@2UK1@@H00H0A@@H0A@@@2U2@2U3@H0A@H0A@@H0A@@@@@@@YAXXZ" 294 template void f<K3{1}>(); 295 template void f<K3{1, 2, 3, 4, 5, 6}>(); 296 297 namespace CvQualifiers { 298 struct A { const int a; int *const b; int c; }; 299 template<A> void f() {} 300 // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1AELi0ELPi0ELi1EEEEEvv 301 // MSABI: define {{.*}} @"??$f@$2UA@CvQualifiers@@$$CBH0A@QEAH0A@H00@@CvQualifiers@@YAXXZ" 302 template void f<A{.c = 1}>(); 303 304 using T1 = const int; 305 using T2 = T1[5]; 306 using T3 = const T2; 307 struct B { T3 arr; }; 308 template<B> void f() {} 309 // CHECK: define {{.*}} @_ZN12CvQualifiers1fIXtlNS_1BEtlA5_iLi1ELi2ELi3ELi4ELi5EEEEEEvv 310 // MSABI: define {{.*}} @"??$f@$2UB@CvQualifiers@@3$$CBH00@01@02@03@04@@@@CvQualifiers@@YAXXZ" 311 template void f<B{1, 2, 3, 4, 5}>(); 312 } 313 314 struct L { 315 signed char a = -1; 316 unsigned char b = -1; 317 short c = -1; 318 unsigned short d = -1; 319 int e = -1; 320 unsigned int f = -1; 321 long g = -1; 322 unsigned long h = -1; 323 long long i = -1; 324 unsigned long long j = -1; 325 }; 326 template<L> void f() {} 327 // CHECK: define {{.*}} @_Z1fIXtl1LLan1ELh255ELsn1ELt65535ELin1ELj4294967295ELln1ELm18446744073709551615ELxn1ELy18446744073709551615EEEEvv 328 // MSABI: define {{.*}} @"??$f@$2UL@@C0?0E0PP@F0?0G0PPPP@H0?0I0PPPPPPPP@J0?0K0PPPPPPPP@_J0?0_K0?0@@@YAXXZ" 329 template void f<L{}>(); 330 331 // Template parameter objects. 332 struct M { int n; }; 333 template<M a> constexpr const M &f() { return a; } 334 // CHECK: define {{.*}} @_Z1fIXtl1MLi42EEEERKS0_v 335 // CHECK: ret {{.*}} @_ZTAXtl1MLi42EEE 336 // MSABI: define {{.*}} @"??$f@$2UM@@H0CK@@@@YAAEBUM@@XZ" 337 // MSABI: ret {{.*}} @"??__N2UM@@H0CK@@@" 338 template const M &f<M{42}>(); 339 340 template<const M *p> void g() {} 341 // CHECK: define {{.*}} @_Z1gIXadL_ZTAXtl1MLi10EEEEEEvv 342 // MSABI: define {{.*}} @"??$g@$1??__N2UM@@H09@@@@YAXXZ" 343 template void g<&f<M{10}>()>(); 344