summaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-07-13 17:21:42 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-07-13 17:21:42 +0000
commit4ba675006b5a8edfc48b6a9bd3dcf54a70cc08f2 (patch)
tree48b44512b5db8ced345df4a1a56b5065cf2a14d9 /test/CodeGenCXX
parentd7279c4c177bca357ef96ff1379fd9bc420bfe83 (diff)
Notes
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/DynArrayInit.cpp15
-rw-r--r--test/CodeGenCXX/alloca-align.cpp2
-rw-r--r--test/CodeGenCXX/arm-cc.cpp20
-rw-r--r--test/CodeGenCXX/arm.cpp3
-rw-r--r--test/CodeGenCXX/block-in-ctor-dtor.cpp48
-rw-r--r--test/CodeGenCXX/condition.cpp124
-rw-r--r--test/CodeGenCXX/constructor-convert.cpp2
-rw-r--r--test/CodeGenCXX/copy-in-cplus-object.cpp28
-rw-r--r--test/CodeGenCXX/cxx-apple-kext.cpp4
-rw-r--r--test/CodeGenCXX/default-arg-temps.cpp1
-rw-r--r--test/CodeGenCXX/destructors.cpp109
-rw-r--r--test/CodeGenCXX/eh.cpp116
-rw-r--r--test/CodeGenCXX/global-dtor-no-atexit.cpp3
-rw-r--r--test/CodeGenCXX/global-init-darwin.cpp23
-rw-r--r--test/CodeGenCXX/global-init.cpp8
-rw-r--r--test/CodeGenCXX/incomplete-member-function-pointer.cpp10
-rw-r--r--test/CodeGenCXX/instantiate-blocks.cpp33
-rw-r--r--test/CodeGenCXX/internal-linkage.cpp37
-rw-r--r--test/CodeGenCXX/mangle-address-space.cpp6
-rw-r--r--test/CodeGenCXX/mangle-exprs.cpp2
-rw-r--r--test/CodeGenCXX/mangle-ms.cpp96
-rw-r--r--test/CodeGenCXX/mangle-subst-std.cpp10
-rw-r--r--test/CodeGenCXX/mangle-subst.cpp13
-rw-r--r--test/CodeGenCXX/mangle-unnamed.cpp34
-rw-r--r--test/CodeGenCXX/mangle.cpp19
-rw-r--r--test/CodeGenCXX/member-functions.cpp2
-rw-r--r--test/CodeGenCXX/member-init-assignment.cpp17
-rw-r--r--test/CodeGenCXX/nrvo.cpp87
-rw-r--r--test/CodeGenCXX/pointers-to-data-members.cpp36
-rw-r--r--test/CodeGenCXX/reference-in-block-args.cpp29
-rw-r--r--test/CodeGenCXX/references.cpp43
-rw-r--r--test/CodeGenCXX/rtti-layout.cpp14
-rw-r--r--test/CodeGenCXX/rtti-linkage.cpp11
-rw-r--r--test/CodeGenCXX/sel-address.mm14
-rw-r--r--test/CodeGenCXX/static-init.cpp2
-rw-r--r--test/CodeGenCXX/template-instantiation.cpp2
-rw-r--r--test/CodeGenCXX/template-static-var-defer.cpp12
-rw-r--r--test/CodeGenCXX/temporaries.cpp18
-rw-r--r--test/CodeGenCXX/threadsafe-statics-exceptions.cpp11
-rw-r--r--test/CodeGenCXX/throw-expression-dtor.cpp13
-rw-r--r--test/CodeGenCXX/thunks.cpp12
-rw-r--r--test/CodeGenCXX/virtual-base-destructor-call.cpp11
-rw-r--r--test/CodeGenCXX/virtual-functions-incomplete-types.cpp2
-rw-r--r--test/CodeGenCXX/visibility-hidden-extern-templates.cpp26
-rw-r--r--test/CodeGenCXX/visibility-inlines-hidden.cpp57
-rw-r--r--test/CodeGenCXX/visibility.cpp20
-rw-r--r--test/CodeGenCXX/x86_64-arguments.cpp28
47 files changed, 1138 insertions, 95 deletions
diff --git a/test/CodeGenCXX/DynArrayInit.cpp b/test/CodeGenCXX/DynArrayInit.cpp
new file mode 100644
index 000000000000..4b4c2ecf1d3e
--- /dev/null
+++ b/test/CodeGenCXX/DynArrayInit.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -O3 -emit-llvm -o - %s | FileCheck %s
+// PR7490
+
+// CHECK: define signext i8 @_Z2f0v
+// CHECK: ret i8 0
+// CHECK: }
+inline void* operator new[](unsigned long, void* __p) { return __p; }
+static void f0_a(char *a) {
+ new (a) char[4]();
+}
+char f0() {
+ char a[4];
+ f0_a(a);
+ return a[0] + a[1] + a[2] + a[3];
+}
diff --git a/test/CodeGenCXX/alloca-align.cpp b/test/CodeGenCXX/alloca-align.cpp
index b70e366f4cfb..99d6ab5845f2 100644
--- a/test/CodeGenCXX/alloca-align.cpp
+++ b/test/CodeGenCXX/alloca-align.cpp
@@ -18,7 +18,7 @@ extern "C" void f1() {
(void) (struct s0) { 0, 0, 0, 0 };
}
-// CHECK: define i64 @f2
+// CHECK: define i32 @f2
// CHECK: alloca %struct.s1, align 2
struct s1 { short x; short y; };
extern "C" struct s1 f2(int a, struct s1 *x, struct s1 *y) {
diff --git a/test/CodeGenCXX/arm-cc.cpp b/test/CodeGenCXX/arm-cc.cpp
new file mode 100644
index 000000000000..6027746b9ae8
--- /dev/null
+++ b/test/CodeGenCXX/arm-cc.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple=arm-unknown-linux-gnueabi -target-abi aapcs -emit-llvm -o - | FileCheck %s
+
+class SMLoc {
+ const char *Ptr;
+public:
+ SMLoc();
+ SMLoc(const SMLoc &RHS);
+};
+SMLoc foo(void *p);
+void bar(void *x) {
+ foo(x);
+}
+void zed(SMLoc x);
+void baz() {
+ SMLoc a;
+ zed(a);
+}
+
+// CHECK: declare void @_Z3fooPv(%class.SMLoc* sret, i8*)
+// CHECK: declare void @_Z3zed5SMLoc(%class.SMLoc*)
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index 5cca7885b7d7..1d4085ca231d 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -16,5 +16,4 @@ public:
bar baz;
// CHECK: @_GLOBAL__D_a()
-// CHECK: call arm_apcscc void @_ZN3barD1Ev(%class.bar* @baz)
-
+// CHECK: call void @_ZN3barD1Ev(%class.bar* @baz)
diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp
new file mode 100644
index 000000000000..e4389a4eeec8
--- /dev/null
+++ b/test/CodeGenCXX/block-in-ctor-dtor.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+typedef void (^dispatch_block_t)(void);
+
+void dispatch_once(dispatch_block_t);
+
+class Zone {
+public:
+ Zone();
+ ~Zone();
+};
+
+Zone::Zone() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+}
+
+Zone::~Zone() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+}
+
+class X : public virtual Zone {
+ X();
+ ~X();
+};
+
+X::X() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+};
+
+X::~X() {
+ dispatch_once(^{});
+ dispatch_once(^{});
+};
+
+
+// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
+// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
+// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
+// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC1Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC1Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XC2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XD2Ev_block_invoke_
+// CHECK: define internal void @___ZN1XD2Ev_block_invoke_
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp
index f5b43d2ef491..bbc6d2f73b85 100644
--- a/test/CodeGenCXX/condition.cpp
+++ b/test/CodeGenCXX/condition.cpp
@@ -72,12 +72,10 @@ void switch_destruct(int z) {
break;
default:
- // CHECK: {{sw.default:|:5}}
// CHECK: store i32 19
z = 19;
break;
}
- // CHECK: {{sw.epilog:|:6}}
// CHECK: call void @_ZN16ConvertibleToIntD1Ev
// CHECK: store i32 20
z = 20;
@@ -96,66 +94,132 @@ void switch_destruct(int z) {
int foo();
+// CHECK: define void @_Z14while_destructi
void while_destruct(int z) {
- // CHECK: define void @_Z14while_destructi
- // CHECK: {{while.cond:|:3}}
+ // CHECK: [[Z:%.*]] = alloca i32
+ // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
while (X x = X()) {
// CHECK: call void @_ZN1XC1Ev
+ // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv
+ // CHECK-NEXT: br i1 [[COND]]
- // CHECK: {{while.body:|:5}}
- // CHECK: store i32 21
+ // Loop-exit staging block.
+ // CHECK: store i32 1, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: br
+
+ // While body.
+ // CHECK: store i32 21, i32* [[Z]]
+ // CHECK: store i32 2, i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: br
z = 21;
- // CHECK: {{while.cleanup:|:6}}
+ // Cleanup.
// CHECK: call void @_ZN1XD1Ev
+ // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]]
+ // CHECK-NEXT: switch i32 [[DEST]]
}
- // CHECK: {{while.end|:8}}
- // CHECK: store i32 22
+
+ // CHECK: store i32 22, i32* [[Z]]
z = 22;
// CHECK: call void @_Z4getXv
- // CHECK: call zeroext i1 @_ZN1XcvbEv
- // CHECK: call void @_ZN1XD1Ev
- // CHECK: br
+ // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
+ // CHECK-NEXT: call void @_ZN1XD1Ev
+ // CHECK-NEXT: br
while(getX()) { }
- // CHECK: store i32 25
+ // CHECK: store i32 25, i32* [[Z]]
z = 25;
// CHECK: ret
}
+// CHECK: define void @_Z12for_destructi(
void for_destruct(int z) {
- // CHECK: define void @_Z12for_destruct
+ // CHECK: [[Z:%.*]] = alloca i32
+ // CHECK: [[XDEST:%.*]] = alloca i32
+ // CHECK: [[I:%.*]] = alloca i32
// CHECK: call void @_ZN1YC1Ev
- for(Y y = Y(); X x = X(); ++z)
- // CHECK: {{for.cond:|:4}}
+ // CHECK-NEXT: br
+ // -> %for.cond
+
+ for(Y y = Y(); X x = X(); ++z) {
+ // %for.cond: The loop condition.
// CHECK: call void @_ZN1XC1Ev
- // CHECK: {{for.body:|:6}}
- // CHECK: store i32 23
+ // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv(
+ // CHECK-NEXT: br i1 [[COND]]
+ // -> %for.body, %for.cond.cleanup
+
+ // %for.cond.cleanup: Exit cleanup staging.
+ // CHECK: store i32 1, i32* [[XDEST]]
+ // CHECK-NEXT: br
+ // -> %cleanup
+
+ // %for.body:
+ // CHECK: store i32 23, i32* [[Z]]
+ // CHECK-NEXT: br
+ // -> %for.inc
z = 23;
- // CHECK: {{for.inc:|:7}}
- // CHECK: br label %{{for.cond.cleanup|10}}
- // CHECK: {{for.cond.cleanup:|:10}}
+
+ // %for.inc:
+ // CHECK: [[TMP:%.*]] = load i32* [[Z]]
+ // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
+ // CHECK-NEXT: store i32 [[INC]], i32* [[Z]]
+ // CHECK-NEXT: store i32 2, i32* [[XDEST]]
+ // CHECK-NEXT: br
+ // -> %cleanup
+
+ // %cleanup: Destroys X.
// CHECK: call void @_ZN1XD1Ev
- // CHECK: {{for.end:|:12}}
- // CHECK: call void @_ZN1YD1Ev
+ // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[XDEST]]
+ // CHECK-NEXT: switch i32 [[YDESTTMP]]
+ // 1 -> %cleanup4, 2 -> %cleanup.cont
+
+ // %cleanup.cont: (eliminable)
+ // CHECK: br
+ // -> %for.cond
+
+ // %cleanup4: Destroys Y.
+ // CHECK: call void @_ZN1YD1Ev(
+ // CHECK-NEXT: br
+ // -> %for.end
+ }
+
+ // %for.end:
// CHECK: store i32 24
z = 24;
+ // CHECK-NEXT: store i32 0, i32* [[I]]
+ // CHECK-NEXT: br
+ // -> %for.cond6
+
+ // %for.cond6:
// CHECK: call void @_Z4getXv
- // CHECK: call zeroext i1 @_ZN1XcvbEv
- // CHECK: call void @_ZN1XD1Ev
+ // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
+ // CHECK-NEXT: call void @_ZN1XD1Ev
+ // CHECK-NEXT: br
+ // -> %for.body10, %for.end16
+
+ // %for.body10:
// CHECK: br
+ // -> %for.inc11
+
+ // %for.inc11:
// CHECK: call void @_Z4getXv
- // CHECK: load
- // CHECK: add
- // CHECK: call void @_ZN1XD1Ev
+ // CHECK-NEXT: load i32* [[I]]
+ // CHECK-NEXT: add
+ // CHECK-NEXT: store
+ // CHECK-NEXT: call void @_ZN1XD1Ev
+ // CHECK-NEXT: br
+ // -> %for.cond6
int i = 0;
for(; getX(); getX(), ++i) { }
- z = 26;
+
+ // %for.end16
// CHECK: store i32 26
- // CHECK: ret
+ z = 26;
+
+ // CHECK-NEXT: ret void
}
void do_destruct(int z) {
diff --git a/test/CodeGenCXX/constructor-convert.cpp b/test/CodeGenCXX/constructor-convert.cpp
index 7de07724bf17..338febbe97a9 100644
--- a/test/CodeGenCXX/constructor-convert.cpp
+++ b/test/CodeGenCXX/constructor-convert.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -emit-llvm -S -o - %s
+// RUN: %clang_cc1 -emit-llvm -o - %s
// PR5775
class Twine {
diff --git a/test/CodeGenCXX/copy-in-cplus-object.cpp b/test/CodeGenCXX/copy-in-cplus-object.cpp
new file mode 100644
index 000000000000..bdfca5e4ee0a
--- /dev/null
+++ b/test/CodeGenCXX/copy-in-cplus-object.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+struct S {
+ S(const char *);
+ ~S();
+};
+
+struct TestObject
+{
+ TestObject(const TestObject& inObj, int def = 100, const S &Silly = "silly");
+ TestObject();
+ ~TestObject();
+ TestObject& operator=(const TestObject& inObj);
+ int version() const;
+
+};
+
+void testRoutine() {
+ TestObject one;
+ int (^V)() = ^{ return one.version(); };
+}
+
+// CHECK: call void @_ZN10TestObjectC1Ev
+// CHECK: call void @_ZN1SC1EPKc
+// CHECK: call void @_ZN10TestObjectC1ERKS_iRK1S
+// CHECK: call void @_ZN1SD1Ev
+// CHECK: call void @_ZN10TestObjectD1Ev
+// CHECK: call void @_ZN10TestObjectD1Ev
diff --git a/test/CodeGenCXX/cxx-apple-kext.cpp b/test/CodeGenCXX/cxx-apple-kext.cpp
index 4ba69069bedd..e9a17277b0bb 100644
--- a/test/CodeGenCXX/cxx-apple-kext.cpp
+++ b/test/CodeGenCXX/cxx-apple-kext.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 %s -flto -S -o - |\
+// RUN: %clangxx -ccc-host-triple x86_64-apple-darwin10 %s -flto -S -o - |\
// RUN: FileCheck --check-prefix=CHECK-NO-KEXT %s
-// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 %s -fapple-kext -flto -S -o - |\
+// RUN: %clangxx -ccc-host-triple x86_64-apple-darwin10 %s -fapple-kext -flto -S -o - |\
// RUN: FileCheck --check-prefix=CHECK-KEXT %s
// CHECK-NO-KEXT-NOT: _GLOBAL__D_a
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
index e4a06770cd9b..c4419850f12d 100644
--- a/test/CodeGenCXX/default-arg-temps.cpp
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -44,7 +44,6 @@ class obj{ int a; float b; double d; };
// CHECK: define void @_Z1hv()
void h() {
// CHECK: call void @llvm.memset.p0i8.i64(
- // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
obj o = obj();
}
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 1442e3740393..8efaf01f3c60 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -32,6 +32,26 @@ struct C {
C::~C() { }
+namespace PR7526 {
+ extern void foo();
+ struct allocator {
+ ~allocator() throw();
+ };
+
+ struct allocator_derived : allocator { };
+
+ // CHECK: define void @_ZN6PR75269allocatorD2Ev
+ // CHECK: call void @__cxa_call_unexpected
+ allocator::~allocator() throw() { foo(); }
+
+ // CHECK: define linkonce_odr void @_ZN6PR752617allocator_derivedD1Ev
+ // CHECK-NOT: call void @__cxa_call_unexpected
+ // CHECK: }
+ void foo() {
+ allocator_derived ad;
+ }
+}
+
// PR5084
template<typename T>
class A1 {
@@ -168,15 +188,92 @@ namespace test3 {
// Checked at top of file:
// @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+ // More checks at end of file.
+
+}
+
+namespace test4 {
+ struct A { ~A(); };
+
+ // CHECK: define void @_ZN5test43fooEv()
+ // CHECK: call void @_ZN5test41AD1Ev
+ // CHECK: ret void
+ void foo() {
+ {
+ A a;
+ goto failure;
+ }
+
+ failure:
+ return;
+ }
+
+ // CHECK: define void @_ZN5test43barEi(
+ // CHECK: [[X:%.*]] = alloca i32
+ // CHECK-NEXT: [[A:%.*]] = alloca
+ // CHECK: br label
+ // CHECK: [[TMP:%.*]] = load i32* [[X]]
+ // CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP]], 0
+ // CHECK-NEXT: br i1
+ // CHECK: call void @_ZN5test41AD1Ev(
+ // CHECK: br label
+ // CHECK: [[TMP:%.*]] = load i32* [[X]]
+ // CHECK: [[TMP2:%.*]] = add nsw i32 [[TMP]], -1
+ // CHECK: store i32 [[TMP2]], i32* [[X]]
+ // CHECK: br label
+ // CHECK: ret void
+ void bar(int x) {
+ for (A a; x; ) {
+ x--;
+ }
+ }
+}
+
+// PR7575
+namespace test5 {
+ struct A { ~A(); };
+
+ // This is really unnecessarily verbose; we should be using phis,
+ // even at -O0.
+
+ // CHECK: define void @_ZN5test53fooEv()
+ // CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
+ // CHECK-NEXT: [[IVAR:%.*]] = alloca i64
+ // CHECK: [[ELEMSARRAY:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to [[A]]
+ // CHECK-NEXT: store i64 5, i64* [[IVAR]]
+ // CHECK-NEXT: br label
+ // CHECK: [[I:%.*]] = load i64* [[IVAR]]
+ // CHECK-NEXT: icmp ne i64 [[I]], 0
+ // CHECK-NEXT: br i1
+ // CHECK: [[I:%.*]] = load i64* [[IVAR]]
+ // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I]], 1
+ // CHECK-NEXT: getelementptr inbounds [[A]]* [[ELEMSARRAY]], i64 [[I2]]
+ // CHECK-NEXT: call void @_ZN5test51AD1Ev(
+ // CHECK-NEXT: br label
+ // CHECK: [[I:%.*]] = load i64* [[IVAR]]
+ // CHECK-NEXT: [[I1:%.*]] = sub i64 [[I]], 1
+ // CHECK-NEXT: store i64 [[I1]], i64* [[IVAR]]
+ // CHECK-NEXT: br label
+ // CHECK: ret void
+ void foo() {
+ A elems[5];
+ }
+}
+
+// Checks from test3:
+
// CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(
// CHECK: call void @_ZN5test31BD2Ev(
// CHECK: call void @_ZN5test31AD2Ev(
// CHECK: ret void
// CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(
- // CHECK: call void @_ZN5test312_GLOBAL__N_11DD1Ev(
- // CHECK: call void @_ZdlPv(
+ // CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev(
+ // CHECK: call void @_ZdlPv({{.*}}) nounwind
// CHECK: ret void
+ // CHECK: call i8* @llvm.eh.exception(
+ // CHECK: call void @_ZdlPv({{.*}}) nounwind
+ // CHECK: call void @_Unwind_Resume_or_Rethrow
// Checked at top of file:
// @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
@@ -196,9 +293,12 @@ namespace test3 {
// CHECK: declare void @_ZN5test31AD2Ev(
// CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(
- // CHECK: call void @_ZN5test312_GLOBAL__N_11CD1Ev(
- // CHECK: call void @_ZdlPv(
+ // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev(
+ // CHECK: call void @_ZdlPv({{.*}}) nounwind
// CHECK: ret void
+ // CHECK: call i8* @llvm.eh.exception()
+ // CHECK: call void @_ZdlPv({{.*}}) nounwind
+ // CHECK: call void @_Unwind_Resume_or_Rethrow(
// CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
// CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
@@ -209,4 +309,3 @@ namespace test3 {
// CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
// CHECK: call void @_ZN5test312_GLOBAL__N_11CD0Ev(
// CHECK: ret void
-}
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index f2629d19d902..d03dc9171539 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -38,6 +38,7 @@ void test2() {
// CHECK: define void @_Z5test2v()
// CHECK: [[FREEVAR:%.*]] = alloca i1
// CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[EXNSLOTVAR:%.*]] = alloca i8*
// CHECK-NEXT: store i1 false, i1* [[FREEVAR]]
// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
// CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]]
@@ -104,3 +105,118 @@ namespace test5 {
// : [[HANDLER]]: (can't check this in Release-Asserts builds)
// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*))
}
+
+namespace test6 {
+ template <class T> struct allocator {
+ ~allocator() throw() { }
+ };
+
+ void foo() {
+ allocator<int> a;
+ }
+}
+
+// PR7127
+namespace test7 {
+// CHECK: define i32 @_ZN5test73fooEv()
+ int foo() {
+// CHECK: [[FREEEXNOBJ:%.*]] = alloca i1
+// CHECK-NEXT: [[EXNALLOCVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[CAUGHTEXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32
+// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
+ try {
+ try {
+// CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception
+// CHECK-NEXT: store i8* [[EXNALLOC]], i8** [[EXNALLOCVAR]]
+// CHECK-NEXT: store i1 true, i1* [[FREEEXNOBJ]]
+// CHECK-NEXT: bitcast i8* [[EXNALLOC]] to i32*
+// CHECK-NEXT: store i32 1, i32*
+// CHECK-NEXT: store i1 false, i1* [[FREEEXNOBJ]]
+// CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXNALLOC]], i8* bitcast (i8** @_ZTIi to i8*), i8* null
+ throw 1;
+ }
+// This cleanup ends up here for no good reason. It's actually unused.
+// CHECK: load i8** [[EXNALLOCVAR]]
+// CHECK-NEXT: call void @__cxa_free_exception(
+
+// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
+// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
+// CHECK-NEXT: icmp eq
+// CHECK-NEXT: br i1
+// CHECK: load i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i8* @__cxa_begin_catch
+// CHECK: invoke void @__cxa_rethrow
+ catch (int) {
+ throw;
+ }
+ }
+// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
+// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
+// CHECK-NEXT: call void @__cxa_end_catch()
+// CHECK-NEXT: br label
+// CHECK: load i8** [[CAUGHTEXNVAR]]
+// CHECK-NEXT: call i8* @__cxa_begin_catch
+// CHECK-NEXT: call void @__cxa_end_catch
+ catch (...) {
+ }
+// CHECK: ret i32 0
+ return 0;
+ }
+}
+
+// Ordering of destructors in a catch handler.
+namespace test8 {
+ struct A { A(const A&); ~A(); };
+ void bar();
+
+ // CHECK: define void @_ZN5test83fooEv()
+ void foo() {
+ try {
+ // CHECK: invoke void @_ZN5test83barEv()
+ bar();
+ } catch (A a) {
+ // CHECK: call i8* @__cxa_get_exception_ptr
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_(
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK-NEXT: invoke void @_ZN5test81AD1Ev(
+
+ // CHECK: call void @__cxa_end_catch()
+ // CHECK-NEXT: load
+ // CHECK-NEXT: switch
+
+ // CHECK: ret void
+ }
+ }
+}
+
+// Constructor function-try-block must rethrow on fallthrough.
+// rdar://problem/7696603
+namespace test9 {
+ void opaque();
+
+ struct A { A(); };
+
+ // CHECK: define void @_ZN5test91AC1Ev
+ // CHECK: call void @_ZN5test91AC2Ev
+ // CHECK-NEXT: ret void
+
+ // CHECK: define void @_ZN5test91AC2Ev(
+ A::A() try {
+ // CHECK: invoke void @_ZN5test96opaqueEv()
+ opaque();
+ } catch (int x) {
+ // CHECK: call i8* @__cxa_begin_catch
+ // CHECK: invoke void @_ZN5test96opaqueEv()
+ // CHECK: invoke void @__cxa_rethrow()
+ opaque();
+ }
+
+ // landing pad from first call to invoke
+ // CHECK: call i8* @llvm.eh.exception
+ // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+}
diff --git a/test/CodeGenCXX/global-dtor-no-atexit.cpp b/test/CodeGenCXX/global-dtor-no-atexit.cpp
index 81e219989800..1e125e3f7d81 100644
--- a/test/CodeGenCXX/global-dtor-no-atexit.cpp
+++ b/test/CodeGenCXX/global-dtor-no-atexit.cpp
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -emit-llvm -o - | FileCheck %s
+// PR7097
+// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -mconstructor-aliases -emit-llvm -o - | FileCheck %s
+
// CHECK: define internal void @_GLOBAL__D_a()
// CHECK: call void @_ZN1AD1Ev(%class.A* @b)
// CHECK: call void @_ZN1AD1Ev(%class.A* @a)
diff --git a/test/CodeGenCXX/global-init-darwin.cpp b/test/CodeGenCXX/global-init-darwin.cpp
new file mode 100644
index 000000000000..20c13c6eef77
--- /dev/null
+++ b/test/CodeGenCXX/global-init-darwin.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
+
+struct A {
+ A();
+ ~A();
+};
+
+A a;
+A as[2];
+
+struct B {
+ B();
+ ~B();
+ int f();
+};
+
+int i = B().f();
+
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: "__TEXT,__StaticInit,regular,pure_instructions" {
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index 7cbd55940b43..8ee087e29d11 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fexceptions %s -o - |FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix NOEXC %s
struct A {
A();
@@ -28,4 +29,7 @@ C c;
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
D d;
-// CHECK: define internal void @_GLOBAL__I_a() {
+// CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" {
+
+// rdar://problem/8090834: this should be nounwind
+// CHECK-NOEXC: define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" {
diff --git a/test/CodeGenCXX/incomplete-member-function-pointer.cpp b/test/CodeGenCXX/incomplete-member-function-pointer.cpp
new file mode 100644
index 000000000000..b97e44c9172d
--- /dev/null
+++ b/test/CodeGenCXX/incomplete-member-function-pointer.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+// PR7040
+struct fake_tuple;
+struct connection {
+ void bar(fake_tuple);
+};
+void (connection::*a)(fake_tuple) = &connection::bar;
+void f() {
+ void (connection::*b)(fake_tuple) = &connection::bar;
+}
diff --git a/test/CodeGenCXX/instantiate-blocks.cpp b/test/CodeGenCXX/instantiate-blocks.cpp
new file mode 100644
index 000000000000..c8f897de8200
--- /dev/null
+++ b/test/CodeGenCXX/instantiate-blocks.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s
+// rdar : // 6182276
+
+template <typename T> T foo(T t)
+{
+ void (^block)(int);
+ return 1;
+}
+
+int test1(void)
+{
+ int i = 1;
+ int b = 2;
+ i = foo(b);
+ return 0;
+}
+
+template <typename T, typename T1> void foo(T t, T1 r)
+{
+ T block_arg;
+ __block T1 byref_block_arg;
+
+ T1 (^block)(char, T, T1, double) =
+ ^ T1 (char ch, T arg, T1 arg2, double d1) { byref_block_arg = arg2;
+ return byref_block_arg + block_arg + arg; };
+
+ void (^block2)() = ^{};
+}
+
+void test2(void)
+{
+ foo(100, 'a');
+}
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
index 4263891e57f5..9fdb7274e146 100644
--- a/test/CodeGenCXX/internal-linkage.cpp
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -17,3 +17,40 @@ Anon anon1;
// CHECK: @anon2 = internal global
X<Anon> anon2;
+// rdar: // 8071804
+char const * const xyzzy = "Hello, world!";
+extern char const * const xyzzy;
+
+char const * const *test1()
+{
+ // CHECK: @_ZL5xyzzy = internal constant
+ return &xyzzy;
+}
+
+static char const * const static_xyzzy = "Hello, world!";
+extern char const * const static_xyzzy;
+
+char const * const *test2()
+{
+ // CHECK: @_ZL12static_xyzzy = internal constant
+ return &static_xyzzy;
+}
+
+static char const * static_nonconst_xyzzy = "Hello, world!";
+extern char const * static_nonconst_xyzzy;
+
+char const * *test3()
+{
+ // CHECK: @_ZL21static_nonconst_xyzzy = internal global
+ return &static_nonconst_xyzzy;
+}
+
+
+char const * extern_nonconst_xyzzy = "Hello, world!";
+extern char const * extern_nonconst_xyzzy;
+
+char const * *test4()
+{
+ // CHECK: @extern_nonconst_xyzzy = global
+ return &extern_nonconst_xyzzy;
+}
diff --git a/test/CodeGenCXX/mangle-address-space.cpp b/test/CodeGenCXX/mangle-address-space.cpp
new file mode 100644
index 000000000000..fbbcbfa35b58
--- /dev/null
+++ b/test/CodeGenCXX/mangle-address-space.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: define void @_Z2f0Pc
+void f0(char *p) { }
+// CHECK: define void @_Z2f0PU3AS1c
+void f0(char __attribute__((address_space(1))) *p) { }
diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp
index 6f1ca5568ed6..d68425f5a578 100644
--- a/test/CodeGenCXX/mangle-exprs.cpp
+++ b/test/CodeGenCXX/mangle-exprs.cpp
@@ -39,6 +39,6 @@ namespace Casts {
// CHECK: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
template void static_<4>(void*);
- // CHECK: define weak_odr i64 @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
+ // CHECK: define weak_odr i8 @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
template T<6> f<6>();
}
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
new file mode 100644
index 000000000000..61f8a595fc4f
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
+
+// CHECK: @"\01?a@@3HA"
+// CHECK: @"\01?b@N@@3HA"
+// CHECK: @c
+// CHECK: @"\01?d@foo@@0FB"
+// CHECK: @"\01?e@foo@@1JC"
+// CHECK: @"\01?f@foo@@2DD"
+// CHECK: @"\01?g@bar@@2HA"
+// CHECK: @"\01?h@@3QAHA"
+// CHECK: @"\01?i@@3PAY0BE@HA"
+// CHECK: @"\01?j@@3P6GHCE@ZA"
+// CHECK: @"\01?k@@3PTfoo@@DA"
+// CHECK: @"\01?l@@3P8foo@@AAHH@ZA"
+
+int a;
+
+namespace N { int b; }
+
+static int c;
+int _c(void) {return c;}
+// CHECK: @"\01?_c@@YAHXZ"
+
+class foo {
+ static const short d;
+protected:
+ static volatile long e;
+public:
+ static const volatile char f;
+ int operator+(int a);
+};
+
+struct bar {
+ static int g;
+};
+
+union baz {
+ int a;
+ char b;
+ double c;
+};
+
+enum quux {
+ qone,
+ qtwo,
+ qthree
+};
+
+// NOTE: The calling convention is supposed to be __thiscall by default,
+// but that needs to be fixed in Sema/AST.
+int foo::operator+(int a) {return a;}
+// CHECK: @"\01??Hfoo@@QAAHH@Z"
+
+const short foo::d = 0;
+volatile long foo::e;
+const volatile char foo::f = 'C';
+
+int bar::g;
+
+extern int * const h = &a;
+
+int i[10][20];
+
+int (__stdcall *j)(signed char, unsigned char);
+
+const volatile char foo::*k;
+
+int (foo::*l)(int);
+
+// Static functions are mangled, too.
+// Also make sure calling conventions, arglists, and throw specs work.
+static void __stdcall alpha(float a, double b) throw() {}
+bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) {
+// CHECK: @"\01?beta@@YI_N_J_W@Z"
+ alpha(0.f, 0.0);
+ return false;
+}
+
+// CHECK: @"\01?alpha@@YGXMN@Z"
+
+// Make sure tag-type mangling works.
+void gamma(class foo, struct bar, union baz, enum quux) {}
+// CHECK: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z"
+
+// Make sure pointer/reference-type mangling works.
+void delta(int * const a, const long &) {}
+// CHECK: @"\01?delta@@YAXQAHABJ@Z"
+
+// Array mangling.
+void epsilon(int a[][10][20]) {}
+// CHECK: @"\01?epsilon@@YAXQAY19BE@H@Z"
+
+// Blocks mangling (Clang extension).
+void zeta(int (^)(int, int)) {}
+// CHECK: @"\01?zeta@@YAXP_EAHHH@Z@Z"
+
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
index 4c15eaac8835..9c1e978294c8 100644
--- a/test/CodeGenCXX/mangle-subst-std.cpp
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -99,3 +99,13 @@ void f(not_string) { }
void create_streams() {
std::basic_iostream<char> bio(17);
}
+
+// Make sure we don't mangle 'std' as 'St' here.
+namespace N {
+ namespace std {
+ struct A { void f(); };
+
+ // CHECK: define void @_ZN1N3std1A1fEv
+ void A::f() { }
+ }
+}
diff --git a/test/CodeGenCXX/mangle-subst.cpp b/test/CodeGenCXX/mangle-subst.cpp
index bd06869ff7f9..d83a081dd76a 100644
--- a/test/CodeGenCXX/mangle-subst.cpp
+++ b/test/CodeGenCXX/mangle-subst.cpp
@@ -67,3 +67,16 @@ namespace NS {
// CHECK: @_ZN2NS1fERNS_1CE
void f(C&) { }
}
+
+namespace Test1 {
+
+struct A { };
+struct B { };
+
+// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_
+void f(void (B::*)(), A, A) { }
+
+// CHECK: @_ZN5Test11fEMNS_1BEFvvENS_1AES3_MS0_FvS3_EMS3_FvvE
+void f(void (B::*)(), A, A, void (B::*)(A), void (A::*)()) { }
+
+}
diff --git a/test/CodeGenCXX/mangle-unnamed.cpp b/test/CodeGenCXX/mangle-unnamed.cpp
index 4aec7dbf4a76..83b46d69454e 100644
--- a/test/CodeGenCXX/mangle-unnamed.cpp
+++ b/test/CodeGenCXX/mangle-unnamed.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
struct S {
virtual ~S() { }
@@ -37,3 +37,35 @@ struct A {
};
int f4() { return A().a(); }
+
+int f5() {
+ static union {
+ int a;
+ };
+
+ // CHECK: _ZZ2f5vE1a
+ return a;
+}
+
+int f6() {
+ static union {
+ union {
+ int : 1;
+ };
+ int b;
+ };
+
+ // CHECK: _ZZ2f6vE1b
+ return b;
+}
+
+int f7() {
+ static union {
+ union {
+ int b;
+ } a;
+ };
+
+ // CHECK: _ZZ2f7vE1a
+ return a.b;
+}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 8f3d35684884..54a4060352e0 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -477,3 +477,22 @@ namespace test10 {
// CHECK: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE(
template void f<(char) 3>(struct S<3>);
}
+
+namespace test11 {
+ // CHECK: @_ZN6test111fEz
+ void f(...) { }
+
+ struct A {
+ void f(...);
+ };
+
+ // CHECK: @_ZN6test111A1fEz
+ void A::f(...) { }
+}
+
+namespace test12 {
+
+ // CHECK: _ZN6test121fENS_1AILt33000EEE
+ template <unsigned short> struct A { };
+ void f(A<33000>) { }
+} \ No newline at end of file
diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp
index 087e62c5bb37..b363552a4806 100644
--- a/test/CodeGenCXX/member-functions.cpp
+++ b/test/CodeGenCXX/member-functions.cpp
@@ -58,6 +58,6 @@ struct T {
void test3() {
T t1, t2;
- // RUN: grep "call i64 @_ZN1TplERKS_" %t
+ // RUN: grep "call i8 @_ZN1TplERKS_" %t
T result = t1 + t2;
}
diff --git a/test/CodeGenCXX/member-init-assignment.cpp b/test/CodeGenCXX/member-init-assignment.cpp
new file mode 100644
index 000000000000..57ab7ebd1f2f
--- /dev/null
+++ b/test/CodeGenCXX/member-init-assignment.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// PR7291
+
+struct Foo {
+ unsigned file_id;
+
+ Foo(unsigned arg);
+};
+
+Foo::Foo(unsigned arg) : file_id(arg = 42)
+{ }
+
+// CHECK: define void @_ZN3FooC2Ej
+// CHECK: [[ARG:%.*]] = alloca i32
+// CHECK: store i32 42, i32* [[ARG]]
+// CHECK: store i32 42, i32* %{{.*}}
+// CHECK: ret void
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index 9ee553673f18..6181f0eee131 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -emit-llvm -O1 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
+// RUN: %clang_cc1 -emit-llvm -O1 -fexceptions -o - %s | FileCheck --check-prefix=CHECK-EH %s
// Test code generation for the named return value optimization.
class X {
@@ -13,48 +13,97 @@ public:
// CHECK-EH: define void @_Z5test0v
X test0() {
X x;
- // CHECK-NOT: call void @_ZN1XD1Ev
- // CHECK: ret void
- // CHECK-EH: br label
- // CHECK-EH: call void @_ZN1XD1Ev
- // CHECK-EH: br label
- // CHECK-EH: invoke void @_ZN1XD1Ev
- // CHECK-EH: ret void
+ // CHECK: call void @_ZN1XC1Ev
+ // CHECK-NEXT: ret void
+
+ // CHECK-EH: call void @_ZN1XC1Ev
+ // CHECK-EH-NEXT: ret void
return x;
}
// CHECK: define void @_Z5test1b(
+// CHECK-EH: define void @_Z5test1b(
X test1(bool B) {
- // CHECK: call void @_ZN1XC1Ev
+ // CHECK: tail call void @_ZN1XC1Ev
+ // CHECK-NEXT: ret void
X x;
- // CHECK-NOT: call void @_ZN1XD1Ev
- // CHECK: ret void
if (B)
return (x);
return x;
- // CHECK-EH: invoke void @_ZN1XD1Ev
+ // CHECK-EH: tail call void @_ZN1XC1Ev
+ // CHECK-EH-NEXT: ret void
}
// CHECK: define void @_Z5test2b
// CHECK-EH: define void @_Z5test2b
X test2(bool B) {
- // No NRVO
- // CHECK: call void @_ZN1XC1Ev
+ // No NRVO.
+
X x;
- // CHECK: call void @_ZN1XC1Ev
X y;
- // CHECK: call void @_ZN1XC1ERKS_
- // CHECK-EH: invoke void @_ZN1XC1ERKS_
if (B)
return y;
- // CHECK: call void @_ZN1XC1ERKS_
- // CHECK-EH: invoke void @_ZN1XC1ERKS_
return x;
+
+ // CHECK: call void @_ZN1XC1Ev
+ // CHECK-NEXT: call void @_ZN1XC1Ev
+ // CHECK: call void @_ZN1XC1ERKS_
+ // CHECK: call void @_ZN1XC1ERKS_
// CHECK: call void @_ZN1XD1Ev
// CHECK: call void @_ZN1XD1Ev
// CHECK: ret void
+
+ // The block ordering in the -fexceptions IR is unfortunate.
+
+ // CHECK-EH: call void @_ZN1XC1Ev
+ // CHECK-EH-NEXT: invoke void @_ZN1XC1Ev
+ // -> %invoke.cont1, %lpad
+
+ // %invoke.cont1:
+ // CHECK-EH: br i1
+ // -> %if.then, %if.end
+
+ // %if.then: returning 'x'
+ // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // -> %cleanup, %lpad5
+
+ // %invoke.cont: rethrow block for %eh.cleanup.
+ // This really should be elsewhere in the function.
+ // CHECK-EH: call void @_Unwind_Resume_or_Rethrow
+ // CHECK-EH-NEXT: unreachable
+
+ // %lpad: landing pad for ctor of 'y', dtor of 'y'
+ // CHECK-EH: call i8* @llvm.eh.exception()
+ // CHECK-EH: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+ // CHECK-EH-NEXT: br label
+ // -> %eh.cleanup
+
+ // %invoke.cont2: normal cleanup for 'x'
+ // CHECK-EH: call void @_ZN1XD1Ev
+ // CHECK-EH-NEXT: ret void
+
+ // %lpad5: landing pad for return copy ctors, EH cleanup for 'y'
+ // CHECK-EH: invoke void @_ZN1XD1Ev
+ // -> %eh.cleanup, %terminate.lpad
+
+ // %if.end: returning 'y'
+ // CHECK-EH: invoke void @_ZN1XC1ERKS_
+ // -> %cleanup, %lpad5
+
+ // %cleanup: normal cleanup for 'y'
// CHECK-EH: invoke void @_ZN1XD1Ev
+ // -> %invoke.cont2, %lpad
+
+ // %eh.cleanup: EH cleanup for 'x'
// CHECK-EH: invoke void @_ZN1XD1Ev
+ // -> %invoke.cont, %terminate.lpad
+
+ // %terminate.lpad: terminate landing pad.
+ // CHECK-EH: call i8* @llvm.eh.exception()
+ // CHECK-EH-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector
+ // CHECK-EH-NEXT: call void @_ZSt9terminatev()
+ // CHECK-EH-NEXT: unreachable
+
}
X test3(bool B) {
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
index affe1f7d18de..70308c6abc5f 100644
--- a/test/CodeGenCXX/pointers-to-data-members.cpp
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -68,11 +68,11 @@ void f() {
// CHECK: store i64 -1, i64* @_ZN5Casts2paE
pa = 0;
- // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 4
+ // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add nsw i64 {{.*}}, 4
// CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2pcE
pc = pa;
- // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 4
+ // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub nsw i64 {{.*}}, 4
// CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2paE
pa = static_cast<int A::*>(pc);
}
@@ -151,3 +151,35 @@ bool check2() {
}
}
+
+namespace VirtualBases {
+
+struct A {
+ char c;
+ int A::*i;
+};
+
+// FIXME: A::i should be initialized to -1 here.
+struct B : virtual A { };
+B b;
+
+// FIXME: A::i should be initialized to -1 here.
+struct C : virtual A { int A::*i; };
+C c;
+
+// FIXME: C::A::i should be initialized to -1 here.
+struct D : C { int A::*i; };
+D d;
+
+}
+
+namespace Test1 {
+
+// Don't crash when A contains a bit-field.
+struct A {
+ int A::* a;
+ int b : 10;
+};
+A a;
+
+}
diff --git a/test/CodeGenCXX/reference-in-block-args.cpp b/test/CodeGenCXX/reference-in-block-args.cpp
new file mode 100644
index 000000000000..1ff1ae2dc856
--- /dev/null
+++ b/test/CodeGenCXX/reference-in-block-args.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fblocks %s -emit-llvm -o %t
+// rdar: // 8041962
+
+extern "C" int printf(const char*, ...);
+
+struct ST {
+ int filler;
+ int referrer;
+};
+
+void OUTER_BLOCK(void (^fixer)(ST& ref)) {
+ ST ref = {2, 100};
+ fixer(ref);
+}
+
+void INNER_BLOCK(int (^largeDo) ()) {
+ printf("%d\n", largeDo());
+}
+
+void scan() {
+ OUTER_BLOCK(^(ST &ref) {
+ INNER_BLOCK(^() { return ref.referrer + ref.filler; });
+ });
+
+}
+
+int main() {
+ scan();
+}
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index 6fc610298bd2..d2ad98013553 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -150,10 +150,9 @@ void f0(s1 a) { s1 b = a; }
// PR6024
// CHECK: @_Z2f2v()
-// CHECK: alloca
-// CHECK: store
-// CHECK: load
-// CHECK: ret
+// CHECK: alloca i32,
+// CHECK-NEXT: store
+// CHECK-NEXT: ret
const int &f2() { return 0; }
// Don't constant fold const reference parameters with default arguments to
@@ -161,7 +160,7 @@ const int &f2() { return 0; }
namespace N1 {
const int foo = 1;
// CHECK: @_ZN2N14test
- int test(const int& arg = foo) {
+ void test(const int& arg = foo) {
// Ensure this array is on the stack where we can set values instead of
// being a global constant.
// CHECK: %args_array = alloca
@@ -225,3 +224,37 @@ namespace N2 {
i = 19;
}
}
+
+namespace N3 {
+
+// PR7326
+
+struct A {
+ explicit A(int);
+ ~A();
+};
+
+// CHECK: define internal void @__cxx_global_var_init
+// CHECK: call void @_ZN2N31AC1Ei(%"class.N2::X"* @_ZGRN2N35sA123E, i32 123)
+// CHECK: call i32 @__cxa_atexit
+// CHECK: ret void
+const A &sA123 = A(123);
+}
+
+namespace N4 {
+
+struct A {
+ A();
+ ~A();
+};
+
+void f() {
+ // CHECK: define void @_ZN2N41fEv
+ // CHECK: call void @_ZN2N41AC1Ev(%"class.N2::X"* @_ZGRZN2N41fEvE2ar)
+ // CHECK: call i32 @__cxa_atexit
+ // CHECK: ret void
+ static const A& ar = A();
+
+}
+}
+
diff --git a/test/CodeGenCXX/rtti-layout.cpp b/test/CodeGenCXX/rtti-layout.cpp
index 1ad87fbc7ef7..7128c4e4d07b 100644
--- a/test/CodeGenCXX/rtti-layout.cpp
+++ b/test/CodeGenCXX/rtti-layout.cpp
@@ -93,6 +93,14 @@ struct VMI7 : VMIBase1, VMI5, private VMI6 { };
#define CHECK_BASE_INFO_TYPE(type, index, base) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__base_type == &typeid(base))
#define CHECK_BASE_INFO_OFFSET_FLAGS(type, index, offset, flags) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__offset_flags == (((offset) << 8) | (flags)))
+struct B {
+ static int const volatile (*a)[10];
+ static int (*b)[10];
+
+ static int const volatile (B::*c)[10];
+ static int (B::*d)[10];
+};
+
// CHECK: define i32 @_Z1fv()
int f() {
// Vectors should be treated as fundamental types.
@@ -168,6 +176,12 @@ int f() {
CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask));
CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask));
+ // Check that when stripping qualifiers off the pointee type, we correctly handle arrays.
+ CHECK(to<__pbase_type_info>(typeid(B::a)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+ CHECK(to<__pbase_type_info>(typeid(B::a)).__pointee == to<__pbase_type_info>(typeid(B::b)).__pointee);
+ CHECK(to<__pbase_type_info>(typeid(B::c)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+ CHECK(to<__pbase_type_info>(typeid(B::c)).__pointee == to<__pbase_type_info>(typeid(B::d)).__pointee);
+
// Success!
// CHECK: ret i32 0
return 0;
diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp
index 9d85a2c69ba0..f8c1167b53db 100644
--- a/test/CodeGenCXX/rtti-linkage.cpp
+++ b/test/CodeGenCXX/rtti-linkage.cpp
@@ -14,6 +14,7 @@
// CHECK: _ZTI1A = weak_odr constant
// CHECK: _ZTI1B = constant
// CHECK: _ZTI1C = internal constant
+// CHECK: _ZTIA10_i = weak_odr constant
// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal constant
// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal constant
// CHECK: _ZTIFvvE = weak_odr
@@ -33,6 +34,7 @@
// CHECK: _ZTS1B = constant
// CHECK: _ZTS1C = internal constant
// CHECK: _ZTS1F = weak_odr constant
+// CHECK: _ZTSA10_i = weak_odr constant
// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
// CHECK: _ZTSFvvE = weak_odr constant
@@ -107,3 +109,12 @@ const std::type_info &t2() {
return typeid(getD());
}
+
+namespace Arrays {
+ struct A {
+ static const int a[10];
+ };
+ const std::type_info &f() {
+ return typeid(A::a);
+ }
+}
diff --git a/test/CodeGenCXX/sel-address.mm b/test/CodeGenCXX/sel-address.mm
new file mode 100644
index 000000000000..c3db9a7d00e5
--- /dev/null
+++ b/test/CodeGenCXX/sel-address.mm
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -verify -emit-llvm -o %t
+// pr7390
+
+void f(const SEL& v2) {}
+void g() {
+ f(@selector(dealloc));
+
+ SEL s = @selector(dealloc);
+ SEL* ps = &s;
+
+ @selector(dealloc) = s; // expected-error {{expression is not assignable}}
+
+ SEL* ps2 = &@selector(dealloc);
+}
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index 9ad87df8f0c3..09b398a530a1 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -2,7 +2,7 @@
// CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
-// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 4
+// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index 4a3857542d06..cb6c81231641 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -O1 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
diff --git a/test/CodeGenCXX/template-static-var-defer.cpp b/test/CodeGenCXX/template-static-var-defer.cpp
new file mode 100644
index 000000000000..fe18c21a2927
--- /dev/null
+++ b/test/CodeGenCXX/template-static-var-defer.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | not grep define
+// PR7415
+class X {
+ template <class Dummy> struct COMTypeInfo {
+ static const int kIID;
+ };
+ static const int& GetIID() {return COMTypeInfo<int>::kIID;}
+};
+template <class Dummy> const int X::COMTypeInfo<Dummy>::kIID = 10;
+
+
+
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index eb543cb54552..9a397abfc0cf 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -320,3 +320,21 @@ namespace UserConvertToValue {
f(1);
}
}
+
+namespace PR7556 {
+ struct A { ~A(); };
+ struct B { int i; ~B(); };
+ struct C { int C::*pm; ~C(); };
+ // CHECK: define void @_ZN6PR75563fooEv()
+ void foo() {
+ // CHECK: call void @_ZN6PR75561AD1Ev
+ A();
+ // CHECK: call void @llvm.memset.p0i8.i64
+ // CHECK: call void @_ZN6PR75561BD1Ev
+ B();
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+ // CHECK: call void @_ZN6PR75561CD1Ev
+ C();
+ // CHECK-NEXT: ret void
+ }
+}
diff --git a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
index 9347cc9616a1..17c10301d4fa 100644
--- a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
+++ b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
@@ -12,15 +12,18 @@ void f() {
// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ1fvE1x)
// CHECK: invoke void @_ZN1XC1Ev
// CHECK: call void @__cxa_guard_release(i64* @_ZGVZ1fvE1x)
- // CHECK: call i32 @__cxa_atexit
+ // CHECK-NEXT: call i32 @__cxa_atexit
// CHECK: br
static X x;
+
+ // CHECK: call i8* @__cxa_allocate_exception
+ // CHECK: invoke void @__cxa_throw
+ throw Y();
+
+ // Finally, the landing pad.
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector
// CHECK: call void @__cxa_guard_abort(i64* @_ZGVZ1fvE1x)
// CHECK: call void @_Unwind_Resume_or_Rethrow
// CHECK: unreachable
-
- // CHECK: call i8* @__cxa_allocate_exception
- throw Y();
}
diff --git a/test/CodeGenCXX/throw-expression-dtor.cpp b/test/CodeGenCXX/throw-expression-dtor.cpp
new file mode 100644
index 000000000000..f87657fdcc01
--- /dev/null
+++ b/test/CodeGenCXX/throw-expression-dtor.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm-only -verify -fexceptions
+// PR7281
+
+class A {
+public:
+ ~A();
+};
+class B : public A {
+ void ice_throw();
+};
+void B::ice_throw() {
+ throw *this;
+}
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index 79ca709f470d..1de576128a11 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -234,6 +234,18 @@ namespace Test8 {
void C::bar(NonPOD var) {}
}
+// PR7241: Emitting thunks for a method shouldn't require the vtable for
+// that class to be emitted.
+namespace Test9 {
+ struct A { virtual ~A() { } };
+ struct B : A { virtual void test() const {} };
+ struct C : B { C(); ~C(); };
+ struct D : C { D() {} };
+ void test() {
+ D d;
+ }
+}
+
/**** The following has to go at the end of the file ****/
// This is from Test5:
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index 22c49a089d0d..4618a03b9d3f 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -27,6 +27,11 @@ int main() {
// CHECK: call void @_ZN13basic_istreamIcED2Ev
// CHECK: }
+// basic_istream's base dtor is a no-op.
+// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
+// CHECK-NOT: call
+// CHECK: }
+
// basic_iostream's deleting dtor calls its complete dtor, then
// operator delete().
// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
@@ -44,9 +49,3 @@ int main() {
// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev
// CHECK: call void @_ZN13basic_istreamIcED1Ev
// CHECK: call void @_ZdlPv
-
-// basic_istream's base dtor is a no-op.
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
-// CHECK-NOT: call
-// CHECK: }
-
diff --git a/test/CodeGenCXX/virtual-functions-incomplete-types.cpp b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
index 991c2bc7220f..052a0192d665 100644
--- a/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
+++ b/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
@@ -9,7 +9,7 @@ struct B {
void B::f() { }
-// CHECK: define i64 @_ZN1D1gEv(%struct.B* %this)
+// CHECK: define i32 @_ZN1D1gEv(%struct.B* %this)
// CHECK: declare void @_ZN1B1gEv()
struct C;
diff --git a/test/CodeGenCXX/visibility-hidden-extern-templates.cpp b/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
new file mode 100644
index 000000000000..7629b77c2cee
--- /dev/null
+++ b/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -O1 -emit-llvm -o - -fvisibility hidden %s | FileCheck %s
+
+template<typename T>
+struct X {
+ void f();
+ void g() { }
+};
+
+template<typename T> void X<T>::f() { }
+
+extern template struct X<int>;
+template struct X<int>;
+extern template struct X<char>;
+
+// <rdar://problem/8109763>
+void test_X(X<int> xi, X<char> xc) {
+ // CHECK: define weak_odr hidden void @_ZN1XIiE1fEv
+ xi.f();
+ // CHECK: define weak_odr hidden void @_ZN1XIiE1gEv
+ xi.g();
+ // CHECK: declare void @_ZN1XIcE1fEv
+ xc.f();
+ // CHECK: define available_externally void @_ZN1XIcE1gEv
+ xc.g();
+}
+
diff --git a/test/CodeGenCXX/visibility-inlines-hidden.cpp b/test/CodeGenCXX/visibility-inlines-hidden.cpp
new file mode 100644
index 000000000000..bb1574fe9d5f
--- /dev/null
+++ b/test/CodeGenCXX/visibility-inlines-hidden.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fvisibility-inlines-hidden -emit-llvm -o - %s | FileCheck %s
+struct X0 {
+ void __attribute__((visibility("default"))) f1() { }
+ void f2() { }
+ void f3();
+ static void f5() { }
+ virtual void f6() { }
+};
+
+inline void X0::f3() { }
+
+template<typename T>
+struct X1 {
+ void __attribute__((visibility("default"))) f1() { }
+ void f2() { }
+ void f3();
+ void f4();
+ static void f5() { }
+ virtual void f6() { }
+};
+
+template<typename T>
+inline void X1<T>::f3() { }
+
+template<>
+inline void X1<int>::f4() { }
+
+struct __attribute__((visibility("default"))) X2 {
+ void f2() { }
+};
+
+void use(X0 *x0, X1<int> *x1, X2 *x2) {
+ // CHECK: define linkonce_odr void @_ZN2X02f1Ev
+ x0->f1();
+ // CHECK: define linkonce_odr hidden void @_ZN2X02f2Ev
+ x0->f2();
+ // CHECK: define linkonce_odr hidden void @_ZN2X02f3Ev
+ x0->f3();
+ // CHECK: define linkonce_odr hidden void @_ZN2X02f5Ev
+ X0::f5();
+ // CHECK: define linkonce_odr hidden void @_ZN2X02f6Ev
+ x0->X0::f6();
+ // CHECK: define linkonce_odr void @_ZN2X1IiE2f1Ev
+ x1->f1();
+ // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f2Ev
+ x1->f2();
+ // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f3Ev
+ x1->f3();
+ // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f4Ev
+ x1->f4();
+ // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f5Ev
+ X1<int>::f5();
+ // CHECK: define linkonce_odr hidden void @_ZN2X1IiE2f6Ev
+ x1->X1::f6();
+ // CHECK: define linkonce_odr hidden void @_ZN2X22f2Ev
+ x2->f2();
+}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 5edd27b8b279..ee3c1795fbb7 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -5,7 +5,7 @@
#define DEFAULT __attribute__((visibility("default")))
// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
-
+// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant
namespace Test1 {
// CHECK: define hidden void @_ZN5Test11fEv
void HIDDEN f() { }
@@ -64,3 +64,21 @@ namespace Test5 {
void g() { }
}
}
+
+// <rdar://problem/8091955>
+namespace Test6 {
+ struct HIDDEN foo {
+ foo() { }
+ void bonk();
+ virtual void bar() = 0;
+
+ virtual void zonk() {}
+ };
+
+ struct barc : public foo {
+ barc();
+ virtual void bar();
+ };
+
+ barc::barc() {}
+}
diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp
index 4bc83b85134e..df0c78ad941e 100644
--- a/test/CodeGenCXX/x86_64-arguments.cpp
+++ b/test/CodeGenCXX/x86_64-arguments.cpp
@@ -1,24 +1,21 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
-// CHECK: [[i64_i64_ty:%.*]] = type { i64, i64 }
-// CHECK: [[i64_double_ty:%.*]] = type { i64, double }
-
// Basic base class test.
struct f0_s0 { unsigned a; };
struct f0_s1 : public f0_s0 { void *b; };
-// CHECK: define void @_Z2f05f0_s1([[i64_i64_ty]])
+// CHECK: define void @_Z2f05f0_s1(i64 %a0.coerce0, i8* %a0.coerce1)
void f0(f0_s1 a0) { }
// Check with two eight-bytes in base class.
struct f1_s0 { unsigned a; unsigned b; float c; };
struct f1_s1 : public f1_s0 { float d;};
-// CHECK: define void @_Z2f15f1_s1([[i64_double_ty]])
+// CHECK: define void @_Z2f15f1_s1(i64 %a0.coerce0, double %a0.coerce1)
void f1(f1_s1 a0) { }
// Check with two eight-bytes in base class and merge.
struct f2_s0 { unsigned a; unsigned b; float c; };
struct f2_s1 : public f2_s0 { char d;};
-// CHECK: define void @_Z2f25f2_s1([[i64_i64_ty]])
+// CHECK: define void @_Z2f25f2_s1(i64 %a0.coerce0, i64 %a0.coerce1)
void f2(f2_s1 a0) { }
// PR5831
@@ -26,10 +23,25 @@ struct s3_0 {};
struct s3_1 { struct s3_0 a; long b; };
void f3(struct s3_1 x) {}
-// CHECK: define i64 @_Z4f4_0M2s4i(i64)
-// CHECK: define [[i64_i64_ty]] @_Z4f4_1M2s4FivE([[i64_i64_ty]])
+// CHECK: define i64 @_Z4f4_0M2s4i(i64 %a.coerce)
+// CHECK: define {{.*}} @_Z4f4_1M2s4FivE(i64 %a.coerce0, i64 %a.coerce1)
struct s4 {};
typedef int s4::* s4_mdp;
typedef int (s4::*s4_mfp)();
s4_mdp f4_0(s4_mdp a) { return a; }
s4_mfp f4_1(s4_mfp a) { return a; }
+
+
+namespace PR7523 {
+struct StringRef {
+ char *a;
+};
+
+void AddKeyword(StringRef, int x);
+
+void foo() {
+ // CHECK: define void @_ZN6PR75233fooEv()
+ // CHECK: call void @_ZN6PR752310AddKeywordENS_9StringRefEi(i8* {{.*}}, i32 4)
+ AddKeyword(StringRef(), 4);
+}
+} \ No newline at end of file