1// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++11 | FileCheck %s 2struct X { }; 3struct Y { }; 4 5// CHECK: @unmangled_variable = global 6// CHECK: @_ZN1N1iE = global 7// CHECK: @_ZZN1N1fEiiE1b = internal global 8// CHECK: @_ZZN1N1gEvE1a = internal global 9// CHECK: @_ZGVZN1N1gEvE1a = internal global 10 11//CHECK: @pr5966_i = external global 12//CHECK: @_ZL8pr5966_j = internal global 13 14// CHECK-LABEL: define zeroext i1 @_ZplRK1YRA100_P1X 15bool operator+(const Y&, X* (&xs)[100]) { return false; } 16 17// CHECK-LABEL: define void @_Z1f1s 18typedef struct { int a; } s; 19void f(s) { } 20 21// CHECK-LABEL: define void @_Z1f1e 22typedef enum { foo } e; 23void f(e) { } 24 25// CHECK-LABEL: define void @_Z1f1u 26typedef union { int a; } u; 27void f(u) { } 28 29// CHECK-LABEL: define void @_Z1f1x 30typedef struct { int a; } x,y; 31void f(y) { } 32 33// CHECK-LABEL: define void @_Z1fv 34void f() { } 35 36// CHECK-LABEL: define void @_ZN1N1fEv 37namespace N { void f() { } } 38 39// CHECK-LABEL: define void @_ZN1N1N1fEv 40namespace N { namespace N { void f() { } } } 41 42// CHECK-LABEL: define void @unmangled_function 43extern "C" { namespace N { void unmangled_function() { } } } 44 45extern "C" { namespace N { int unmangled_variable = 10; } } 46 47namespace N { int i; } 48 49namespace N { int f(int, int) { static int b; return b; } } 50 51namespace N { int h(); void g() { static int a = h(); } } 52 53// CHECK-LABEL: define void @_Z1fno 54void f(__int128_t, __uint128_t) { } 55 56template <typename T> struct S1 {}; 57 58// CHECK-LABEL: define void @_Z1f2S1IiE 59void f(S1<int>) {} 60 61// CHECK-LABEL: define void @_Z1f2S1IdE 62void f(S1<double>) {} 63 64template <int N> struct S2 {}; 65// CHECK-LABEL: define void @_Z1f2S2ILi100EE 66void f(S2<100>) {} 67 68// CHECK-LABEL: define void @_Z1f2S2ILin100EE 69void f(S2<-100>) {} 70 71template <bool B> struct S3 {}; 72 73// CHECK-LABEL: define void @_Z1f2S3ILb1EE 74void f(S3<true>) {} 75 76// CHECK-LABEL: define void @_Z1f2S3ILb0EE 77void f(S3<false>) {} 78 79struct S; 80 81// CHECK-LABEL: define void @_Z1fM1SKFvvE 82void f(void (S::*)() const) {} 83 84// CHECK-LABEL: define void @_Z1fM1SFvvE 85void f(void (S::*)()) {} 86 87// CHECK-LABEL: define void @_Z1fi 88void f(const int) { } 89 90template<typename T, typename U> void ft1(U u, T t) { } 91 92template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { } 93 94template<typename T, typename U = S1<T> > struct S4 { }; 95template<typename T> void ft3(S4<T>*) { } 96 97namespace NS { 98 template<typename T> void ft1(T) { } 99} 100 101void g1() { 102 // CHECK: @_Z3ft1IidEvT0_T_ 103 ft1<int, double>(1, 0); 104 105 // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_ 106 ft2<char>(1, 0, 0); 107 108 // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE 109 ft3<int>(0); 110 111 // CHECK: @_ZN2NS3ft1IiEEvT_ 112 NS::ft1<int>(1); 113} 114 115// Expressions 116template<int I> struct S5 { }; 117 118template<int I> void ft4(S5<I>) { } 119void g2() { 120 // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE 121 ft4(S5<10>()); 122 123 // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE 124 ft4(S5<20>()); 125} 126 127extern "C++" { 128 // CHECK: @_Z1hv 129 void h() { } 130} 131 132// PR5019 133extern "C" { struct a { int b; }; } 134 135// CHECK: @_Z1fP1a 136int f(struct a *x) { 137 return x->b; 138} 139 140// PR5017 141extern "C" { 142struct Debug { 143 const Debug& operator<< (unsigned a) const { return *this; } 144}; 145Debug dbg; 146// CHECK: @_ZNK5DebuglsEj 147int main(void) { dbg << 32 ;} 148} 149 150template<typename T> struct S6 { 151 typedef int B; 152}; 153 154template<typename T> void ft5(typename S6<T>::B) { } 155// CHECK: @_Z3ft5IiEvN2S6IT_E1BE 156template void ft5<int>(int); 157 158template<typename T> class A {}; 159 160namespace NS { 161template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; } 162} 163 164// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_ 165template bool NS::operator==(const ::A<char>&, const ::A<char>&); 166 167namespace std { 168template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; } 169} 170 171// CHECK: @_ZSteqIcEbRK1AIT_ES4_ 172template bool std::operator==(const ::A<char>&, const ::A<char>&); 173 174struct S { 175 typedef int U; 176}; 177 178template <typename T> typename T::U ft6(const T&) { return 0; } 179 180// CHECK: @_Z3ft6I1SENT_1UERKS1_ 181template int ft6<S>(const S&); 182 183template<typename> struct __is_scalar_type { 184 enum { __value = 1 }; 185}; 186 187template<bool, typename> struct __enable_if { }; 188 189template<typename T> struct __enable_if<true, T> { 190 typedef T __type; 191}; 192 193// PR5063 194template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { } 195 196// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv 197template void ft7<int>(); 198// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv 199template void ft7<void*>(); 200 201// PR5144 202extern "C" { 203void extern_f(void); 204}; 205 206// CHECK: @extern_f 207void extern_f(void) { } 208 209struct S7 { 210 S7(); 211 212 struct S { S(); }; 213 struct { 214 S s; 215 } a; 216}; 217 218// PR5139 219// CHECK: @_ZN2S7C2Ev 220// CHECK: @_ZN2S7Ut_C1Ev 221// CHECK: @_ZN2S7C1Ev 222S7::S7() {} 223 224// PR5063 225template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { } 226// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv 227template void ft8<int>(); 228// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv 229template void ft8<void*>(); 230 231// PR5796 232namespace PR5796 { 233template<typename> struct __is_scalar_type { 234 enum { __value = 0 }; 235}; 236 237template<bool, typename> struct __enable_if {}; 238template<typename T> struct __enable_if<true, T> { typedef T __type; }; 239template<typename T> 240 241// CHECK-LABEL: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv 242typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { }; 243 244void f() { __fill_a<int>(); } 245} 246 247namespace Expressions { 248// Unary operators. 249 250// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i 251template <int i> void f1(int (*)[(-i) + 2]) { }; 252template void f1<1>(int (*)[1]); 253 254// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i 255template <int i> void f2(int (*)[+i]) { }; 256template void f2<1>(int (*)[1]); 257 258// Binary operators. 259 260// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i 261template <int i> void f3(int (*)[i+i]) { }; 262template void f3<1>(int (*)[2]); 263 264// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i 265template <int i> void f4(int (*)[2 + i+i]) { }; 266template void f4<1>(int (*)[4]); 267 268// The ternary operator. 269// CHECK-LABEL: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i 270template <bool b> void f4(int (*)[b ? 1 : 2]) { }; 271template void f4<true>(int (*)[1]); 272} 273 274struct Ops { 275 Ops& operator+(const Ops&); 276 Ops& operator-(const Ops&); 277 Ops& operator&(const Ops&); 278 Ops& operator*(const Ops&); 279 280 void *v; 281}; 282 283// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsplERKS_ 284Ops& Ops::operator+(const Ops&) { return *this; } 285// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmiERKS_ 286Ops& Ops::operator-(const Ops&) { return *this; } 287// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsanERKS_ 288Ops& Ops::operator&(const Ops&) { return *this; } 289// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmlERKS_ 290Ops& Ops::operator*(const Ops&) { return *this; } 291 292// PR5861 293namespace PR5861 { 294template<bool> class P; 295template<> class P<true> {}; 296 297template<template <bool> class, bool> 298struct Policy { }; 299 300template<typename T, typename = Policy<P, true> > class Alloc 301{ 302 T *allocate(int, const void*) { return 0; } 303}; 304 305// CHECK-LABEL: define weak_odr i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv 306template class Alloc<char>; 307} 308 309// CHECK-LABEL: define void @_Z1fU13block_pointerFiiiE 310void f(int (^)(int, int)) { } 311 312void pr5966_foo() { 313 extern int pr5966_i; 314 pr5966_i = 0; 315} 316 317static int pr5966_j; 318 319void pr5966_bar() { 320 pr5966_j = 0; 321} 322 323namespace test0 { 324 int ovl(int x); 325 char ovl(double x); 326 327 template <class T> void f(T, char (&buffer)[sizeof(ovl(T()))]) {} 328 329 void test0() { 330 char buffer[1]; 331 f(0.0, buffer); 332 } 333 // CHECK-LABEL: define void @_ZN5test05test0Ev() 334 // CHECK-LABEL: define linkonce_odr void @_ZN5test01fIdEEvT_RAszcl3ovlcvS1__EE_c( 335 336 void test1() { 337 char buffer[sizeof(int)]; 338 f(1, buffer); 339 } 340 // CHECK-LABEL: define void @_ZN5test05test1Ev() 341 // CHECK-LABEL: define linkonce_odr void @_ZN5test01fIiEEvT_RAszcl3ovlcvS1__EE_c( 342 343 template <class T> void g(char (&buffer)[sizeof(T() + 5.0f)]) {} 344 void test2() { 345 char buffer[sizeof(float)]; 346 g<float>(buffer); 347 } 348 // CHECK-LABEL: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40a00000E_c( 349 350 template <class T> void h(char (&buffer)[sizeof(T() + 5.0)]) {} 351 void test3() { 352 char buffer[sizeof(double)]; 353 h<float>(buffer); 354 } 355 // CHECK-LABEL: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c( 356 357 template <class T> void j(char (&buffer)[sizeof(T().buffer)]) {} 358 struct A { double buffer[128]; }; 359 void test4() { 360 char buffer[1024]; 361 j<A>(buffer); 362 } 363 // CHECK-LABEL: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszdtcvT__E6buffer_c( 364 365 template <class T> void k(char (&buffer)[sizeof(T() + 0.0f)]) {} 366 void test5() { 367 char buffer[sizeof(float)]; 368 k<float>(buffer); 369 } 370 // CHECK-LABEL: define linkonce_odr void @_ZN5test01kIfEEvRAszplcvT__ELf00000000E_c( 371 372} 373 374namespace test1 { 375 template<typename T> struct X { }; 376 template<template<class> class Y, typename T> void f(Y<T>) { } 377 // CHECK-LABEL: define weak_odr void @_ZN5test11fINS_1XEiEEvT_IT0_E 378 template void f(X<int>); 379} 380 381// CHECK-LABEL: define internal void @_ZL27functionWithInternalLinkagev() 382static void functionWithInternalLinkage() { } 383void g() { functionWithInternalLinkage(); } 384 385namespace test2 { 386 template <class T> decltype(((T*) 0)->member) read_member(T& obj) { 387 return obj.member; 388 } 389 390 struct A { int member; } obj; 391 int test() { 392 return read_member(obj); 393 } 394 395 // CHECK-LABEL: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_( 396} 397 398// rdar://problem/9280586 399namespace test3 { 400 struct AmbiguousBase { int ab; }; 401 struct Path1 : AmbiguousBase { float p; }; 402 struct Path2 : AmbiguousBase { double p; }; 403 struct Derived : Path1, Path2 { }; 404 405 // CHECK-LABEL: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E2abERS2_( 406 template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; } 407 408 // CHECK-LABEL: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E2abERS2_( 409 template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; } 410 411 // CHECK-LABEL: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E1pERS2_( 412 template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; } 413 414 // CHECK-LABEL: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E1pERS2_( 415 template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; } 416 417 Derived obj; 418 void test() { 419 get_ab_1(obj); 420 get_ab_2(obj); 421 get_p_1(obj); 422 get_p_2(obj); 423 } 424} 425 426// CHECK-LABEL: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE 427namespace test4 { 428 struct foo { int bar; }; 429 template <int (foo::*)> 430 struct zed {}; 431 void g(zed<&foo::bar>*) 432 {} 433} 434// CHECK-LABEL: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE 435namespace test5 { 436 struct foo { static int bar; }; 437 template <int *> 438 struct zed {}; 439 void g(zed<&foo::bar>*) 440 {} 441} 442// CHECK-LABEL: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE 443namespace test6 { 444 struct foo { int bar(); }; 445 template <int (foo::*)()> 446 struct zed {}; 447 void g(zed<&foo::bar>*) 448 {} 449} 450// CHECK-LABEL: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE 451namespace test7 { 452 struct foo { static int bar(); }; 453 template <int (*f)()> 454 struct zed {}; 455 void g(zed<&foo::bar>*) 456 {} 457} 458// CHECK-LABEL: define weak_odr void @_ZN5test81AIL_ZNS_1B5valueEEE3incEv 459namespace test8 { 460 template <int &counter> class A { void inc() { counter++; } }; 461 class B { public: static int value; }; 462 template class A<B::value>; 463} 464// CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE 465namespace test9 { 466 template<class T> 467 struct foo { 468 typedef T X; 469 }; 470 struct bar { 471 typedef foo<int> baz; 472 }; 473 template <class zaz, class zed> 474 void f(const typename zed::baz::X&); 475 void g() { 476 f<int, bar>( 0); 477 } 478} 479 480// <rdar://problem/7825453> 481namespace test10 { 482 template <char P1> struct S {}; 483 template <char P2> void f(struct S<false ? 'a' : P2> ) {} 484 485 // CHECK-LABEL: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE( 486 template void f<(char) 3>(struct S<3>); 487} 488 489namespace test11 { 490 // CHECK: @_ZN6test111fEz 491 void f(...) { } 492 493 struct A { 494 void f(...); 495 }; 496 497 // CHECK: @_ZN6test111A1fEz 498 void A::f(...) { } 499} 500 501namespace test12 { 502 503 // CHECK: _ZN6test121fENS_1AILt33000EEE 504 template <unsigned short> struct A { }; 505 void f(A<33000>) { } 506} 507 508// PR7446 509namespace test13 { 510 template <template <class> class T> class A {}; 511 template <class U> class B {}; 512 513 template <template<class> class T> void foo(const A<T> &a) {} 514 515 // CHECK-LABEL: define weak_odr void @_ZN6test133fooINS_1BEEEvRKNS_1AIT_EE( 516 template void foo(const A<B> &a); 517} 518 519namespace test14 { 520 extern "C" { 521 struct S { 522 static int a(), x; 523 }; 524 // CHECK-LABEL: define i32 @_ZN6test141S1aEv 525 // CHECK: load i32, i32* @_ZN6test141S1xE 526 int S::a() { return S::x; } 527 } 528} 529 530// rdar://problem/8204122 531namespace test15 { 532 enum E { e = 3 }; 533 template <int I> struct S {}; 534 535 template <int I> void f(S<I + e>) {} 536 537 // CHECK-LABEL: define weak_odr void @_ZN6test151fILi7EEEvNS_1SIXplT_LNS_1EE3EEEE( 538 template void f<7>(S<7 + e>); 539} 540 541// rdar://problem/8302148 542namespace test17 { 543 template <int N> struct A {}; 544 545 struct B { 546 static int foo(void); 547 }; 548 549 template <class T> A<sizeof(T::foo())> func(void); 550 551 // CHECK-LABEL: define void @_ZN6test174testEv() 552 // CHECK: call {{.*}} @_ZN6test174funcINS_1BEEENS_1AIXszclsrT_3fooEEEEv() 553 void test() { 554 func<B>(); 555 } 556} 557 558// PR7891 559namespace test18 { 560 struct A { 561 int operator+(); 562 int operator-(); 563 int operator*(); 564 int operator&(); 565 }; 566 template <int (A::*)()> struct S {}; 567 568 template <typename T> void f(S<&T::operator+>) {} 569 template void f<A>(S<&A::operator+>); 570 571 template <typename T> void f(S<&T::operator- >) {} 572 template void f<A>(S<&A::operator- >); 573 574 template <typename T> void f(S<&T::operator*>) {} 575 template void f<A>(S<&A::operator*>); 576 577 template <typename T> void f(S<&T::operator&>) {} 578 template void f<A>(S<&A::operator&>); 579 580 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onplEEE 581 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmiEEE 582 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmlEEE 583 // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onanEEE 584} 585 586// rdar://problem/8332117 587namespace test19 { 588 struct A { 589 template <typename T> int f(); 590 int operator+(); 591 operator int(); 592 template <typename T> int operator-(); 593 }; 594 595 template <int (A::*)()> struct S {}; 596 597 template <typename T> void g (S<&T::template f<int> >) {} 598 template <typename T> void g (S<&T::operator+ >) {} 599 template <typename T> void g (S<&T::operator int>) {} 600 template <typename T> void g (S<&T::template operator- <double> >) {} 601 602 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE( 603 template void g<A>(S<&A::f<int> >); 604 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onplEEE( 605 template void g<A>(S<&A::operator+>); 606 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_oncviEEE( 607 template void g<A>(S<&A::operator int>); 608 // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onmiIdEEEE( 609 template void g<A>(S<&A::operator-<double> >); 610} 611 612namespace test20 { 613 template <class T> T *f(const T&); 614 template <class T> T *f(T*); 615 616 // CHECK-LABEL: define weak_odr void @_ZN6test205test0IiEEvDTcl1fIPT_ELi0EEE( 617 template <class T> void test0(decltype(f<T*>(0))) {} 618 template void test0<int>(decltype(f<int*>(0))); 619 620 // CHECK-LABEL: define weak_odr void @_ZN6test205test1IiEEvDTcl1fIEcvT__EEE( 621 template <class T> void test1(decltype(f<>(T()))) {} 622 template void test1<int>(decltype(f<>(int()))); 623} 624 625// rdar:// 8620510 626namespace test21 { 627 // CHECK-LABEL: define void @_ZN6test2112vla_arg_funcEiPA_i( 628 void vla_arg_func(int X, int a[X][X]) {} 629} 630 631namespace test22 { 632 // CHECK-LABEL: define void @_ZN6test221fEDn( 633 void f(decltype(nullptr)) { } 634} 635 636// rdar://problem/8913416 637namespace test23 { 638 typedef void * const vpc; 639 640 // CHECK-LABEL: define void @_ZN6test231fERA10_KPv( 641 void f(vpc (&)[10]) {} 642 643 typedef vpc vpca5[5]; 644 void f(vpca5 volatile (&)[10]) {} 645 // CHECK-LABEL: define void @_ZN6test231fERA10_A5_VKPv( 646} 647 648namespace test24 { 649 void test0() { 650 extern int foo(); 651 // CHECK: call i32 @_ZN6test243fooEv() 652 foo(); 653 } 654 655 static char bar() {} 656 void test1() { 657 // CHECK: call signext i8 @_ZN6test24L3barEv() 658 bar(); 659 } 660} 661 662// rdar://problem/8806641 663namespace test25 { 664 template <void (*fn)()> struct A { 665 static void call() { fn(); } 666 }; 667 void foo(); 668 void test() { 669 // CHECK: call void @_ZN6test251AIXadL_ZNS_3fooEvEEE4callEv() 670 A<foo>::call(); 671 } 672} 673 674namespace test26 { 675 template <template <class> class T> void foo(decltype(T<float>::object) &object) {} 676 677 template <class T> struct holder { static T object; }; 678 679 void test() { 680 float f; 681 682 // CHECK: call void @_ZN6test263fooINS_6holderEEEvRDtsrT_IfE6objectE( 683 foo<holder>(f); 684 } 685} 686 687namespace test27 { 688 struct A { 689 struct inner { 690 float object; 691 }; 692 693 float meth(); 694 }; 695 typedef A Alias; 696 697 template <class T> void a(decltype(T::inner::object) &object) {} 698 template <class T> void b(decltype(T().Alias::meth()) &object) {} 699 700 void test() { 701 float f; 702 // CHECK: call void @_ZN6test271aINS_1AEEEvRDtsrNT_5innerE6objectE( 703 a<A>(f); 704 // CHECK: call void @_ZN6test271bINS_1AEEEvRDTcldtcvT__Esr5AliasE4methEE( 705 b<A>(f); 706 } 707} 708 709// An injected class name type in a unresolved-name. 710namespace test28 { 711 template <class T> struct A { 712 enum { bit }; 713 }; 714 715 template <class T> void foo(decltype(A<T>::A::bit) x); 716 717 void test() { 718 foo<char>(A<char>::bit); 719 // CHECK: call void @_ZN6test283fooIcEEvDtsr1AIT_E1AE3bitE( 720 } 721} 722 723// An enclosing template type parameter in an unresolved-name. 724namespace test29 { 725 template <class T> struct A { 726 template <class U> static void foo(decltype(T::fn(U())) x); 727 }; 728 struct B { static int fn(int); static long fn(long); }; 729 730 void test() { 731 A<B>::foo<int>(0); 732 // CHECK: call void @_ZN6test291AINS_1BEE3fooIiEEvDTclsrS1_2fncvT__EEE( 733 } 734} 735 736// An enclosing template template parameter in an unresolved-name. 737namespace test30 { 738 template <template <class> class T> struct A { 739 template <class U> static void foo(decltype(T<U>::fn()) x); 740 }; 741 template <class T> struct B { static T fn(); }; 742 743 void test() { 744 A<B>::foo<int>(0); 745 // CHECK: call void @_ZN6test301AINS_1BEE3fooIiEEvDTclsrS1_IT_EE2fnEE( 746 } 747} 748 749namespace test31 { // instantiation-dependent mangling of decltype 750 int x; 751 template<class T> auto f1(T p)->decltype(x) { return 0; } 752 // The return type in the mangling of the template signature 753 // is encoded as "i". 754 template<class T> auto f2(T p)->decltype(p) { return 0; } 755 // The return type in the mangling of the template signature 756 // is encoded as "Dtfp_E". 757 void g(int); 758 template<class T> auto f3(T p)->decltype(g(p)) {} 759 760 // CHECK-LABEL: define weak_odr i32 @_ZN6test312f1IiEEiT_( 761 template int f1(int); 762 // CHECK-LABEL: define weak_odr i32 @_ZN6test312f2IiEEDtfp_ET_ 763 template int f2(int); 764 // CHECK-LABEL: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_ 765 template void f3(int); 766} 767 768// PR10205 769namespace test32 { 770 template<typename T, int=T::value> struct A { 771 typedef int type; 772 }; 773 struct B { enum { value = 4 }; }; 774 775 template <class T> typename A<T>::type foo() { return 0; } 776 void test() { 777 foo<B>(); 778 // CHECK: call i32 @_ZN6test323fooINS_1BEEENS_1AIT_XsrS3_5valueEE4typeEv() 779 } 780} 781 782namespace test33 { 783 template <class T> struct X { 784 enum { value = T::value }; 785 }; 786 787 template<typename T, int=X<T>::value> struct A { 788 typedef int type; 789 }; 790 struct B { enum { value = 4 }; }; 791 792 template <class T> typename A<T>::type foo() { return 0; } 793 794 void test() { 795 foo<B>(); 796 // CHECK: call i32 @_ZN6test333fooINS_1BEEENS_1AIT_Xsr1XIS3_EE5valueEE4typeEv() 797 } 798} 799 800namespace test34 { 801 // Mangling for instantiation-dependent decltype expressions. 802 template<typename T> 803 void f(decltype(sizeof(decltype(T() + T())))) {} 804 805 // CHECK-LABEL: define weak_odr void @_ZN6test341fIiEEvDTstDTplcvT__EcvS1__EEE 806 template void f<int>(decltype(sizeof(1))); 807 808 // Mangling for non-instantiation-dependent sizeof expressions. 809 template<unsigned N> 810 void f2(int (&)[N + sizeof(int*)]) {} 811 812 // CHECK-LABEL: define weak_odr void @_ZN6test342f2ILj4EEEvRAplT_Lm8E_i 813 template void f2<4>(int (&)[4 + sizeof(int*)]); 814 815 // Mangling for non-instantiation-dependent sizeof expressions 816 // involving an implicit conversion of the result of the sizeof. 817 template<unsigned long long N> 818 void f3(int (&)[N + sizeof(int*)]) {} 819 820 // CHECK-LABEL: define weak_odr void @_ZN6test342f3ILy4EEEvRAplT_Ly8E_i 821 template void f3<4>(int (&)[4 + sizeof(int*)]); 822 823 // Mangling for instantiation-dependent sizeof() expressions as 824 // template arguments. 825 template<unsigned> struct A { }; 826 827 template<typename T> void f4(::test34::A<sizeof(sizeof(decltype(T() + T())))>) { } 828 829 // CHECK-LABEL: define weak_odr void @_ZN6test342f4IiEEvNS_1AIXszstDTplcvT__EcvS2__EEEEE 830 template void f4<int>(A<sizeof(sizeof(int))>); 831} 832 833namespace test35 { 834 // Dependent operator names of unknown arity. 835 struct A { 836 template<typename U> A operator+(U) const; 837 }; 838 839 template<typename T> 840 void f1(decltype(sizeof(&T::template operator+<int>))) {} 841 842 // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_onplIiEE 843 template void f1<A>(__SIZE_TYPE__); 844} 845 846namespace test36 { 847 template<unsigned> struct A { }; 848 849 template<typename ...Types> 850 auto f1(Types... values) -> A<sizeof...(values)> { } 851 852 // CHECK: define weak_odr {{.*}} @_ZN6test362f1IJifEEENS_1AIXsZfp_EEEDpT_ 853 template A<2> f1(int, float); 854} 855 856namespace test37 { 857 struct foo { 858 struct { 859 } a; 860 typedef struct { } b; 861 typedef struct { } *c; 862 struct { 863 } d; 864 }; 865 template<typename T> void func(T) { } 866 void test() { 867 // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt_EEEvT_ 868 func(foo().a); 869 // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt0_EEEvT_ 870 func(*foo::c()); 871 // CHECK-LABEL: define linkonce_odr void @_ZN6test374funcINS_3fooUt1_EEEvT_ 872 func(foo().d); 873 } 874} 875 876// CHECK-LABEL: define void @_Z6ASfuncPU3AS3i 877void ASfunc(__attribute__((address_space(3))) int* x) {} 878 879namespace test38 { 880 // CHECK-LABEL: define linkonce_odr void @_ZN6test384funcINS_3fooUt_EEEvT_ 881 typedef struct { 882 struct { 883 } a; 884 } foo; 885 886 template <typename T> void func(T) {} 887 void test() { func(foo().a); } 888} 889 890namespace test39 { 891 // CHECK-LABEL: define internal void @"_ZN6test394funcINS_3$_03$_1EEEvT_" 892 typedef struct { 893 struct {} a; 894 } *foo; 895 template<typename T> void func(T) {} 896 void test(foo x) { 897 func(x->a); 898 } 899} 900 901namespace test40 { 902 // CHECK: i32* {{.*}} @_ZZN6test401fEvE1a_0 903 void h(int&); 904 inline void f() { 905 if (0) { 906 static int a; 907 } 908 static int a; 909 h(a); 910 }; 911 void g() { f(); } 912} 913 914namespace test41 { 915 // CHECK: define linkonce_odr void @_ZN6test414funcINS_1XEEEvNS_3fooILi20ES1_EE 916 template <int i, class T> struct foo { 917 template <class T2 = T> friend void func(foo x) {} 918 }; 919 920 struct X {}; 921 922 void g() { func(foo<20, X>()); } 923} 924 925namespace test42 { 926 // CHECK: define linkonce_odr void @_ZN6test424funcINS_1XEEEvNS_3fooILi20ES1_EE 927 template <int i, template <class> class T> struct foo { 928 template <template <class> class T2 = T> friend void func(foo x) {} 929 }; 930 931 template <class V> struct X { 932 }; 933 934 void g() { func(foo<20, X>()); } 935} 936 937namespace test43 { 938 // CHECK-LABEL: define void @_ZN6test431gEPNS_3zedIXadL_ZNS_3fooUt_3barEEEEE 939 struct foo { union { int bar; }; }; 940 template <int (foo::*)> 941 struct zed {}; 942 void g(zed<&foo::bar>*) 943 {} 944} 945 946namespace test44 { 947 struct foo { void bar() __restrict { }; } obj; 948 949 void f() { 950 obj.bar(); 951 } 952 // CHECK-LABEL: define linkonce_odr void @_ZN6test443foo3barEv(%"struct.test44::foo"* %this) 953} 954 955namespace test45 { 956 struct S { 957 enum e {}; 958 }; 959 template <typename T> 960 void f(enum T::e *) {} 961 template void f<S>(S::e *); 962 // CHECK-LABEL: define weak_odr void @_ZN6test451fINS_1SEEEvPTeNT_1eE(i32*) 963} 964 965namespace test46 { 966 struct S { 967 struct s {}; 968 }; 969 template <typename T> 970 void f(struct T::s *) {} 971 template void f<S>(S::s *); 972 // CHECK-LABEL: define weak_odr void @_ZN6test461fINS_1SEEEvPTsNT_1sE(%"struct.test46::S::s"*) 973} 974 975namespace test47 { 976 struct S { 977 class c {}; 978 }; 979 template <typename T> 980 void f(class T::c *) {} 981 template void f<S>(S::c *); 982 // CHECK-LABEL: define weak_odr void @_ZN6test471fINS_1SEEEvPTsNT_1cE(%"class.test47::S::c"*) 983} 984 985namespace test48 { 986 struct S { 987 union u {}; 988 }; 989 template <typename T> 990 void f(union T::u *) {} 991 template void f<S>(S::u *); 992 // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPTuNT_1uE(%"union.test48::S::u"*) 993} 994 995namespace test49 { 996 template <int> 997 struct S {}; 998 999 template <template <int> class T> 1000 T<3> fin(T<3>); 1001 1002 auto v = fin<S>; 1003 // CHECK-LABEL: declare void @_ZN6test493finINS_1SEEET_ILi3EES3_() 1004} 1005 1006namespace test50 { 1007 template <int> 1008 struct S {}; 1009 1010 template <template <int> class T> 1011 T<3> fin(T<4>); 1012 1013 auto v = fin<S>; 1014 // CHECK-LABEL: declare void @_ZN6test503finINS_1SEEET_ILi3EES2_ILi4EE() 1015} 1016 1017namespace test51 { 1018 template <typename T> 1019 decltype(T().~T()) fun() {} 1020 template void fun<int>(); 1021 // CHECK-LABEL: @_ZN6test513funIiEEDTcldtcvT__EdnS1_EEv 1022 template void fun<X>(); 1023 // CHECK-LABEL: @_ZN6test513funI1XEEDTcldtcvT__EdnS2_EEv 1024 template void fun<S1<int> >(); 1025 // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv 1026 1027 enum E {}; 1028 template <typename T> 1029 struct X { 1030 struct Y {}; 1031 }; 1032 1033 template <typename T> 1034 decltype(S1<T>().~S1<T>()) fun1() {}; 1035 template <typename U, typename T> 1036 decltype(U().~S1<T>()) fun2() {} 1037 template <typename U, typename T> 1038 decltype(S1<T>().~U()) fun3() {} 1039 template <typename T> 1040 decltype(S1<T>().~S1<T>(), S1<T>().~S1<T>()) fun4() {}; 1041 template <typename T> 1042 decltype(S1<int>().~S1<T>()) fun5(){}; 1043 template <template <typename T> class U> 1044 decltype(S1<int>().~U<int>()) fun6(){}; 1045 template <typename T> 1046 decltype(E().E::~T()) fun7() {} 1047 template <template <typename> class U> 1048 decltype(X<int>::Y().U<int>::Y::~Y()) fun8() {} 1049 template void fun1<int>(); 1050 // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv 1051 template void fun2<S1<int>, int>(); 1052 // CHECK-LABEL: @_ZN6test514fun2I2S1IiEiEEDTcldtcvT__Edn2S1IT0_EEEv 1053 template void fun3<S1<int>, int>(); 1054 // CHECK-LABEL: @_ZN6test514fun3I2S1IiEiEEDTcldtcvS1_IT0_E_EdnT_EEv 1055 template void fun4<int>(); 1056 // CHECK-LABEL: @_ZN6test514fun4IiEEDTcmcldtcv2S1IT_E_Edn2S1IS2_EEcldtcvS3__Edn2S1IS2_EEEv 1057 template void fun5<int>(); 1058 // CHECK-LABEL: @_ZN6test514fun5IiEEDTcldtcv2S1IiE_Edn2S1IT_EEEv 1059 template void fun6<S1>(); 1060 // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv 1061 template void fun7<E>(); 1062 // CHECK-LABEL: @_ZN6test514fun7INS_1EEEEDTcldtcvS1__Esr1EEdnT_EEv 1063 template void fun8<X>(); 1064} 1065 1066namespace test52 { 1067struct X {}; 1068void operator+(X); 1069template <typename... T> 1070auto f4(T... x) -> decltype(operator+(x...)); 1071// CHECK-LABEL: @_ZN6test522f4IJNS_1XEEEEDTclonplspfp_EEDpT_ 1072void use() { f4(X{}); } 1073} 1074 1075namespace test53 { 1076struct c { 1077 using t1 = struct { int z; }; 1078 using t2 = struct { double z; }; 1079 using t3 = struct { float z; }; 1080 using t4 = struct { float z; }; 1081 1082 __attribute__((used)) c(t1) {} 1083 __attribute__((used)) c(t2) {} 1084 __attribute__((used)) c(t3) {} 1085 __attribute__((used)) c(t4) {} 1086 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t1E 1087 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t2E 1088 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t3E 1089 // CHECK-LABEL: @_ZN6test531cC2ENS0_2t4E 1090}; 1091} 1092 1093namespace test54 { 1094struct c { 1095 using t1 = struct { int z; } *; 1096 using t2 = struct { double z; } *; 1097 1098 __attribute__((used)) c(t1) {} 1099 __attribute__((used)) c(t2) {} 1100 // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut_E 1101 // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut0_E 1102}; 1103} 1104