summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/PR5050-constructor-conversion.cpp1
-rw-r--r--test/CodeGenCXX/abstract-class-ctors-dtors.cpp16
-rw-r--r--test/CodeGenCXX/arm.cpp8
-rw-r--r--test/CodeGenCXX/array-construction.cpp1
-rw-r--r--test/CodeGenCXX/array-operator-delete-call.cpp1
-rw-r--r--test/CodeGenCXX/call-arg-zero-temp.cpp1
-rw-r--r--test/CodeGenCXX/cast-conversion.cpp1
-rw-r--r--test/CodeGenCXX/constructor-conversion.cpp1
-rw-r--r--test/CodeGenCXX/constructor-default-arg.cpp1
-rw-r--r--test/CodeGenCXX/constructor-for-array-members.cpp1
-rw-r--r--test/CodeGenCXX/constructor-template.cpp1
-rw-r--r--test/CodeGenCXX/convert-to-fptr.cpp1
-rw-r--r--test/CodeGenCXX/copy-assign-synthesis-1.cpp1
-rw-r--r--test/CodeGenCXX/cxx0x-defaulted-templates.cpp19
-rw-r--r--test/CodeGenCXX/cxx0x-delegating-ctors.cpp42
-rw-r--r--test/CodeGenCXX/debug-info-pubtypes.cpp15
-rw-r--r--test/CodeGenCXX/decl-ref-init.cpp1
-rw-r--r--test/CodeGenCXX/default-constructor-for-members.cpp1
-rw-r--r--test/CodeGenCXX/derived-to-base-conv.cpp1
-rw-r--r--test/CodeGenCXX/destructors.cpp4
-rw-r--r--test/CodeGenCXX/eh.cpp22
-rw-r--r--test/CodeGenCXX/exceptions.cpp2
-rw-r--r--test/CodeGenCXX/global-array-destruction.cpp1
-rw-r--r--test/CodeGenCXX/global-llvm-constant.cpp22
-rw-r--r--test/CodeGenCXX/goto.cpp1
-rw-r--r--test/CodeGenCXX/instrument-functions.cpp30
-rw-r--r--test/CodeGenCXX/internal-linkage.cpp8
-rw-r--r--test/CodeGenCXX/mangle-alias-template.cpp41
-rw-r--r--test/CodeGenCXX/mangle-exprs.cpp16
-rw-r--r--test/CodeGenCXX/mangle-subst-std.cpp1
-rw-r--r--test/CodeGenCXX/mangle-unnameable-conversions.cpp14
-rw-r--r--test/CodeGenCXX/mangle.cpp43
-rw-r--r--test/CodeGenCXX/member-init-ctor.cpp14
-rw-r--r--test/CodeGenCXX/new.cpp52
-rw-r--r--test/CodeGenCXX/nrvo.cpp2
-rw-r--r--test/CodeGenCXX/pr9965.cpp12
-rw-r--r--test/CodeGenCXX/ptr-to-member-function.cpp1
-rw-r--r--test/CodeGenCXX/scoped-enums.cpp9
-rw-r--r--test/CodeGenCXX/skip-vtable-pointer-initialization.cpp200
-rw-r--r--test/CodeGenCXX/static-init-2.cpp2
-rw-r--r--test/CodeGenCXX/template-instantiation.cpp30
-rw-r--r--test/CodeGenCXX/threadsafe-statics-exceptions.cpp2
-rw-r--r--test/CodeGenCXX/thunks.cpp30
-rw-r--r--test/CodeGenCXX/vararg-non-pod.cpp16
-rw-r--r--test/CodeGenCXX/virtual-base-destructor-call.cpp10
-rw-r--r--test/CodeGenCXX/x86_32-arguments.cpp4
46 files changed, 652 insertions, 51 deletions
diff --git a/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
index aa75ea4..9b993f2 100644
--- a/test/CodeGenCXX/PR5050-constructor-conversion.cpp
+++ b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/abstract-class-ctors-dtors.cpp b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
new file mode 100644
index 0000000..e1c1a75
--- /dev/null
+++ b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// Check that we dont emit the complete constructor/destructor for this class.
+struct A {
+ virtual void f() = 0;
+ A();
+ ~A();
+};
+
+// CHECK-NOT: define void @_ZN1AC1Ev
+// CHECK: define void @_ZN1AC2Ev
+// CHECK-NOT: define void @_ZN1AD1Ev
+// CHECK: define void @_ZN1AD2Ev
+A::A() { }
+
+A::~A() { }
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index 8d74d00..dcb27ce 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -136,8 +136,8 @@ namespace test3 {
void d(int n) {
// CHECK: define void @_ZN5test31dEi(
// CHECK: [[N:%.*]] = load i32*
- // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
// CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
+ // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
// CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
// CHECK: [[SZ:%.*]] = select
// CHECK: call noalias i8* @_Znam(i32 [[SZ]])
@@ -208,8 +208,8 @@ namespace test4 {
void d(int n) {
// CHECK: define void @_ZN5test41dEi(
// CHECK: [[N:%.*]] = load i32*
- // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
// CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80)
+ // CHECK: [[NE:%.*]] = mul i32 [[N]], 20
// CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8)
// CHECK: [[SZ:%.*]] = select
// CHECK: call noalias i8* @_Znam(i32 [[SZ]])
@@ -310,7 +310,7 @@ namespace test7 {
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
- // CHECK: call void @_Unwind_Resume_or_Rethrow
+ // CHECK: call void @llvm.eh.resume(
}
}
@@ -349,7 +349,7 @@ namespace test8 {
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
- // CHECK: call void @_Unwind_Resume_or_Rethrow
+ // CHECK: call void @llvm.eh.resume(
}
}
diff --git a/test/CodeGenCXX/array-construction.cpp b/test/CodeGenCXX/array-construction.cpp
index d044ac5..5efe183 100644
--- a/test/CodeGenCXX/array-construction.cpp
+++ b/test/CodeGenCXX/array-construction.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/array-operator-delete-call.cpp b/test/CodeGenCXX/array-operator-delete-call.cpp
index ad60cf6..41b0118 100644
--- a/test/CodeGenCXX/array-operator-delete-call.cpp
+++ b/test/CodeGenCXX/array-operator-delete-call.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/call-arg-zero-temp.cpp b/test/CodeGenCXX/call-arg-zero-temp.cpp
index 88e7452..101e81f 100644
--- a/test/CodeGenCXX/call-arg-zero-temp.cpp
+++ b/test/CodeGenCXX/call-arg-zero-temp.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/cast-conversion.cpp b/test/CodeGenCXX/cast-conversion.cpp
index 27e34b9..b7a9740 100644
--- a/test/CodeGenCXX/cast-conversion.cpp
+++ b/test/CodeGenCXX/cast-conversion.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/constructor-conversion.cpp b/test/CodeGenCXX/constructor-conversion.cpp
index 405bba6..58d0d39 100644
--- a/test/CodeGenCXX/constructor-conversion.cpp
+++ b/test/CodeGenCXX/constructor-conversion.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/constructor-default-arg.cpp b/test/CodeGenCXX/constructor-default-arg.cpp
index 0c08c76..dc0ab50 100644
--- a/test/CodeGenCXX/constructor-default-arg.cpp
+++ b/test/CodeGenCXX/constructor-default-arg.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/constructor-for-array-members.cpp b/test/CodeGenCXX/constructor-for-array-members.cpp
index fd6dc6d..ef5900e 100644
--- a/test/CodeGenCXX/constructor-for-array-members.cpp
+++ b/test/CodeGenCXX/constructor-for-array-members.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp
index a3f38a6..7472d7e 100644
--- a/test/CodeGenCXX/constructor-template.cpp
+++ b/test/CodeGenCXX/constructor-template.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp
index f895dbc..c1c9f63 100644
--- a/test/CodeGenCXX/convert-to-fptr.cpp
+++ b/test/CodeGenCXX/convert-to-fptr.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
index eb761c2..17abeb9 100644
--- a/test/CodeGenCXX/copy-assign-synthesis-1.cpp
+++ b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
new file mode 100644
index 0000000..3d4000e
--- /dev/null
+++ b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s | FileCheck %s
+
+template <typename T>
+struct X {
+ X();
+};
+
+// CHECK: define void @_ZN1XIbEC1Ev
+// CHECK: define void @_ZN1XIbEC2Ev
+template <> X<bool>::X() = default;
+
+// CHECK: define weak_odr void @_ZN1XIiEC1Ev
+// CHECK: define weak_odr void @_ZN1XIiEC2Ev
+template <typename T> X<T>::X() = default;
+template X<int>::X();
+
+// CHECK: define linkonce_odr void @_ZN1XIcEC1Ev
+// CHECK: define linkonce_odr void @_ZN1XIcEC2Ev
+X<char> x;
diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
index 5b432c7..15c8e7f 100644
--- a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
+++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
@@ -2,10 +2,10 @@
struct non_trivial {
non_trivial();
- ~non_trivial();
+ ~non_trivial() noexcept(false);
};
non_trivial::non_trivial() {}
-non_trivial::~non_trivial() {}
+non_trivial::~non_trivial() noexcept(false) {}
// We use a virtual base to ensure that the constructor
// delegation optimization (complete->base) can't be
@@ -22,27 +22,35 @@ delegator::delegator() {
throw 0;
}
-// CHECK: define void @_ZN9delegatorC1Ei
-// CHECK: call void @_ZN9delegatorC1Ev
-// CHECK-NOT: lpad
-// CHECK: ret
-// CHECK-NOT: lpad
-// CHECK: define void @_ZN9delegatorC2Ei
-// CHECK: call void @_ZN9delegatorC2Ev
-// CHECK-NOT: lpad
-// CHECK: ret
-// CHECK-NOT: lpad
-delegator::delegator(int)
- : delegator()
-{}
delegator::delegator(bool)
{}
+// CHECK: define void @_ZN9delegatorC1Ec
+// CHECK: void @_ZN9delegatorC1Eb
+// CHECK: void @__cxa_throw
+// CHECK: void @_ZSt9terminatev
+// CHECK: void @_ZN9delegatorD1Ev
// CHECK: define void @_ZN9delegatorC2Ec
-// CHECK: call void @_ZN9delegatorC2Eb
-// CHECK: call void @__cxa_throw
+// CHECK: void @_ZN9delegatorC2Eb
+// CHECK: void @__cxa_throw
+// CHECK: void @_ZSt9terminatev
+// CHECK: void @_ZN9delegatorD2Ev
delegator::delegator(char)
: delegator(true) {
throw 0;
}
+
+// CHECK: define void @_ZN9delegatorC1Ei
+// CHECK: void @_ZN9delegatorC1Ev
+// CHECK-NOT: void @_ZSt9terminatev
+// CHECK: ret
+// CHECK-NOT: void @_ZSt9terminatev
+// CHECK: define void @_ZN9delegatorC2Ei
+// CHECK: void @_ZN9delegatorC2Ev
+// CHECK-NOT: void @_ZSt9terminatev
+// CHECK: ret
+// CHECK-NOT: void @_ZSt9terminatev
+delegator::delegator(int)
+ : delegator()
+{}
diff --git a/test/CodeGenCXX/debug-info-pubtypes.cpp b/test/CodeGenCXX/debug-info-pubtypes.cpp
new file mode 100644
index 0000000..35ba90b
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-pubtypes.cpp
@@ -0,0 +1,15 @@
+// REQUIRES: x86-64-registered-target
+// RUN: %clang -cc1 -triple x86_64-apple-darwin10 -g -S %s -o %t
+// RUN: FileCheck %s < %t
+
+//CHECK: .asciz "G"
+//CHECK-NEXT: .long 0
+//CHECK-NEXT: Lpubtypes_end1:
+
+class G {
+public:
+ void foo();
+};
+
+void G::foo() {
+}
diff --git a/test/CodeGenCXX/decl-ref-init.cpp b/test/CodeGenCXX/decl-ref-init.cpp
index 58fdeda..a066fbb 100644
--- a/test/CodeGenCXX/decl-ref-init.cpp
+++ b/test/CodeGenCXX/decl-ref-init.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/default-constructor-for-members.cpp b/test/CodeGenCXX/default-constructor-for-members.cpp
index a97764d..714811f 100644
--- a/test/CodeGenCXX/default-constructor-for-members.cpp
+++ b/test/CodeGenCXX/default-constructor-for-members.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp
index 006f264..c47c831 100644
--- a/test/CodeGenCXX/derived-to-base-conv.cpp
+++ b/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 353b610..94d8833 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -334,7 +334,7 @@ namespace test7 {
// CHECK: ret void
// CHECK: call i8* @llvm.eh.exception(
// CHECK: call void @_ZdlPv({{.*}}) nounwind
- // CHECK: call void @_Unwind_Resume_or_Rethrow
+ // CHECK: call void @llvm.eh.resume(
// Checked at top of file:
// @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
@@ -364,7 +364,7 @@ namespace test7 {
// CHECK: ret void
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call void @_ZdlPv({{.*}}) nounwind
- // CHECK: call void @_Unwind_Resume_or_Rethrow(
+ // CHECK: call void @llvm.eh.resume(
// CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
// CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index 6c44c76..44219b4 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -30,7 +30,8 @@ void test2() {
}
// CHECK: define void @_Z5test2v()
-// CHECK: [[EXNSLOTVAR:%.*]] = alloca i8*
+// CHECK: [[EXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32
// CHECK-NEXT: [[CLEANUPDESTVAR:%.*]] = alloca i32
// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
@@ -104,6 +105,7 @@ namespace test7 {
// CHECK: define i32 @_ZN5test73fooEv()
int foo() {
// CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32
// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32
// CHECK-NEXT: [[EHCLEANUPDESTVAR:%.*]] = alloca i32
try {
@@ -117,7 +119,8 @@ namespace test7 {
// 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: [[SELECTOR:%.*]] = 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: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
// CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
// CHECK-NEXT: icmp eq
// CHECK-NEXT: br i1
@@ -130,7 +133,8 @@ namespace test7 {
}
// 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: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
+// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
// CHECK-NEXT: store i32 1, i32* [[EHCLEANUPDESTVAR]]
// CHECK-NEXT: call void @__cxa_end_catch()
// CHECK-NEXT: br label
@@ -159,7 +163,7 @@ namespace test8 {
// CHECK-NEXT: bitcast
// CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_(
// CHECK: call i8* @__cxa_begin_catch
- // CHECK-NEXT: invoke void @_ZN5test81AD1Ev(
+ // CHECK-NEXT: call void @_ZN5test81AD1Ev(
// CHECK: call void @__cxa_end_catch()
// CHECK: ret void
}
@@ -190,7 +194,7 @@ namespace test9 {
// 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)
+ // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
}
// __cxa_end_catch can throw for some kinds of caught exceptions.
@@ -255,6 +259,7 @@ namespace test11 {
void bar() {
try {
// CHECK: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
// CHECK-NEXT: [[P:%.*]] = alloca [[A:%.*]]**,
// CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]*
// CHECK-NEXT: invoke void @_ZN6test116opaqueEv()
@@ -272,7 +277,7 @@ namespace test11 {
// PR7686
namespace test12 {
- struct A { ~A(); };
+ struct A { ~A() noexcept(false); };
bool opaque(const A&);
// CHECK: define void @_ZN6test124testEv()
@@ -392,8 +397,8 @@ namespace test15 {
}
namespace test16 {
- struct A { A(); ~A(); };
- struct B { int x; B(const A &); ~B(); };
+ struct A { A(); ~A() noexcept(false); };
+ struct B { int x; B(const A &); ~B() noexcept(false); };
void foo();
bool cond();
@@ -403,6 +408,7 @@ namespace test16 {
// CHECK-NEXT: [[EXN_ACTIVE:%.*]] = alloca i1
// CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]],
// CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
// CHECK-NEXT: [[EHDEST:%.*]] = alloca i32
// CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index d9b8506..b32b90b 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -273,6 +273,7 @@ namespace test5 {
// CHECK: define void @_ZN5test54testEv()
// CHECK: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
// CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
// CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
// CHECK-NEXT: alloca i32
@@ -324,6 +325,7 @@ namespace test7 {
// CHECK-NEXT: alloca [[A:%.*]],
// CHECK-NEXT: alloca i8*
// CHECK-NEXT: alloca i32
+ // CHECK-NEXT: alloca i32
// CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
// CHECK-NEXT: alloca i8*
// CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
diff --git a/test/CodeGenCXX/global-array-destruction.cpp b/test/CodeGenCXX/global-array-destruction.cpp
index c77551c..bbe574d 100644
--- a/test/CodeGenCXX/global-array-destruction.cpp
+++ b/test/CodeGenCXX/global-array-destruction.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
diff --git a/test/CodeGenCXX/global-llvm-constant.cpp b/test/CodeGenCXX/global-llvm-constant.cpp
index ef1dcf0..2bd43b9 100644
--- a/test/CodeGenCXX/global-llvm-constant.cpp
+++ b/test/CodeGenCXX/global-llvm-constant.cpp
@@ -8,3 +8,25 @@ struct A {
const A x;
// CHECK: @_ZL1x = internal global
+
+struct X {
+ int (*fp)(int, int);
+};
+
+int add(int x, int y) { return x + y; }
+
+// CHECK: @x2 = constant
+extern const X x2;
+const X x2 = { &add };
+
+struct X1 {
+ mutable int i;
+};
+
+struct X2 {
+ X1 array[3];
+};
+
+// CHECK: @x2b = global
+extern const X2 x2b;
+const X2 x2b = { { { 1 }, { 2 }, { 3 } } };
diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp
index 3286b22..9a12a91 100644
--- a/test/CodeGenCXX/goto.cpp
+++ b/test/CodeGenCXX/goto.cpp
@@ -12,6 +12,7 @@ namespace test0 {
// CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]],
// CHECK-NEXT: [[Z:%.*]] = alloca [[A]]
// CHECK-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SEL:%.*]] = alloca i32
// CHECK-NEXT: alloca i32
// CHECK-NEXT: [[V:%.*]] = alloca [[V:%.*]]*,
// CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]
diff --git a/test/CodeGenCXX/instrument-functions.cpp b/test/CodeGenCXX/instrument-functions.cpp
new file mode 100644
index 0000000..253e096
--- /dev/null
+++ b/test/CodeGenCXX/instrument-functions.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s
+
+// CHECK: @_Z5test1i
+int test1(int x) {
+// CHECK: __cyg_profile_func_enter
+// CHECK: __cyg_profile_func_exit
+// CHECK: ret
+ return x;
+}
+
+// CHECK: @_Z5test2i
+int test2(int) __attribute__((no_instrument_function));
+int test2(int x) {
+// CHECK-NOT: __cyg_profile_func_enter
+// CHECK-NOT: __cyg_profile_func_exit
+// CHECK: ret
+ return x;
+}
+
+// This test case previously crashed code generation. It exists solely
+// to test -finstrument-function does not crash codegen for this trivial
+// case.
+namespace rdar9445102 {
+ class Rdar9445102 {
+ public:
+ Rdar9445102();
+ };
+}
+static rdar9445102::Rdar9445102 s_rdar9445102Initializer;
+
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
index 39bce85..56cb810 100644
--- a/test/CodeGenCXX/internal-linkage.cpp
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -54,3 +54,11 @@ char const * *test4()
// CHECK: @extern_nonconst_xyzzy = global
return &extern_nonconst_xyzzy;
}
+
+// PR10120
+template <typename T> class klass {
+ virtual void f();
+};
+namespace { struct S; }
+void foo () { klass<S> x; }
+// CHECK: @_ZTV5klassIN12_GLOBAL__N_11SEE = internal unnamed_addr constant
diff --git a/test/CodeGenCXX/mangle-alias-template.cpp b/test/CodeGenCXX/mangle-alias-template.cpp
new file mode 100644
index 0000000..2020a0a
--- /dev/null
+++ b/test/CodeGenCXX/mangle-alias-template.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+template<typename T> struct alloc {};
+template<typename T> using Alloc = alloc<T>;
+template<typename T, typename A = Alloc<T>> struct vector {};
+
+template<typename T> using Vec = vector<T>;
+
+template<typename T> void f(Vec<T> v);
+template<typename T> void g(T);
+
+template<template<typename> class F> void h(F<int>);
+
+// CHECK: define void @_Z1zv(
+void z() {
+ vector<int> VI;
+ f(VI);
+ // CHECK: call void @_Z1fIiEv6vectorIT_5allocIS1_EE(
+
+ Vec<double> VD;
+ g(VD);
+ // CHECK: call void @_Z1gI6vectorId5allocIdEEEvT_(
+
+ h<Vec>(VI);
+ // CHECK: call void @_Z1hI3VecEvT_IiE(
+
+ Alloc<int> AC;
+ h(AC);
+ // CHECK: call void @_Z1hI5allocEvT_IiE(
+
+ h<Alloc>(AC);
+ // CHECK: call void @_Z1hI5AllocEvT_IiE(
+
+ Vec<char> VC;
+ g<Vec<char>>(VC);
+ // CHECK: call void @_Z1gI6vectorIc5allocIcEEEvT_(
+
+ Vec<Vec<int>> VVI;
+ g(VVI);
+ // CHECK: call void @_Z1gI6vectorIS0_Ii5allocIiEES1_IS3_EEEvT_(
+}
diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp
index 46c46f0..75294e0 100644
--- a/test/CodeGenCXX/mangle-exprs.cpp
+++ b/test/CodeGenCXX/mangle-exprs.cpp
@@ -109,3 +109,19 @@ namespace test2 {
// CHECK: store float {{.*}}, float* @_ZZN5test21gIPFfvEEEvT_DTclfL0p_EEE8variable,
}
+
+namespace test3 {
+ template <class T, class U> void a(T x, U y, decltype(x.*y) z) {}
+
+ struct X {
+ int *member;
+ };
+
+ // CHECK: define void @_ZN5test311instantiateEv
+ void instantiate() {
+ X x;
+ int *ip;
+ // CHECK: call void @_ZN5test31aINS_1XEMS1_PiEEvT_T0_DTdsfL0p_fL0p0_E
+ a(x, &X::member, ip);
+ }
+}
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
index fea3582..837d4fa 100644
--- a/test/CodeGenCXX/mangle-subst-std.cpp
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -11,6 +11,7 @@
// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant
// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant
// CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant
+
namespace std {
struct A { A(); };
diff --git a/test/CodeGenCXX/mangle-unnameable-conversions.cpp b/test/CodeGenCXX/mangle-unnameable-conversions.cpp
new file mode 100644
index 0000000..2132eff
--- /dev/null
+++ b/test/CodeGenCXX/mangle-unnameable-conversions.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+template<typename T> using id = T;
+struct S {
+ template<typename T, int N>
+ operator id<T[N]>&();
+ template<typename T, typename U>
+ operator id<T (U::*)()>() const;
+};
+
+void f() {
+ int (&a)[42] = S(); // CHECK: @_ZN1ScvRAT0__T_IiLi42EEEv(
+ char (S::*fp)() = S(); // CHECK: @_ZNK1ScvMT0_FT_vEIcS_EEv(
+};
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 27777a5..01dcf8b 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -397,16 +397,16 @@ namespace test3 {
struct Path2 : AmbiguousBase { double p; };
struct Derived : Path1, Path2 { };
- // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path1E2abERS2_(
+ // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E2abERS2_(
template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
- // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path2E2abERS2_(
+ // CHECK: define linkonce_odr i32 @_ZN5test38get_ab_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E2abERS2_(
template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
- // CHECK: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path1E1pERS2_(
+ // CHECK: define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0Esr5Path1E1pERS2_(
template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
- // CHECK: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0EsrNS_5Path2E1pERS2_(
+ // CHECK: define linkonce_odr double @_ZN5test37get_p_2INS_7DerivedEEEDtptcvPT_Li0Esr5Path2E1pERS2_(
template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
Derived obj;
@@ -676,3 +676,38 @@ namespace test25 {
A<foo>::call();
}
}
+
+namespace test26 {
+ template <template <class> class T> void foo(decltype(T<float>::object) &object) {}
+
+ template <class T> struct holder { static T object; };
+
+ void test() {
+ float f;
+
+ // CHECK: call void @_ZN6test263fooINS_6holderEEEvRDtsrT_IfE6objectE(
+ foo<holder>(f);
+ }
+}
+
+namespace test27 {
+ struct A {
+ struct inner {
+ float object;
+ };
+
+ float meth();
+ };
+ typedef A Alias;
+
+ template <class T> void a(decltype(T::inner::object) &object) {}
+ template <class T> void b(decltype(T().Alias::meth()) &object) {}
+
+ void test() {
+ float f;
+ // CHECK: call void @_ZN6test271aINS_1AEEEvRDtsrNT_5innerE6objectE(
+ a<A>(f);
+ // CHECK: call void @_ZN6test271bINS_1AEEEvRDTcldtcvT__Esr5AliasE4methEE(
+ b<A>(f);
+ }
+}
diff --git a/test/CodeGenCXX/member-init-ctor.cpp b/test/CodeGenCXX/member-init-ctor.cpp
new file mode 100644
index 0000000..d9a6734
--- /dev/null
+++ b/test/CodeGenCXX/member-init-ctor.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -std=c++0x -emit-llvm -o - | FileCheck %s
+
+bool b();
+struct S {
+ int n = b() ? S().n + 1 : 0;
+};
+
+S s;
+
+// CHECK: define{{.*}} void @_ZN1SC2Ev(
+// CHECK-NOT }
+// CHECK: call {{.*}} @_Z1bv()
+// CHECK-NOT }
+// CHECK: call {{.*}} @_ZN1SC1Ev(
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 10a6f7f..d14a5e2 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -1,12 +1,16 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
-#include <stddef.h>
+
+typedef __typeof__(sizeof(0)) size_t;
void t1() {
int* a = new int;
}
-// Placement.
-void* operator new(size_t, void*) throw();
+// Declare the reserved placement operators.
+void *operator new(size_t, void*) throw();
+void operator delete(void*, void*) throw();
+void *operator new[](size_t, void*) throw();
+void operator delete[](void*, void*) throw();
void t2(int* a) {
int* b = new (a) int;
@@ -163,3 +167,45 @@ void f() {
delete new bool;
// CHECK: ret void
}
+
+namespace test15 {
+ struct A { A(); ~A(); };
+
+ // CHECK: define void @_ZN6test155test0EPv(
+ // CHECK: [[P:%.*]] = load i8*
+ // CHECK-NEXT: icmp eq i8* [[P]], null
+ // CHECK-NEXT: br i1
+ // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T0]])
+ void test0(void *p) {
+ new (p) A();
+ }
+
+ // CHECK: define void @_ZN6test155test1EPv(
+ // CHECK: [[P:%.*]] = load i8*
+ // CHECK-NEXT: icmp eq i8* [[P]], null
+ // CHECK-NEXT: br i1
+ // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds [[A]]* [[T0]],
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T1]])
+ void test1(void *p) {
+ new (p) A[5];
+ }
+
+ // TODO: it's okay if all these size calculations get dropped.
+ // FIXME: maybe we should try to throw on overflow?
+ // CHECK: define void @_ZN6test155test2EPvi(
+ // CHECK: [[N:%.*]] = load i32*
+ // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64
+ // CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[T0]], 0
+ // CHECK-NEXT: [[T2:%.*]] = select i1 [[T1]], i64 -1, i64 [[T0]]
+ // CHECK-NEXT: [[P:%.*]] = load i8*
+ // CHECK-NEXT: icmp eq i8* [[P]], null
+ // CHECK-NEXT: br i1
+ // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds [[A]]* [[T0]],
+ // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T1]])
+ void test2(void *p, int n) {
+ new (p) A[n];
+ }
+}
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index ad6fa4f..82caff8 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -95,7 +95,7 @@ X test2(bool B) {
// %invoke.cont17: rethrow block for %eh.cleanup.
// This really should be elsewhere in the function.
- // CHECK-EH: call void @_Unwind_Resume_or_Rethrow
+ // CHECK-EH: call void @llvm.eh.resume(
// CHECK-EH-NEXT: unreachable
// %terminate.lpad: terminate landing pad.
diff --git a/test/CodeGenCXX/pr9965.cpp b/test/CodeGenCXX/pr9965.cpp
new file mode 100644
index 0000000..b87fcf4
--- /dev/null
+++ b/test/CodeGenCXX/pr9965.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s | FileCheck %s
+template<typename T>
+struct X
+{
+ X() = default;
+};
+
+X<int> x;
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK: call void @_ZN1XIiEC1Ev
+// CHECK: define linkonce_odr void @_ZN1XIiEC1Ev
+// CHECK: define linkonce_odr void @_ZN1XIiEC2Ev
diff --git a/test/CodeGenCXX/ptr-to-member-function.cpp b/test/CodeGenCXX/ptr-to-member-function.cpp
index 89db142..d012fb9 100644
--- a/test/CodeGenCXX/ptr-to-member-function.cpp
+++ b/test/CodeGenCXX/ptr-to-member-function.cpp
@@ -1,3 +1,4 @@
+// REQUIRES: x86-registered-target,x86-64-registered-target
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s
// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/scoped-enums.cpp b/test/CodeGenCXX/scoped-enums.cpp
new file mode 100644
index 0000000..d40ab36
--- /dev/null
+++ b/test/CodeGenCXX/scoped-enums.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s
+
+// PR9923
+enum class Color { red, blue, green };
+
+void f(Color);
+void g() {
+ f(Color::red);
+}
diff --git a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
new file mode 100644
index 0000000..84697be
--- /dev/null
+++ b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// See Test9 for test description.
+// CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant
+namespace Test1 {
+
+// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial.
+struct A {
+ virtual void f();
+ ~A();
+};
+
+// CHECK: define void @_ZN5Test11AD2Ev
+// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test2 {
+
+// Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial.
+struct A {
+ virtual void f();
+ ~A();
+};
+
+// CHECK: define void @_ZN5Test21AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2), i8***
+A::~A() {
+ f();
+}
+
+}
+
+namespace Test3 {
+
+// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial
+// and Field's destructor body is also trivial.
+struct Field {
+ ~Field() { }
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test31AD2Ev
+// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2), i8***
+A::~A() {
+
+}
+
+}
+
+namespace Test4 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body
+// isn't trivial.
+
+void f();
+
+struct Field {
+ ~Field() { f(); }
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test41AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test5 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't
+// available in this translation unit.
+
+struct Field {
+ ~Field();
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test51AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test6 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a member
+// variable with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field {
+ NonTrivialDestructorBody nonTrivialDestructorBody;
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test61AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test7 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test71AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test8 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : virtual NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test81AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test9 {
+
+// Check that we emit a VTT for B, even though we don't initialize the vtable pointer in the destructor.
+struct A { virtual ~A () { } };
+struct B : virtual A {};
+struct C : virtual B {
+ virtual ~C();
+};
+C::~C() {}
+
+}
diff --git a/test/CodeGenCXX/static-init-2.cpp b/test/CodeGenCXX/static-init-2.cpp
index 65ab3bb..768e6de 100644
--- a/test/CodeGenCXX/static-init-2.cpp
+++ b/test/CodeGenCXX/static-init-2.cpp
@@ -3,4 +3,4 @@
// Make sure we don't crash generating y; its value is constant, but the
// initializer has side effects, so EmitConstantExpr should fail.
int x();
-int y = x() && 0;
+int y = x() & 0;
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index 635e1d2..cc30af0 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -1,9 +1,15 @@
// RUN: %clang_cc1 %s -O1 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// CHECK: @_ZN7PR100011xE = global
+// CHECK-NOT: @_ZN7PR100014kBarE = external global i32
+//
// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant
+// CHECK: @_ZN7PR100011SIiE3arrE = weak_odr global [3 x i32]
+// CHECK-NOT: @_ZN7PR100011SIiE3arr2E = weak_odr global [3 x i32]A
+
// CHECK-NOT: _ZTVN5test31SIiEE
// CHECK-NOT: _ZTSN5test31SIiEE
@@ -122,3 +128,27 @@ class B {
// CHECK-NOT: _ZN6PR85051AILi0EE1B1fEv
template class A<0>;
}
+
+// Ensure that when instantiating initializers for static data members to
+// complete their type in an unevaluated context, we *do* emit initializers with
+// side-effects, but *don't* emit initializers and variables which are otherwise
+// unused in the program.
+namespace PR10001 {
+ template <typename T> struct S {
+ static const int arr[];
+ static const int arr2[];
+ static const int x, y;
+ static int f();
+ };
+
+ extern int foo();
+ extern int kBar;
+
+ template <typename T> const int S<T>::arr[] = { 1, 2, foo() }; // possible side effects
+ template <typename T> const int S<T>::arr2[] = { 1, 2, kBar }; // no side effects
+ template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]);
+ template <typename T> const int S<T>::y = sizeof(arr2) / sizeof(arr2[0]);
+ template <typename T> int S<T>::f() { return x + y; }
+
+ int x = S<int>::f();
+}
diff --git a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
index 0bd810e..aa79a4f 100644
--- a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
+++ b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
@@ -24,6 +24,6 @@ void f() {
// 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: call void @llvm.eh.resume(
// CHECK: unreachable
}
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index a74cc05..7c80b96 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -265,18 +265,42 @@ namespace Test11 {
struct C : B { virtual C* f(); };
C* C::f() { return 0; }
+ // C::f itself.
+ // CHECK: define {{.*}} @_ZN6Test111C1fEv(
+
// The this-adjustment and return-adjustment thunk required when
// C::f appears in a vtable where A is at a nonzero offset from C.
// CHECK: define {{.*}} @_ZTcv0_n24_v0_n32_N6Test111C1fEv(
- // C::f itself.
- // CHECK: define {{.*}} @_ZN6Test111C1fEv(
-
// The return-adjustment thunk required when C::f appears in a vtable
// where A is at a zero offset from C.
// CHECK: define {{.*}} @_ZTch0_v0_n32_N6Test111C1fEv(
}
+// Varargs thunk test.
+namespace Test12 {
+ struct A {
+ virtual A* f(int x, ...);
+ };
+ struct B {
+ virtual B* f(int x, ...);
+ };
+ struct C : A, B {
+ virtual void c();
+ virtual C* f(int x, ...);
+ };
+ C* C::f(int x, ...) { return this; }
+
+ // C::f
+ // CHECK: define {{.*}} @_ZN6Test121C1fEiz
+
+ // Varargs thunk; check that both the this and covariant adjustments
+ // are generated.
+ // CHECK: define {{.*}} @_ZTchn8_h8_N6Test121C1fEiz
+ // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
+ // CHECK: getelementptr inbounds i8* {{.*}}, i64 8
+}
+
/**** The following has to go at the end of the file ****/
// This is from Test5:
diff --git a/test/CodeGenCXX/vararg-non-pod.cpp b/test/CodeGenCXX/vararg-non-pod.cpp
new file mode 100644
index 0000000..6c6f459
--- /dev/null
+++ b/test/CodeGenCXX/vararg-non-pod.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -Wno-error=non-pod-varargs -emit-llvm -o - %s | FileCheck %s
+
+struct X {
+ X();
+ X(const X&);
+ ~X();
+};
+
+void vararg(...);
+
+// CHECK: define void @_Z4test1X
+void test(X x) {
+ // CHECK: call void @llvm.trap()
+ vararg(x);
+ // CHECK: ret void
+}
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index 807eaff..f028e4c 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -27,11 +27,6 @@ int main() {
// CHECK: call void @_ZN13basic_istreamIcED2Ev
// CHECK: }
-// basic_istream's base dtor is a no-op.
-// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* %this, i8** %vtt) unnamed_addr
-// CHECK-NOT: call
-// CHECK: }
-
// basic_iostream's deleting dtor calls its complete dtor, then
// operator delete().
// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev(%struct.basic_iostream* %this) unnamed_addr
@@ -49,3 +44,8 @@ int main() {
// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev(%struct.basic_istream* %this) unnamed_addr
// 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(%struct.basic_istream* %this, i8** %vtt) unnamed_addr
+// CHECK-NOT: call
+// CHECK: }
diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp
index e94e2ca..4c06033 100644
--- a/test/CodeGenCXX/x86_32-arguments.cpp
+++ b/test/CodeGenCXX/x86_32-arguments.cpp
@@ -31,7 +31,7 @@ void f(C) { }
// CHECK: define void @_ZThn4_N18BasicAliasAnalysis13getModRefInfoE8CallSite
// ...
-// CHECK: %struct.CallSite* byval %CS)
+// CHECK: %struct.CallSite* byval align 4 %CS)
struct CallSite {
unsigned Ptr;
CallSite(unsigned XX) : Ptr(XX) {}
@@ -89,7 +89,7 @@ struct s5 { s5(); int &x; };
s5 f5() { return s5(); }
// CHECK: define i32 @_Z4f6_0M2s6i(i32 %a)
-// CHECK: define i64 @_Z4f6_1M2s6FivE(%{{.*}} byval)
+// CHECK: define i64 @_Z4f6_1M2s6FivE(%{{.*}} byval align 4)
// FIXME: It would be nice to avoid byval on the previous case.
struct s6 {};
typedef int s6::* s6_mdp;
OpenPOWER on IntegriCloud