2009-12-16 04:14:24 +08:00
|
|
|
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
|
2009-08-16 06:30:50 +08:00
|
|
|
struct A {
|
|
|
|
A();
|
|
|
|
~A();
|
|
|
|
void f();
|
|
|
|
};
|
|
|
|
|
2009-08-16 11:06:32 +08:00
|
|
|
void f1() {
|
2009-10-19 05:11:11 +08:00
|
|
|
// CHECK: call void @_ZN1AC1Ev
|
|
|
|
// CHECK: call void @_ZN1AD1Ev
|
2009-08-16 11:06:32 +08:00
|
|
|
(void)A();
|
2009-10-19 05:11:11 +08:00
|
|
|
|
|
|
|
// CHECK: call void @_ZN1AC1Ev
|
|
|
|
// CHECK: call void @_ZN1AD1Ev
|
2009-08-16 06:30:50 +08:00
|
|
|
A().f();
|
|
|
|
}
|
2009-08-16 11:06:32 +08:00
|
|
|
|
2009-08-16 11:42:12 +08:00
|
|
|
// Function calls
|
2009-08-16 11:06:32 +08:00
|
|
|
struct B {
|
|
|
|
B();
|
|
|
|
~B();
|
|
|
|
};
|
|
|
|
|
|
|
|
B g();
|
|
|
|
|
|
|
|
void f2() {
|
2009-10-19 05:11:11 +08:00
|
|
|
// CHECK-NOT: call void @_ZN1BC1Ev
|
|
|
|
// CHECK: call void @_ZN1BD1Ev
|
2009-08-16 11:06:32 +08:00
|
|
|
(void)g();
|
|
|
|
}
|
|
|
|
|
2009-08-16 11:42:12 +08:00
|
|
|
// Member function calls
|
|
|
|
struct C {
|
|
|
|
C();
|
|
|
|
~C();
|
|
|
|
|
|
|
|
C f();
|
|
|
|
};
|
|
|
|
|
|
|
|
void f3() {
|
2009-10-19 05:11:11 +08:00
|
|
|
// CHECK: call void @_ZN1CC1Ev
|
|
|
|
// CHECK: call void @_ZN1CD1Ev
|
|
|
|
// CHECK: call void @_ZN1CD1Ev
|
2009-08-16 11:42:12 +08:00
|
|
|
C().f();
|
|
|
|
}
|
|
|
|
|
2009-08-16 11:53:54 +08:00
|
|
|
// Function call operator
|
|
|
|
struct D {
|
|
|
|
D();
|
|
|
|
~D();
|
|
|
|
|
|
|
|
D operator()();
|
|
|
|
};
|
|
|
|
|
|
|
|
void f4() {
|
2009-11-01 04:42:26 +08:00
|
|
|
// CHECK: call void @_ZN1DC1Ev
|
|
|
|
// CHECK: call void @_ZN1DD1Ev
|
|
|
|
// CHECK: call void @_ZN1DD1Ev
|
2009-08-16 11:53:54 +08:00
|
|
|
D()();
|
|
|
|
}
|
2009-08-16 11:42:12 +08:00
|
|
|
|
2009-08-16 12:11:06 +08:00
|
|
|
// Overloaded operators
|
|
|
|
struct E {
|
|
|
|
E();
|
|
|
|
~E();
|
|
|
|
E operator+(const E&);
|
|
|
|
E operator!();
|
|
|
|
};
|
|
|
|
|
|
|
|
void f5() {
|
2009-10-19 05:11:11 +08:00
|
|
|
// CHECK: call void @_ZN1EC1Ev
|
|
|
|
// CHECK: call void @_ZN1EC1Ev
|
|
|
|
// CHECK: call void @_ZN1ED1Ev
|
|
|
|
// CHECK: call void @_ZN1ED1Ev
|
|
|
|
// CHECK: call void @_ZN1ED1Ev
|
2009-08-16 12:11:06 +08:00
|
|
|
E() + E();
|
2009-10-19 05:11:11 +08:00
|
|
|
|
|
|
|
// CHECK: call void @_ZN1EC1Ev
|
|
|
|
// CHECK: call void @_ZN1ED1Ev
|
|
|
|
// CHECK: call void @_ZN1ED1Ev
|
2009-08-16 12:11:06 +08:00
|
|
|
!E();
|
|
|
|
}
|
2009-08-16 11:42:12 +08:00
|
|
|
|
2009-09-14 09:30:44 +08:00
|
|
|
struct F {
|
|
|
|
F();
|
|
|
|
~F();
|
|
|
|
F& f();
|
|
|
|
};
|
|
|
|
|
|
|
|
void f6() {
|
2009-10-19 05:11:11 +08:00
|
|
|
// CHECK: call void @_ZN1FC1Ev
|
|
|
|
// CHECK: call void @_ZN1FD1Ev
|
2009-09-14 09:30:44 +08:00
|
|
|
F().f();
|
|
|
|
}
|
|
|
|
|
2009-10-19 05:20:14 +08:00
|
|
|
struct G {
|
|
|
|
G();
|
|
|
|
G(A);
|
|
|
|
~G();
|
|
|
|
operator A();
|
|
|
|
};
|
|
|
|
|
|
|
|
void a(const A&);
|
|
|
|
|
|
|
|
void f7() {
|
|
|
|
// CHECK: call void @_ZN1AC1Ev
|
|
|
|
// CHECK: call void @_Z1aRK1A
|
|
|
|
// CHECK: call void @_ZN1AD1Ev
|
|
|
|
a(A());
|
|
|
|
|
|
|
|
// CHECK: call void @_ZN1GC1Ev
|
|
|
|
// CHECK: call void @_ZN1Gcv1AEv
|
|
|
|
// CHECK: call void @_Z1aRK1A
|
|
|
|
// CHECK: call void @_ZN1AD1Ev
|
|
|
|
// CHECK: call void @_ZN1GD1Ev
|
|
|
|
a(G());
|
|
|
|
}
|
2009-11-06 12:11:09 +08:00
|
|
|
|
|
|
|
namespace PR5077 {
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
A();
|
|
|
|
~A();
|
|
|
|
int f();
|
|
|
|
};
|
|
|
|
|
|
|
|
void f();
|
|
|
|
int g(const A&);
|
|
|
|
|
|
|
|
struct B {
|
|
|
|
int a1;
|
|
|
|
int a2;
|
|
|
|
B();
|
2009-11-06 12:19:02 +08:00
|
|
|
~B();
|
2009-11-06 12:11:09 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
B::B()
|
|
|
|
// CHECK: call void @_ZN6PR50771AC1Ev
|
|
|
|
// CHECK: call i32 @_ZN6PR50771A1fEv
|
|
|
|
// CHECK: call void @_ZN6PR50771AD1Ev
|
|
|
|
: a1(A().f())
|
|
|
|
// CHECK: call void @_ZN6PR50771AC1Ev
|
|
|
|
// CHECK: call i32 @_ZN6PR50771gERKNS_1AE
|
|
|
|
// CHECK: call void @_ZN6PR50771AD1Ev
|
|
|
|
, a2(g(A()))
|
|
|
|
{
|
|
|
|
// CHECK: call void @_ZN6PR50771fEv
|
|
|
|
f();
|
|
|
|
}
|
|
|
|
|
2009-11-06 12:19:02 +08:00
|
|
|
struct C {
|
|
|
|
C();
|
|
|
|
|
|
|
|
const B& b;
|
|
|
|
};
|
|
|
|
|
|
|
|
C::C()
|
|
|
|
// CHECK: call void @_ZN6PR50771BC1Ev
|
|
|
|
: b(B()) {
|
|
|
|
// CHECK: call void @_ZN6PR50771fEv
|
|
|
|
f();
|
|
|
|
|
|
|
|
// CHECK: call void @_ZN6PR50771BD1Ev
|
|
|
|
}
|
2009-11-13 12:34:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
A f8() {
|
|
|
|
// CHECK: call void @_ZN1AC1Ev
|
|
|
|
// CHECK-NOT: call void @_ZN1AD1Ev
|
|
|
|
return A();
|
|
|
|
// CHECK: ret void
|
|
|
|
}
|
2009-11-06 12:19:02 +08:00
|
|
|
|
2009-11-13 12:34:45 +08:00
|
|
|
struct H {
|
|
|
|
H();
|
|
|
|
~H();
|
|
|
|
H(const H&);
|
|
|
|
};
|
2009-11-06 12:19:02 +08:00
|
|
|
|
2009-11-13 12:34:45 +08:00
|
|
|
void f9(H h) {
|
|
|
|
// CHECK: call void @_ZN1HC1Ev
|
|
|
|
// CHECK: call void @_Z2f91H
|
|
|
|
// CHECK: call void @_ZN1HD1Ev
|
|
|
|
f9(H());
|
|
|
|
|
|
|
|
// CHECK: call void @_ZN1HC1ERKS_
|
|
|
|
// CHECK: call void @_Z2f91H
|
|
|
|
// CHECK: call void @_ZN1HD1Ev
|
|
|
|
f9(h);
|
2009-11-06 12:11:09 +08:00
|
|
|
}
|
2009-11-14 01:04:35 +08:00
|
|
|
|
|
|
|
void f10(const H&);
|
|
|
|
|
|
|
|
void f11(H h) {
|
|
|
|
// CHECK: call void @_ZN1HC1Ev
|
|
|
|
// CHECK: call void @_Z3f10RK1H
|
|
|
|
// CHECK: call void @_ZN1HD1Ev
|
|
|
|
f10(H());
|
|
|
|
|
|
|
|
// CHECK: call void @_Z3f10RK1H
|
|
|
|
// CHECK-NOT: call void @_ZN1HD1Ev
|
|
|
|
// CHECK: ret void
|
|
|
|
f10(h);
|
2009-12-16 04:14:24 +08:00
|
|
|
}
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
|
|
|
|
// PR5808
|
|
|
|
struct I {
|
|
|
|
I(const char *);
|
|
|
|
~I();
|
|
|
|
};
|
|
|
|
|
|
|
|
// CHECK: _Z3f12v
|
|
|
|
I f12() {
|
|
|
|
// CHECK: call void @_ZN1IC1EPKc
|
|
|
|
// CHECK-NOT: call void @_ZN1ID1Ev
|
|
|
|
// CHECK: ret void
|
|
|
|
return "Hello";
|
|
|
|
}
|
2009-12-25 01:16:46 +08:00
|
|
|
|
|
|
|
// PR5867
|
|
|
|
namespace PR5867 {
|
|
|
|
struct S {
|
|
|
|
S();
|
|
|
|
S(const S &);
|
|
|
|
~S();
|
|
|
|
};
|
|
|
|
|
|
|
|
void f(S, int);
|
|
|
|
// CHECK: define void @_ZN6PR58671gEv
|
|
|
|
void g() {
|
|
|
|
// CHECK: call void @_ZN6PR58671SC1Ev
|
|
|
|
// CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
|
|
|
|
// CHECK-NEXT: call void @_ZN6PR58671SD1Ev
|
|
|
|
// CHECK-NEXT: ret void
|
|
|
|
(f)(S(), 0);
|
|
|
|
}
|
2009-12-25 02:51:59 +08:00
|
|
|
|
|
|
|
// CHECK: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
|
|
|
|
template<typename T>
|
|
|
|
void g2(T) {
|
|
|
|
// CHECK: call void @_ZN6PR58671SC1Ev
|
|
|
|
// CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
|
|
|
|
// CHECK-NEXT: call void @_ZN6PR58671SD1Ev
|
|
|
|
// CHECK-NEXT: ret void
|
|
|
|
(f)(S(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void h() {
|
|
|
|
g2(17);
|
|
|
|
}
|
2009-12-25 01:16:46 +08:00
|
|
|
}
|
2010-02-02 15:10:35 +08:00
|
|
|
|
|
|
|
// PR6199
|
|
|
|
namespace PR6199 {
|
|
|
|
struct A { ~A(); };
|
|
|
|
|
|
|
|
struct B { operator A(); };
|
|
|
|
|
|
|
|
// CHECK: define void @_ZN6PR61992f2IiEENS_1AET_
|
|
|
|
template<typename T> A f2(T) {
|
|
|
|
B b;
|
|
|
|
// CHECK: call void @_ZN6PR61991BcvNS_1AEEv
|
|
|
|
// CHECK-NEXT: ret void
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
template A f2<int>(int);
|
|
|
|
|
|
|
|
}
|
2010-02-05 01:32:58 +08:00
|
|
|
|
|
|
|
namespace T12 {
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
A();
|
|
|
|
~A();
|
|
|
|
int f();
|
|
|
|
};
|
|
|
|
|
|
|
|
int& f(int);
|
|
|
|
|
|
|
|
// CHECK: define void @_ZN3T121gEv
|
|
|
|
void g() {
|
|
|
|
// CHECK: call void @_ZN3T121AC1Ev
|
|
|
|
// CHECK-NEXT: call i32 @_ZN3T121A1fEv(
|
|
|
|
// CHECK-NEXT: call i32* @_ZN3T121fEi(
|
|
|
|
// CHECK-NEXT: call void @_ZN3T121AD1Ev(
|
|
|
|
int& i = f(A().f());
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|