1// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s 2struct A { 3 A(); 4 ~A(); 5 void f(); 6}; 7 8void f1() { 9 // CHECK: call void @_ZN1AC1Ev 10 // CHECK: call void @_ZN1AD1Ev 11 (void)A(); 12 13 // CHECK: call void @_ZN1AC1Ev 14 // CHECK: call void @_ZN1AD1Ev 15 A().f(); 16} 17 18// Function calls 19struct B { 20 B(); 21 ~B(); 22}; 23 24B g(); 25 26void f2() { 27 // CHECK-NOT: call void @_ZN1BC1Ev 28 // CHECK: call void @_ZN1BD1Ev 29 (void)g(); 30} 31 32// Member function calls 33struct C { 34 C(); 35 ~C(); 36 37 C f(); 38}; 39 40void f3() { 41 // CHECK: call void @_ZN1CC1Ev 42 // CHECK: call void @_ZN1CD1Ev 43 // CHECK: call void @_ZN1CD1Ev 44 C().f(); 45} 46 47// Function call operator 48struct D { 49 D(); 50 ~D(); 51 52 D operator()(); 53}; 54 55void f4() { 56 // CHECK: call void @_ZN1DC1Ev 57 // CHECK: call void @_ZN1DD1Ev 58 // CHECK: call void @_ZN1DD1Ev 59 D()(); 60} 61 62// Overloaded operators 63struct E { 64 E(); 65 ~E(); 66 E operator+(const E&); 67 E operator!(); 68}; 69 70void f5() { 71 // CHECK: call void @_ZN1EC1Ev 72 // CHECK: call void @_ZN1EC1Ev 73 // CHECK: call void @_ZN1ED1Ev 74 // CHECK: call void @_ZN1ED1Ev 75 // CHECK: call void @_ZN1ED1Ev 76 E() + E(); 77 78 // CHECK: call void @_ZN1EC1Ev 79 // CHECK: call void @_ZN1ED1Ev 80 // CHECK: call void @_ZN1ED1Ev 81 !E(); 82} 83 84struct F { 85 F(); 86 ~F(); 87 F& f(); 88}; 89 90void f6() { 91 // CHECK: call void @_ZN1FC1Ev 92 // CHECK: call void @_ZN1FD1Ev 93 F().f(); 94} 95 96struct G { 97 G(); 98 G(A); 99 ~G(); 100 operator A(); 101}; 102 103void a(const A&); 104 105void f7() { 106 // CHECK: call void @_ZN1AC1Ev 107 // CHECK: call void @_Z1aRK1A 108 // CHECK: call void @_ZN1AD1Ev 109 a(A()); 110 111 // CHECK: call void @_ZN1GC1Ev 112 // CHECK: call void @_ZN1Gcv1AEv 113 // CHECK: call void @_Z1aRK1A 114 // CHECK: call void @_ZN1AD1Ev 115 // CHECK: call void @_ZN1GD1Ev 116 a(G()); 117} 118 119namespace PR5077 { 120 121struct A { 122 A(); 123 ~A(); 124 int f(); 125}; 126 127void f(); 128int g(const A&); 129 130struct B { 131 int a1; 132 int a2; 133 B(); 134 ~B(); 135}; 136 137B::B() 138 // CHECK: call void @_ZN6PR50771AC1Ev 139 // CHECK: call i32 @_ZN6PR50771A1fEv 140 // CHECK: call void @_ZN6PR50771AD1Ev 141 : a1(A().f()) 142 // CHECK: call void @_ZN6PR50771AC1Ev 143 // CHECK: call i32 @_ZN6PR50771gERKNS_1AE 144 // CHECK: call void @_ZN6PR50771AD1Ev 145 , a2(g(A())) 146{ 147 // CHECK: call void @_ZN6PR50771fEv 148 f(); 149} 150 151struct C { 152 C(); 153 154 const B& b; 155}; 156 157C::C() 158 // CHECK: call void @_ZN6PR50771BC1Ev 159 : b(B()) { 160 // CHECK: call void @_ZN6PR50771fEv 161 f(); 162 163 // CHECK: call void @_ZN6PR50771BD1Ev 164} 165} 166 167A f8() { 168 // CHECK: call void @_ZN1AC1Ev 169 // CHECK-NOT: call void @_ZN1AD1Ev 170 return A(); 171 // CHECK: ret void 172} 173 174struct H { 175 H(); 176 ~H(); 177 H(const H&); 178}; 179 180void f9(H h) { 181 // CHECK: call void @_ZN1HC1Ev 182 // CHECK: call void @_Z2f91H 183 // CHECK: call void @_ZN1HD1Ev 184 f9(H()); 185 186 // CHECK: call void @_ZN1HC1ERKS_ 187 // CHECK: call void @_Z2f91H 188 // CHECK: call void @_ZN1HD1Ev 189 f9(h); 190} 191 192void f10(const H&); 193 194void f11(H h) { 195 // CHECK: call void @_ZN1HC1Ev 196 // CHECK: call void @_Z3f10RK1H 197 // CHECK: call void @_ZN1HD1Ev 198 f10(H()); 199 200 // CHECK: call void @_Z3f10RK1H 201 // CHECK-NOT: call void @_ZN1HD1Ev 202 // CHECK: ret void 203 f10(h); 204} 205 206// PR5808 207struct I { 208 I(const char *); 209 ~I(); 210}; 211 212// CHECK: _Z3f12v 213I f12() { 214 // CHECK: call void @_ZN1IC1EPKc 215 // CHECK-NOT: call void @_ZN1ID1Ev 216 // CHECK: ret void 217 return "Hello"; 218} 219 220// PR5867 221namespace PR5867 { 222 struct S { 223 S(); 224 S(const S &); 225 ~S(); 226 }; 227 228 void f(S, int); 229 // CHECK: define void @_ZN6PR58671gEv 230 void g() { 231 // CHECK: call void @_ZN6PR58671SC1Ev 232 // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi 233 // CHECK-NEXT: call void @_ZN6PR58671SD1Ev 234 // CHECK-NEXT: ret void 235 (f)(S(), 0); 236 } 237 238 // CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_ 239 template<typename T> 240 void g2(T) { 241 // CHECK: call void @_ZN6PR58671SC1Ev 242 // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi 243 // CHECK-NEXT: call void @_ZN6PR58671SD1Ev 244 // CHECK-NEXT: ret void 245 (f)(S(), 0); 246 } 247 248 void h() { 249 g2(17); 250 } 251} 252 253// PR6199 254namespace PR6199 { 255 struct A { ~A(); }; 256 257 struct B { operator A(); }; 258 259 // CHECK: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_ 260 template<typename T> A f2(T) { 261 B b; 262 // CHECK: call void @_ZN6PR61991BcvNS_1AEEv 263 // CHECK-NEXT: ret void 264 return b; 265 } 266 267 template A f2<int>(int); 268 269} 270 271namespace T12 { 272 273struct A { 274 A(); 275 ~A(); 276 int f(); 277}; 278 279int& f(int); 280 281// CHECK: define void @_ZN3T121gEv 282void g() { 283 // CHECK: call void @_ZN3T121AC1Ev 284 // CHECK-NEXT: call i32 @_ZN3T121A1fEv( 285 // CHECK-NEXT: call i32* @_ZN3T121fEi( 286 // CHECK-NEXT: call void @_ZN3T121AD1Ev( 287 int& i = f(A().f()); 288} 289 290} 291 292namespace PR6648 { 293 struct B { 294 ~B(); 295 }; 296 B foo; 297 struct D; 298 D& zed(B); 299 void foobar() { 300 // CHECK: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE 301 zed(foo); 302 } 303} 304 305namespace UserConvertToValue { 306 struct X { 307 X(int); 308 X(const X&); 309 ~X(); 310 }; 311 312 void f(X); 313 314 // CHECK: void @_ZN18UserConvertToValue1gEv() 315 void g() { 316 // CHECK: call void @_ZN18UserConvertToValue1XC1Ei 317 // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE 318 // CHECK: call void @_ZN18UserConvertToValue1XD1Ev 319 // CHECK: ret void 320 f(1); 321 } 322} 323 324namespace PR7556 { 325 struct A { ~A(); }; 326 struct B { int i; ~B(); }; 327 struct C { int C::*pm; ~C(); }; 328 // CHECK: define void @_ZN6PR75563fooEv() 329 void foo() { 330 // CHECK: call void @_ZN6PR75561AD1Ev 331 A(); 332 // CHECK: call void @llvm.memset.p0i8.i64 333 // CHECK: call void @_ZN6PR75561BD1Ev 334 B(); 335 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 336 // CHECK: call void @_ZN6PR75561CD1Ev 337 C(); 338 // CHECK-NEXT: ret void 339 } 340} 341 342namespace Elision { 343 struct A { 344 A(); A(const A &); ~A(); 345 void *p; 346 void foo() const; 347 }; 348 349 void foo(); 350 A fooA(); 351 void takeA(A a); 352 353 // CHECK: define void @_ZN7Elision5test0Ev() 354 void test0() { 355 // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8 356 // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8 357 // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8 358 // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8 359 // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8 360 361 // CHECK-NEXT: call void @_ZN7Elision3fooEv() 362 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) 363 A i = (foo(), A()); 364 365 // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]]) 366 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) 367 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) 368 A j = (fooA(), A()); 369 370 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]]) 371 // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]]) 372 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]]) 373 A k = (A(), fooA()); 374 375 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]]) 376 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) 377 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) 378 } 379 380 381 // CHECK: define void @_ZN7Elision5test1EbNS_1AE( 382 void test1(bool c, A x) { 383 // CHECK: [[I:%.*]] = alloca [[A]], align 8 384 // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8 385 386 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[I]]) 387 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* [[X:%.*]]) 388 A i = (c ? A() : x); 389 390 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* [[X]]) 391 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[J]]) 392 A j = (c ? x : A()); 393 394 // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[J]]) 395 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) 396 } 397 398 // CHECK: define void @_ZN7Elision5test2Ev([[A]]* noalias sret 399 A test2() { 400 // CHECK: call void @_ZN7Elision3fooEv() 401 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) 402 // CHECK-NEXT: ret void 403 return (foo(), A()); 404 } 405 406 // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* noalias sret 407 A test3(int v, A x) { 408 if (v < 5) 409 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) 410 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X:%.*]]) 411 return (v < 0 ? A() : x); 412 else 413 // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X]]) 414 // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]]) 415 return (v > 10 ? x : A()); 416 417 // CHECK: ret void 418 } 419 420 // CHECK: define void @_ZN7Elision5test4Ev() 421 void test4() { 422 // CHECK: [[X:%.*]] = alloca [[A]], align 8 423 // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16 424 425 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]]) 426 A x; 427 428 // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0 429 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]]) 430 // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1 431 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]]) 432 A xs[] = { A(), x }; 433 434 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0 435 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 2 436 // CHECK-NEXT: br label 437 // CHECK: [[AFTER:%.*]] = phi [[A]]* 438 // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 439 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]]) 440 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] 441 // CHECK-NEXT: br i1 [[T0]], 442 443 // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) 444 } 445 446 // rdar://problem/8433352 447 // CHECK: define void @_ZN7Elision5test5Ev([[A]]* noalias sret 448 struct B { A a; B(); }; 449 A test5() { 450 // CHECK: [[AT0:%.*]] = alloca [[A]], align 8 451 // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8 452 // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8 453 // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8 454 // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8 455 456 // CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]]) 457 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0 458 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]]) 459 // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]]) 460 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]]) 461 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]]) 462 takeA(B().a); 463 464 // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]]) 465 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0 466 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]]) 467 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]]) 468 A x = B().a; 469 470 // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]]) 471 // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0 472 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]]) 473 // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]]) 474 return B().a; 475 476 // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]]) 477 } 478 479 // Reduced from webkit. 480 // CHECK: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]* 481 struct C { operator A() const; }; 482 void test6(const C *x) { 483 // CHECK: [[T0:%.*]] = alloca [[A]], align 8 484 // CHECK: [[X:%.*]] = load [[C]]** {{%.*}}, align 8 485 // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]]) 486 // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]]) 487 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) 488 // CHECK-NEXT: ret void 489 A(*x).foo(); 490 } 491} 492 493namespace PR8623 { 494 struct A { A(int); ~A(); }; 495 496 // CHECK: define void @_ZN6PR86233fooEb( 497 void foo(bool b) { 498 // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 499 // CHECK-NEXT: [[LCONS:%.*]] = alloca i1 500 // CHECK-NEXT: [[RCONS:%.*]] = alloca i1 501 // CHECK: store i1 false, i1* [[LCONS]] 502 // CHECK-NEXT: store i1 false, i1* [[RCONS]] 503 // CHECK-NEXT: br i1 504 // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2) 505 // CHECK-NEXT: store i1 true, i1* [[LCONS]] 506 // CHECK-NEXT: br label 507 // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3) 508 // CHECK-NEXT: store i1 true, i1* [[RCONS]] 509 // CHECK-NEXT: br label 510 // CHECK: load i1* [[RCONS]] 511 // CHECK-NEXT: br i1 512 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) 513 // CHECK-NEXT: br label 514 // CHECK: load i1* [[LCONS]] 515 // CHECK-NEXT: br i1 516 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) 517 // CHECK-NEXT: br label 518 // CHECK: ret void 519 b ? A(2) : A(3); 520 } 521} 522