1 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s 2 struct A { 3 A(); 4 ~A(); 5 void f(); 6 }; 7 8 void 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 19 struct B { 20 B(); 21 ~B(); 22 }; 23 24 B g(); 25 26 void f2() { 27 // CHECK-NOT: call void @_ZN1BC1Ev 28 // CHECK: call void @_ZN1BD1Ev 29 (void)g(); 30 } 31 32 // Member function calls 33 struct C { 34 C(); 35 ~C(); 36 37 C f(); 38 }; 39 40 void 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 48 struct D { 49 D(); 50 ~D(); 51 52 D operator()(); 53 }; 54 55 void f4() { 56 // CHECK: call void @_ZN1DC1Ev 57 // CHECK: call void @_ZN1DD1Ev 58 // CHECK: call void @_ZN1DD1Ev 59 D()(); 60 } 61 62 // Overloaded operators 63 struct E { 64 E(); 65 ~E(); 66 E operator+(const E&); 67 E operator!(); 68 }; 69 70 void 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 84 struct F { 85 F(); 86 ~F(); 87 F& f(); 88 }; 89 90 void f6() { 91 // CHECK: call void @_ZN1FC1Ev 92 // CHECK: call void @_ZN1FD1Ev 93 F().f(); 94 } 95 96 struct G { 97 G(); 98 G(A); 99 ~G(); 100 operator A(); 101 }; 102 103 void a(const A&); 104 105 void 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 119 namespace PR5077 { 120 121 struct A { 122 A(); 123 ~A(); 124 int f(); 125 }; 126 127 void f(); 128 int g(const A&); 129 130 struct B { 131 int a1; 132 int a2; 133 B(); 134 ~B(); 135 }; 136 137 B::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 151 struct C { 152 C(); 153 154 const B& b; 155 }; 156 157 C::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 167 A f8() { 168 // CHECK: call void @_ZN1AC1Ev 169 // CHECK-NOT: call void @_ZN1AD1Ev 170 return A(); 171 // CHECK: ret void 172 } 173 174 struct H { 175 H(); 176 ~H(); 177 H(const H&); 178 }; 179 180 void 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 192 void f10(const H&); 193 194 void 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 207 struct I { 208 I(const char *); 209 ~I(); 210 }; 211 212 // CHECK: _Z3f12v 213 I f12() { 214 // CHECK: call void @_ZN1IC1EPKc 215 // CHECK-NOT: call void @_ZN1ID1Ev 216 // CHECK: ret void 217 return "Hello"; 218 } 219 220 // PR5867 221 namespace 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 254 namespace 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 271 namespace T12 { 272 273 struct A { 274 A(); 275 ~A(); 276 int f(); 277 }; 278 279 int& f(int); 280 281 // CHECK: define void @_ZN3T121gEv 282 void 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 292 namespace 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 305 namespace 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 324 namespace 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 342 namespace 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 493 namespace 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 523 namespace PR11365 { 524 struct A { A(); ~A(); }; 525 526 // CHECK: define void @_ZN7PR113653fooEv( 527 void foo() { 528 // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0 529 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 3 530 // CHECK-NEXT: br label 531 532 // CHECK: [[PHI:%.*]] = phi 533 // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]]* [[PHI]], i64 -1 534 // CHECK-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]]) 535 // CHECK-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]] 536 // CHECK-NEXT: br i1 537 (void) (A [3]) {}; 538 } 539 } 540