summaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-02-16 09:31:36 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-02-16 09:31:36 +0000
commitecb7e5c8afe929ee38155db94de6b084ec32a645 (patch)
tree53010172e19c77ea447bcd89e117cda052ab52e0 /test/CodeGenCXX
parent5044f5c816adfd5cba17f1adee1a10127296d0bf (diff)
Update clang to r96341.
Notes
Notes: svn path=/vendor/clang/dist/; revision=203955
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/PR4890-debug-info-dtor.cpp6
-rw-r--r--test/CodeGenCXX/alloca-align.cpp12
-rw-r--r--test/CodeGenCXX/anonymous-namespaces.cpp16
-rw-r--r--test/CodeGenCXX/attr.cpp29
-rw-r--r--test/CodeGenCXX/condition.cpp22
-rw-r--r--test/CodeGenCXX/conditional-temporaries.cpp65
-rw-r--r--test/CodeGenCXX/const-global-linkage.cpp4
-rw-r--r--test/CodeGenCXX/const-init.cpp4
-rw-r--r--test/CodeGenCXX/conversion-function.cpp2
-rw-r--r--test/CodeGenCXX/debug-info.cpp28
-rw-r--r--test/CodeGenCXX/default-destructor-synthesis.cpp72
-rw-r--r--test/CodeGenCXX/deferred-global-init.cpp2
-rw-r--r--test/CodeGenCXX/derived-to-base.cpp22
-rw-r--r--test/CodeGenCXX/dyncast.cpp29
-rw-r--r--test/CodeGenCXX/extern-c.cpp3
-rw-r--r--test/CodeGenCXX/global-init.cpp15
-rw-r--r--test/CodeGenCXX/global-llvm-constant.cpp2
-rw-r--r--test/CodeGenCXX/internal-linkage.cpp19
-rw-r--r--test/CodeGenCXX/mangle-exprs.cpp44
-rw-r--r--test/CodeGenCXX/mangle.cpp72
-rw-r--r--test/CodeGenCXX/member-function-pointer-calls.cpp26
-rw-r--r--test/CodeGenCXX/member-function-pointers.cpp37
-rw-r--r--test/CodeGenCXX/member-initializers.cpp34
-rw-r--r--test/CodeGenCXX/member-pointer-cast.cpp21
-rw-r--r--test/CodeGenCXX/member-pointers-zero-init.cpp34
-rw-r--r--test/CodeGenCXX/no-exceptions.cpp12
-rw-r--r--test/CodeGenCXX/pointers-to-data-members.cpp87
-rw-r--r--test/CodeGenCXX/reference-init.cpp8
-rw-r--r--test/CodeGenCXX/references.cpp8
-rw-r--r--test/CodeGenCXX/static-data-member.cpp10
-rw-r--r--test/CodeGenCXX/static-init.cpp19
-rw-r--r--test/CodeGenCXX/temp-order.cpp32
-rw-r--r--test/CodeGenCXX/temporaries.cpp39
-rw-r--r--test/CodeGenCXX/threadsafe-statics.cpp17
-rw-r--r--test/CodeGenCXX/throw-expressions.cpp2
-rw-r--r--test/CodeGenCXX/virt.cpp58
-rw-r--r--test/CodeGenCXX/virtual-bases.cpp8
-rw-r--r--test/CodeGenCXX/virtual-function-calls.cpp21
-rw-r--r--test/CodeGenCXX/visibility.cpp66
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp367
-rw-r--r--test/CodeGenCXX/vtable-pointer-initialization.cpp54
-rw-r--r--test/CodeGenCXX/x86_32-arguments.cpp24
42 files changed, 1213 insertions, 239 deletions
diff --git a/test/CodeGenCXX/PR4890-debug-info-dtor.cpp b/test/CodeGenCXX/PR4890-debug-info-dtor.cpp
deleted file mode 100644
index bcaf1b96274e..000000000000
--- a/test/CodeGenCXX/PR4890-debug-info-dtor.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm-only -g %s
-struct X {
- ~X();
-};
-
-X::~X() { }
diff --git a/test/CodeGenCXX/alloca-align.cpp b/test/CodeGenCXX/alloca-align.cpp
new file mode 100644
index 000000000000..de6b34d06072
--- /dev/null
+++ b/test/CodeGenCXX/alloca-align.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+//
+// CHECK: alloca %struct.MemsetRange, align 16
+
+struct MemsetRange {
+ int Start, End;
+ unsigned Alignment;
+ int TheStores __attribute__((aligned(16)));
+};
+void foobar() {
+ (void) MemsetRange();
+}
diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp
index 7689c941e103..695f8f59defc 100644
--- a/test/CodeGenCXX/anonymous-namespaces.cpp
+++ b/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -1,9 +1,25 @@
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+int f();
+
namespace {
+ // CHECK: @_ZN12_GLOBAL__N_11bE = internal global i32 0
+ // CHECK: @_ZN12_GLOBAL__N_1L1cE = internal global i32 0
+ // CHECK: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
// CHECK: @_ZN12_GLOBAL__N_11aE = internal global i32 0
int a = 0;
+ int b = f();
+
+ static int c = f();
+
+ class D {
+ static int d;
+ };
+
+ int D::d = f();
+
// CHECK: define internal i32 @_ZN12_GLOBAL__N_13fooEv()
int foo() {
return 32;
diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp
index 1b214b77bee7..4c781c62b29f 100644
--- a/test/CodeGenCXX/attr.cpp
+++ b/test/CodeGenCXX/attr.cpp
@@ -1,39 +1,20 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -S %s -o %t.s
-// RUN: FileCheck --input-file=%t.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+// CHECK: define i32 @_Z3foov() nounwind align 1024
int foo() __attribute__((aligned(1024)));
int foo() { }
-// CHECK:.align 10, 0x90
-// CHECK:.globl __Z3foov
-// CHECK:__Z3foov:
-
-
class C {
virtual void bar1() __attribute__((aligned(1)));
virtual void bar2() __attribute__((aligned(2)));
virtual void bar3() __attribute__((aligned(1024)));
} c;
-// CHECK:.align 1, 0x90
-// CHECK-NEXT:.globl __ZN1CC1Ev
-
+// CHECK: define void @_ZN1C4bar1Ev(%class.C* %this) nounwind align 2
void C::bar1() { }
-// CHECK:.align 1, 0x90
-// CHECK-NEXT:.globl __ZN1C4bar1Ev
-// CHECK-NEXT:__ZN1C4bar1Ev:
-
-
+// CHECK: define void @_ZN1C4bar2Ev(%class.C* %this) nounwind align 2
void C::bar2() { }
-// CHECK:.align 1, 0x90
-// CHECK-NEXT:.globl __ZN1C4bar2Ev
-// CHECK-NEXT:__ZN1C4bar2Ev:
-
-
+// CHECK: define void @_ZN1C4bar3Ev(%class.C* %this) nounwind align 1024
void C::bar3() { }
-
-// CHECK:.align 10, 0x90
-// CHECK-NEXT:.globl __ZN1C4bar3Ev
-// CHECK-NEXT:__ZN1C4bar3Ev:
diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp
index a1b7a09aa347..e435408aa840 100644
--- a/test/CodeGenCXX/condition.cpp
+++ b/test/CodeGenCXX/condition.cpp
@@ -64,7 +64,7 @@ void switch_destruct(int z) {
z = 19;
break;
}
- // CHECK: {{sw.epilog:|:4}}
+ // CHECK: {{sw.epilog:|:5}}
// CHECK: call void @_ZN16ConvertibleToIntD1Ev
// CHECK: store i32 20
z = 20;
@@ -74,18 +74,18 @@ int foo();
void while_destruct(int z) {
// CHECK: define void @_Z14while_destructi
- // CHECK: {{while.cond:|:1}}
+ // CHECK: {{while.cond:|:2}}
while (X x = X()) {
// CHECK: call void @_ZN1XC1Ev
- // CHECK: {{while.body:|:3}}
+ // CHECK: {{while.body:|:4}}
// CHECK: store i32 21
z = 21;
- // CHECK: {{while.cleanup:|:4}}
+ // CHECK: {{while.cleanup:|:5}}
// CHECK: call void @_ZN1XD1Ev
}
- // CHECK: {{while.end|:6}}
+ // CHECK: {{while.end|:7}}
// CHECK: store i32 22
z = 22;
}
@@ -94,16 +94,16 @@ void for_destruct(int z) {
// CHECK: define void @_Z12for_destruct
// CHECK: call void @_ZN1YC1Ev
for(Y y = Y(); X x = X(); ++z)
- // CHECK: {{for.cond:|:1}}
+ // CHECK: {{for.cond:|:2}}
// CHECK: call void @_ZN1XC1Ev
- // CHECK: {{for.body:|:3}}
+ // CHECK: {{for.body:|:4}}
// CHECK: store i32 23
z = 23;
- // CHECK: {{for.inc:|:4}}
- // CHECK: br label %{{for.cond.cleanup|7}}
- // CHECK: {{for.cond.cleanup:|:7}}
+ // CHECK: {{for.inc:|:5}}
+ // CHECK: br label %{{for.cond.cleanup|8}}
+ // CHECK: {{for.cond.cleanup:|:8}}
// CHECK: call void @_ZN1XD1Ev
- // CHECK: {{for.end:|:9}}
+ // CHECK: {{for.end:|:10}}
// CHECK: call void @_ZN1YD1Ev
// CHECK: store i32 24
z = 24;
diff --git a/test/CodeGenCXX/conditional-temporaries.cpp b/test/CodeGenCXX/conditional-temporaries.cpp
index 0eac10b43cfd..d5382872f9d9 100644
--- a/test/CodeGenCXX/conditional-temporaries.cpp
+++ b/test/CodeGenCXX/conditional-temporaries.cpp
@@ -1,28 +1,55 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -O3 | FileCheck %s
-struct I {
+namespace {
+
+static int ctorcalls;
+static int dtorcalls;
+
+struct A {
+ A() : i(0) { ctorcalls++; }
+ ~A() { dtorcalls++; }
int i;
- I();
- ~I();
+
+ friend const A& operator<<(const A& a, int n) {
+ return a;
+ }
};
-void g(int);
+void g(int) { }
+void g(const A&) { }
-volatile int i;
+void f1(bool b) {
+ g(b ? A().i : 0);
+ g(b || A().i);
+ g(b && A().i);
+ g(b ? A() << 1 : A() << 2);
+}
-void f1() {
- // CHECK: call void @_ZN1IC1Ev
- g(i ? I().i : 0);
- // CHECK: call void @_Z1gi
- // CHECK: call void @_ZN1ID1Ev
+struct Checker {
+ Checker() {
+ f1(true);
+ f1(false);
+ }
+};
- // CHECK: call void @_ZN1IC1Ev
- g(i || I().i);
- // CHECK: call void @_Z1gi
- // CHECK: call void @_ZN1ID1Ev
+Checker c;
+
+}
+
+// CHECK: define i32 @_Z12getCtorCallsv()
+int getCtorCalls() {
+ // CHECK: ret i32 5
+ return ctorcalls;
+}
+
+// CHECK: define i32 @_Z12getDtorCallsv()
+int getDtorCalls() {
+ // CHECK: ret i32 5
+ return dtorcalls;
+}
- // CHECK: call void @_ZN1IC1Ev
- g(i && I().i);
- // CHECK: call void @_Z1gi
- // CHECK: call void @_ZN1ID1Ev
+// CHECK: define zeroext i1 @_Z7successv()
+bool success() {
+ // CHECK: ret i1 true
+ return ctorcalls == dtorcalls;
}
diff --git a/test/CodeGenCXX/const-global-linkage.cpp b/test/CodeGenCXX/const-global-linkage.cpp
index f88bc808a7c6..d0a055b49495 100644
--- a/test/CodeGenCXX/const-global-linkage.cpp
+++ b/test/CodeGenCXX/const-global-linkage.cpp
@@ -3,11 +3,11 @@
const int x = 10;
const int y = 20;
// CHECK-NOT: @x
-// CHECK: @y = internal constant i32 20
+// CHECK: @_ZL1y = internal constant i32 20
const int& b() { return y; }
const char z1[] = "asdf";
const char z2[] = "zxcv";
// CHECK-NOT: @z1
-// CHECK: @z2 = internal constant
+// CHECK: @_ZL2z2 = internal constant
const char* b2() { return z2; }
diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp
index 874b5f64e2ba..9cfce7ace86b 100644
--- a/test/CodeGenCXX/const-init.cpp
+++ b/test/CodeGenCXX/const-init.cpp
@@ -2,11 +2,11 @@
// CHECK: @a = global i32 10
int a = 10;
-// CHECK: @ar = global i32* @a
+// CHECK: @ar = constant i32* @a
int &ar = a;
void f();
-// CHECK: @fr = global void ()* @_Z1fv
+// CHECK: @fr = constant void ()* @_Z1fv
void (&fr)() = f;
struct S { int& a; };
diff --git a/test/CodeGenCXX/conversion-function.cpp b/test/CodeGenCXX/conversion-function.cpp
index fccb6f094e07..e2f8f7e17b93 100644
--- a/test/CodeGenCXX/conversion-function.cpp
+++ b/test/CodeGenCXX/conversion-function.cpp
@@ -2,7 +2,7 @@
// 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
// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
-
+// XFAIL: *
extern "C" int printf(...);
struct S {
operator int();
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index cb6e830a49e0..6bb9533a477e 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -g
+// RUN: %clang_cc1 -emit-llvm-only -g %s
template<typename T> struct Identity {
typedef T Type;
};
@@ -24,3 +24,29 @@ namespace EmptyNameCrash {
typedef struct { A x; } B;
B x;
}
+
+// PR4890
+namespace PR4890 {
+ struct X {
+ ~X();
+ };
+
+ X::~X() { }
+}
+
+namespace VirtualDtor {
+ struct Y {
+ virtual ~Y();
+ };
+
+ Y::~Y() { }
+}
+
+namespace VirtualBase {
+ struct A { };
+ struct B : virtual A { };
+
+ void f() {
+ B b;
+ }
+}
diff --git a/test/CodeGenCXX/default-destructor-synthesis.cpp b/test/CodeGenCXX/default-destructor-synthesis.cpp
index 71167a204fbb..fac5cc01f6b7 100644
--- a/test/CodeGenCXX/default-destructor-synthesis.cpp
+++ b/test/CodeGenCXX/default-destructor-synthesis.cpp
@@ -1,58 +1,36 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -O0 -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 -O0 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix LP32 -input-file=%t-32.s %s
-
-extern "C" int printf(...);
-
-int count = 1;
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -O2 -o - | FileCheck %s
+static int count = 0;
struct S {
- S() : iS(count++), fS(1.23) {};
- ~S(){printf("S::~S(%d, %f)\n", iS, fS); };
- int iS;
- float fS;
+ S() { count++; }
+ ~S() { count--; }
};
-struct Q {
- Q() : iQ(count++), dQ(2.34) {};
- ~Q(){printf("Q::~Q(%d, %f)\n", iQ, dQ); };
- int iQ;
- double dQ;
+struct P {
+ P() { count++; }
+ ~P() { count--; }
};
-struct P {
- P() : fP(3.45) , iP(count++) {};
- ~P(){printf("P::~P(%d, %f)\n", iP, fP); };
- float fP;
- int iP;
+struct Q {
+ Q() { count++; }
+ ~Q() { count--; }
};
-struct M : Q, P {
+struct M : Q, P {
S s;
-
Q q;
-
- P p;
-
- P p_arr[3];
-
- Q q_arr[2][3];
-
+ P p;
+ P p_arr[3];
+ Q q_arr[2][3];
};
-
-M gm;
-
-int main() {M m1;}
-
-// CHECK-LP64: .globl __ZN1MD1Ev
-// CHECK-LP64-NEXT: .weak_definition __ZN1MD1Ev
-// CHECK-LP64-NEXT: __ZN1MD1Ev:
-// CHECK-LP64: callq __ZN1MC1Ev
-// CHECK-LP64: callq __ZN1MD1Ev
-
-// CHECK-LP32: .globl __ZN1MD1Ev
-// CHECK-LP32-NEXT: .weak_definition __ZN1MD1Ev
-// CHECK-LP32-NEXT:__ZN1MD1Ev:
-// CHECK-LP32: call L__ZN1MC1Ev
-// CHECK-LP32: call L__ZN1MD1Ev
+
+// CHECK: define i32 @_Z1fv() nounwind
+int f() {
+ {
+ count = 1;
+ M a;
+ }
+
+ // CHECK: ret i32 1
+ return count;
+}
diff --git a/test/CodeGenCXX/deferred-global-init.cpp b/test/CodeGenCXX/deferred-global-init.cpp
index 570147905548..802042dd8b90 100644
--- a/test/CodeGenCXX/deferred-global-init.cpp
+++ b/test/CodeGenCXX/deferred-global-init.cpp
@@ -5,7 +5,7 @@ extern void* foo;
static void* const a = foo;
void* bar() { return a; }
-// CHECK: @a = internal global i8* null
+// CHECK: @_ZL1a = internal global i8* null
// CHECK: define internal void @__cxx_global_var_init
// CHECK: load i8** @foo
diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp
index 45728b7c0122..e44fdc5ed2de 100644
--- a/test/CodeGenCXX/derived-to-base.cpp
+++ b/test/CodeGenCXX/derived-to-base.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o -
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
struct A {
void f();
@@ -14,3 +14,23 @@ void f() {
b.f();
}
+
+// CHECK: define %struct.B* @_Z1fP1A(%struct.A* %a) nounwind
+B *f(A *a) {
+ // CHECK-NOT: br label
+ // CHECK: ret %struct.B*
+ return static_cast<B*>(a);
+}
+
+// PR5965
+namespace PR5965 {
+
+// CHECK: define %struct.A* @_ZN6PR59651fEP1B(%struct.B* %b) nounwind
+A *f(B* b) {
+ // CHECK-NOT: br label
+ // CHECK: ret %struct.A*
+ return b;
+}
+
+}
+
diff --git a/test/CodeGenCXX/dyncast.cpp b/test/CodeGenCXX/dyncast.cpp
index 054b972bb158..127cdd89683d 100644
--- a/test/CodeGenCXX/dyncast.cpp
+++ b/test/CodeGenCXX/dyncast.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -I%S -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll
// RUN: FileCheck -check-prefix LL --input-file=%t.ll %s
+// XFAIL: win32
#include <typeinfo>
@@ -69,14 +70,7 @@ void test1() {
// CHECK-LL-NEXT: [[ep:%.*]] = alloca %class.test1_E*, align 8
// CHECK-LL-NEXT: [[vp:%.*]] = alloca i8*, align 8
// CHECK-LL-NEXT: [[cvp:%.*]] = alloca i8*, align 8
-// CHECK-LL-NEXT: br i1 false, label %[[castnull:.*]], label %[[castnotnull:.*]]
-// CHECK-LL: [[castnotnull]]
-// CHECK-LL-NEXT: br label %[[castend:.*]]
-// CHECK-LL: [[castnull]]
-// CHECK-LL-NEXT: br label %[[castend]]
-// CHECK-LL: [[castend]]
-// CHECK-LL-NEXT: [[v0:%.*]] = phi %class.test1_A* [ bitcast (%class.test1_D* @test1_d to %class.test1_A*), %[[castnotnull]] ], [ null, %[[castnull]] ]
-// CHECK-LL-NEXT: store %class.test1_A* [[v0]], %class.test1_A** [[bp]]
+// CHECK-LL-NEXT: store %class.test1_A* bitcast (%class.test1_D* @test1_d to %class.test1_A*), %class.test1_A** [[bp]]
// CHECK-LL-NEXT: br i1 false, label %[[castnull2:.*]], label %[[castnotnull1:.*]]
// CHECK-LL: [[castnotnull1]]
// CHECK-LL-NEXT: [[vtable:%.*]] = load i8** bitcast (%class.test1_D* @test1_d to i8**)
@@ -333,23 +327,10 @@ void test1() {
// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str1, i32 0, i32 0), i32 12)
// CHECK-LL-NEXT: br label %[[ifend113]]
// CHECK-LL: [[ifend113]]
-// CHECK-LL-NEXT: br i1 false, label %[[castnull116:.*]], label %[[castnotnull115:.*]]
-// CHECK-LL: [[castnotnull115]]
-// CHECK-LL-NEXT: br label %[[castend117:.*]]
-// CHECK-LL: [[castnull116]]
-// CHECK-LL-NEXT: br label %[[castend117]]
-// CHECK-LL: [[castend117]]
-// CHECK-LL-NEXT: [[v62:%.*]] = phi %class.test1_E* [ bitcast (%class.test1_F* @test1_f to %class.test1_E*), %[[castnotnull115]] ], [ null, %[[castnull116]] ]
-// CHECK-LL-NEXT: store %class.test1_E* [[v62]], %class.test1_E** [[ep]]
+// CHECK-LL-NEXT: store %class.test1_E* bitcast (%class.test1_F* @test1_f to %class.test1_E*), %class.test1_E** [[ep]]
// CHECK-LL-NEXT: [[tmp118:%.*]] = load %class.test1_E** [[ep]]
-// CHECK-LL-NEXT: br i1 false, label %[[castnull120:.*]], label %[[castnotnull119:.*]]
-// CHECK-LL: [[castnotnull119]]
-// CHECK-LL-NEXT: br label %[[castend121:.*]]
-// CHECK-LL: [[castnull120]]
-// CHECK-LL-NEXT: br label %[[castend121]]
-// CHECK-LL: [[castend121]]
-// CHECK-LL-NEXT: [[v63:%.*]] = phi %class.test1_E* [ bitcast (%class.test1_F* @test1_f to %class.test1_E*), %[[castnotnull119]] ], [ null, %[[castnull120]] ]
-// CHECK-LL-NEXT: [[cmp122:%.*]] = icmp eq %class.test1_E* [[tmp118]], [[v63]]
+// CHECK-LL-NEXT: [[cmp122:%.*]] = icmp eq %class.test1_E* [[tmp118]], bitcast (%class.test1_F* @test1_f to %class.test1_E*) ; <i1> [#uses=1]
+
// CHECK-LL-NEXT: br i1 [[cmp122]], label %[[ifthen123:.*]], label %[[ifelse125:.*]]
// CHECK-LL: [[ifthen123]]
// CHECK-LL-NEXT: call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.str, i32 0, i32 0), i32 13)
diff --git a/test/CodeGenCXX/extern-c.cpp b/test/CodeGenCXX/extern-c.cpp
index 427a45aebb1e..ca5cd7372cad 100644
--- a/test/CodeGenCXX/extern-c.cpp
+++ b/test/CodeGenCXX/extern-c.cpp
@@ -10,4 +10,7 @@ extern int b;
// RUN: grep "@_ZN3foo1cE = global i32" %t | count 1
int c = 5;
+// RUN: not grep "@_ZN3foo1dE" %t
+extern "C" struct d;
+
}
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index b375aef4c8e0..b60e056d708f 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -7,6 +7,12 @@ struct A {
struct B { B(); ~B(); };
+struct C { void *field; };
+
+struct D { ~D(); };
+
+// CHECK: @c = global %struct.C zeroinitializer, align 8
+
// CHECK: call void @_ZN1AC1Ev(%struct.A* @a)
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
A a;
@@ -14,3 +20,12 @@ A a;
// CHECK: call void @_ZN1BC1Ev(%struct.A* @b)
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
B b;
+
+// PR6205: this should not require a global initializer
+// CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c)
+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 @__cxx_global_initialization() {
diff --git a/test/CodeGenCXX/global-llvm-constant.cpp b/test/CodeGenCXX/global-llvm-constant.cpp
index e799231ab744..ef1dcf0c59bf 100644
--- a/test/CodeGenCXX/global-llvm-constant.cpp
+++ b/test/CodeGenCXX/global-llvm-constant.cpp
@@ -7,4 +7,4 @@ struct A {
const A x;
-// CHECK: @x = internal global
+// CHECK: @_ZL1x = internal global
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
new file mode 100644
index 000000000000..1ae0f08f86ee
--- /dev/null
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+struct Global { };
+template<typename T> struct X { };
+
+
+namespace {
+ struct Anon { };
+
+ // CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global
+ Global anon0;
+}
+
+// CHECK: @anon1 = internal global
+Anon anon1;
+
+// CHECK: @anon2 = internal global
+X<Anon> anon2;
+
diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp
new file mode 100644
index 000000000000..cdad39852c9f
--- /dev/null
+++ b/test/CodeGenCXX/mangle-exprs.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+template < bool condition, typename T = void >
+struct enable_if { typedef T type; };
+
+template< typename T >
+struct enable_if< false, T > {};
+
+// PR5876
+namespace Casts {
+ template< unsigned O >
+ void implicit(typename enable_if< O <= 4 >::type* = 0) {
+ }
+
+ template< unsigned O >
+ void cstyle(typename enable_if< O <= (unsigned)4 >::type* = 0) {
+ }
+
+ template< unsigned O >
+ void functional(typename enable_if< O <= unsigned(4) >::type* = 0) {
+ }
+
+ template< unsigned O >
+ void static_(typename enable_if< O <= static_cast<unsigned>(4) >::type* = 0) {
+ }
+
+ // FIXME: Test const_cast, reinterpret_cast, dynamic_cast, which are
+ // a bit harder to use in template arguments.
+ template <unsigned N> struct T {};
+
+ template <int N> T<N> f() { return T<N>(); }
+
+ // CHECK: define void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE
+ template void implicit<4>(void*);
+ // CHECK: define void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+ template void cstyle<4>(void*);
+ // CHECK: define void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+ template void functional<4>(void*);
+ // CHECK: define void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+ template void static_<4>(void*);
+
+ // CHECK: define i64 @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
+ template T<6> f<6>();
+}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 5947587eec32..07183782e75e 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks | FileCheck %s
-
struct X { };
struct Y { };
@@ -9,6 +8,9 @@ struct Y { };
// CHECK: @_ZZN1N1gEvE1a = internal global
// CHECK: @_ZGVZN1N1gEvE1a = internal global
+//CHECK: @pr5966_i = external global
+//CHECK: @_ZL8pr5966_i = internal global
+
// CHECK: define zeroext i1 @_ZplRK1YRA100_P1X
bool operator+(const Y&, X* (&xs)[100]) { return false; }
@@ -310,7 +312,67 @@ template class Alloc<char>;
// CHECK: define void @_Z1fU13block_pointerFiiiE
void f(int (^)(int, int)) { }
-// PR5869
-// CHECK: define internal void @_ZL2f2v
-static void f2() {}
-void f3() { f2(); }
+void pr5966_foo() {
+ extern int pr5966_i;
+ pr5966_i = 0;
+}
+
+static int pr5966_i;
+
+void pr5966_bar() {
+ pr5966_i = 0;
+}
+
+namespace test0 {
+ int ovl(int x);
+ char ovl(double x);
+
+ template <class T> void f(T, char (&buffer)[sizeof(ovl(T()))]) {}
+
+ void test0() {
+ char buffer[1];
+ f(0.0, buffer);
+ }
+ // CHECK: define void @_ZN5test05test0Ev()
+ // CHECK: define linkonce_odr void @_ZN5test01fIdEEvT_RAszcl3ovlcvS1__EE_c(
+
+ void test1() {
+ char buffer[sizeof(int)];
+ f(1, buffer);
+ }
+ // CHECK: define void @_ZN5test05test1Ev()
+ // CHECK: define linkonce_odr void @_ZN5test01fIiEEvT_RAszcl3ovlcvS1__EE_c(
+
+ template <class T> void g(char (&buffer)[sizeof(T() + 5.0f)]) {}
+ void test2() {
+ char buffer[sizeof(float)];
+ g<float>(buffer);
+ }
+ // CHECK: define linkonce_odr void @_ZN5test01gIfEEvRAszplcvT__ELf40A00000E_c(
+
+ template <class T> void h(char (&buffer)[sizeof(T() + 5.0)]) {}
+ void test3() {
+ char buffer[sizeof(double)];
+ h<float>(buffer);
+ }
+ // CHECK: define linkonce_odr void @_ZN5test01hIfEEvRAszplcvT__ELd4014000000000000E_c(
+
+ template <class T> void j(char (&buffer)[sizeof(T().buffer)]) {}
+ struct A { double buffer[128]; };
+ void test4() {
+ char buffer[1024];
+ j<A>(buffer);
+ }
+ // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszmecvT__E6buffer_c(
+}
+
+namespace test1 {
+ template<typename T> struct X { };
+ template<template<class> class Y, typename T> void f(Y<T>) { }
+ // CHECK: define void @_ZN5test11fINS_1XEiEEvT_IT0_E
+ template void f(X<int>);
+}
+
+// CHECK: define internal void @_Z27functionWithInternalLinkagev()
+static void functionWithInternalLinkage() { }
+void g() { functionWithInternalLinkage(); }
diff --git a/test/CodeGenCXX/member-function-pointer-calls.cpp b/test/CodeGenCXX/member-function-pointer-calls.cpp
new file mode 100644
index 000000000000..e1f2eb78d414
--- /dev/null
+++ b/test/CodeGenCXX/member-function-pointer-calls.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+struct A {
+ virtual int vf1() { return 1; }
+ virtual int vf2() { return 2; }
+};
+
+int f(A* a, int (A::*fp)()) {
+ return (a->*fp)();
+}
+
+// CHECK: define i32 @_Z2g1v()
+int g1() {
+ A a;
+
+ // CHECK: call i32 @_ZN1A3vf1Ev
+ // CHECK-NEXT: ret i32
+ return f(&a, &A::vf1);
+}
+
+int g2() {
+ A a;
+
+ // CHECK: call i32 @_ZN1A3vf2Ev
+ // CHECK-NEXT: ret i32
+ return f(&a, &A::vf2);
+}
diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp
index e1353a72b396..f7c445b1cb10 100644
--- a/test/CodeGenCXX/member-function-pointers.cpp
+++ b/test/CodeGenCXX/member-function-pointers.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
-struct A { int a; void f(); virtual void vf(); };
+struct A { int a; void f(); virtual void vf1(); virtual void vf2(); };
struct B { int b; virtual void g(); };
struct C : B, A { };
@@ -9,17 +9,20 @@ void (A::*volatile vpa)();
void (B::*pb)();
void (C::*pc)();
-// CHECK: @pa2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 0 }, align 8
+// CHECK: @pa2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8
void (A::*pa2)() = &A::f;
// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8
-void (A::*pa3)() = &A::vf;
+void (A::*pa3)() = &A::vf1;
-// CHECK: @pc2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 16 }, align 8
+// CHECK: @pa4 = global %0 { i64 9, i64 0 }, align 8
+void (A::*pa4)() = &A::vf2;
+
+// CHECK: @pc2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8
void (C::*pc2)() = &C::f;
// CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8
-void (A::*pc3)() = &A::vf;
+void (A::*pc3)() = &A::vf1;
void f() {
// CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
@@ -43,7 +46,7 @@ void f() {
void f2() {
// CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0
- // CHECK: store i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64* [[pa2ptr]]
+ // CHECK: store i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64* [[pa2ptr]]
// CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1
// CHECK: store i64 0, i64* [[pa2adj]]
void (A::*pa2)() = &A::f;
@@ -52,7 +55,13 @@ void f2() {
// CHECK: store i64 1, i64* [[pa3ptr]]
// CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1
// CHECK: store i64 0, i64* [[pa3adj]]
- void (A::*pa3)() = &A::vf;
+ void (A::*pa3)() = &A::vf1;
+
+ // CHECK: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0
+ // CHECK: store i64 9, i64* [[pa4ptr]]
+ // CHECK: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1
+ // CHECK: store i64 0, i64* [[pa4adj]]
+ void (A::*pa4)() = &A::vf2;
}
void f3(A *a, A &ar) {
@@ -150,3 +159,17 @@ namespace MemberPointerImpCast {
(obj->*method)();
}
}
+
+// PR6258
+namespace PR6258 {
+
+ struct A {
+ void f(bool);
+ };
+
+ void (A::*pf)(bool) = &A::f;
+
+ void f() {
+ void (A::*pf)(bool) = &A::f;
+ }
+}
diff --git a/test/CodeGenCXX/member-initializers.cpp b/test/CodeGenCXX/member-initializers.cpp
new file mode 100644
index 000000000000..81dcee7e407a
--- /dev/null
+++ b/test/CodeGenCXX/member-initializers.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -O3 | FileCheck %s
+
+struct A {
+ virtual int f() { return 1; }
+};
+
+struct B : A {
+ B() : i(f()) { }
+
+ virtual int f() { return 2; }
+
+ int i;
+};
+
+// CHECK: define i32 @_Z1fv() nounwind
+int f() {
+ B b;
+
+ // CHECK: call i32 @_ZN1B1fEv
+ return b.i;
+}
+
+// Test that we don't try to fold the default value of j when initializing i.
+// CHECK: define i32 @_Z9test_foldv() nounwind
+int test_fold() {
+ struct A {
+ A(const int j = 1) : i(j) { }
+ int i;
+ };
+
+ // CHECK: ret i32 2
+ return A(2).i;
+}
+
diff --git a/test/CodeGenCXX/member-pointer-cast.cpp b/test/CodeGenCXX/member-pointer-cast.cpp
deleted file mode 100644
index 4937b037de53..000000000000
--- a/test/CodeGenCXX/member-pointer-cast.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
-
-struct A { int a; };
-struct B { int b; };
-struct C : B, A { };
-
-int A::*pa;
-int C::*pc;
-
-void f() {
- // CHECK: store i64 -1, i64* @pa
- pa = 0;
-
- // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 4
- // CHECK: store i64 [[ADJ]], i64* @pc
- pc = pa;
-
- // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 4
- // CHECK: store i64 [[ADJ]], i64* @pa
- pa = static_cast<int A::*>(pc);
-}
diff --git a/test/CodeGenCXX/member-pointers-zero-init.cpp b/test/CodeGenCXX/member-pointers-zero-init.cpp
deleted file mode 100644
index 18a2ead1ede5..000000000000
--- a/test/CodeGenCXX/member-pointers-zero-init.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm %s -o %t -triple=x86_64-apple-darwin9
-
-struct A {
- int i;
-};
-
-// RUN: grep "@a = global i64 -1" %t
-int A::* a;
-
-// RUN: grep "@aa = global \[2 x i64\] \[i64 -1, i64 -1\]" %t
-int A::* aa[2];
-
-// RUN: grep "@aaa = global \[2 x \[2 x i64\]\] \[\[2 x i64\] \[i64 -1, i64 -1\], \[2 x i64\] \[i64 -1, i64 -1\]\]" %t
-int A::* aaa[2][2];
-
-// RUN: grep "@b = global i64 -1" %t
-int A::* b = 0;
-
-void f() {
- // RUN: grep "%.* = icmp ne i64 %.*, -1" %t | count 2
- if (a) { }
- if (a != 0) { }
-
- // RUN: grep "%.* = icmp ne i64 -1, %.*" %t | count 1
- if (0 != a) { }
-
- // RUN: grep "%.* = icmp eq i64 %.*, -1" %t | count 1
- if (a == 0) { }
-
- // RUN: grep "%.* = icmp eq i64 -1, %.*" %t | count 1
- if (0 == a) { }
-
-}
-
diff --git a/test/CodeGenCXX/no-exceptions.cpp b/test/CodeGenCXX/no-exceptions.cpp
new file mode 100644
index 000000000000..da672c43f8d4
--- /dev/null
+++ b/test/CodeGenCXX/no-exceptions.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+void g();
+
+// CHECK: define void @_Z1fv() nounwind
+void f() throw (int) {
+
+ // CHECK-NOT: invoke void @_Z1gv
+ g();
+ // CHECK: call void @_Z1gv()
+ // CHECK: ret void
+}
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
new file mode 100644
index 000000000000..d96eb03b8d82
--- /dev/null
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+
+struct A { int a; int b; };
+struct B { int b; };
+struct C : B, A { };
+
+// Zero init.
+namespace ZeroInit {
+ // CHECK: @_ZN8ZeroInit1aE = global i64 -1
+ int A::* a;
+
+ // CHECK: @_ZN8ZeroInit2aaE = global [2 x i64] [i64 -1, i64 -1]
+ int A::* aa[2];
+
+ // CHECK: @_ZN8ZeroInit3aaaE = global [2 x [2 x i64]] {{\[}}[2 x i64] [i64 -1, i64 -1], [2 x i64] [i64 -1, i64 -1]]
+ int A::* aaa[2][2];
+
+ // CHECK: @_ZN8ZeroInit1bE = global i64 -1,
+ int A::* b = 0;
+
+ // CHECK: @_ZN8ZeroInit2saE = global %struct.anon { i64 -1 }
+ struct {
+ int A::*a;
+ } sa;
+
+ // CHECK: @_ZN8ZeroInit3ssaE =
+ // CHECK: [2 x i64] [i64 -1, i64 -1]
+ struct {
+ int A::*aa[2];
+ } ssa[2];
+
+ // CHECK: @_ZN8ZeroInit2ssE = global %1 { %struct.anon { i64 -1 } }
+ struct {
+ struct {
+ int A::*pa;
+ } s;
+ } ss;
+}
+
+// PR5674
+namespace PR5674 {
+ // CHECK: @_ZN6PR56742pbE = global i64 4
+ int A::*pb = &A::b;
+}
+
+// Casts.
+namespace Casts {
+
+int A::*pa;
+int C::*pc;
+
+void f() {
+ // CHECK: store i64 -1, i64* @_ZN5Casts2paE
+ pa = 0;
+
+ // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 4
+ // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2pcE
+ pc = pa;
+
+ // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 4
+ // CHECK: store i64 [[ADJ]], i64* @_ZN5Casts2paE
+ pa = static_cast<int A::*>(pc);
+}
+
+}
+
+// Comparisons
+namespace Comparisons {
+ void f() {
+ int A::*a;
+
+ // CHECK: icmp ne i64 {{.*}}, -1
+ if (a) { }
+
+ // CHECK: icmp ne i64 {{.*}}, -1
+ if (a != 0) { }
+
+ // CHECK: icmp ne i64 -1, {{.*}}
+ if (0 != a) { }
+
+ // CHECK: icmp eq i64 {{.*}}, -1
+ if (a == 0) { }
+
+ // CHECK: icmp eq i64 -1, {{.*}}
+ if (0 == a) { }
+ }
+}
diff --git a/test/CodeGenCXX/reference-init.cpp b/test/CodeGenCXX/reference-init.cpp
index 6c2c6a301681..9469c84eb5d0 100644
--- a/test/CodeGenCXX/reference-init.cpp
+++ b/test/CodeGenCXX/reference-init.cpp
@@ -14,3 +14,11 @@ namespace PR5911 {
int iarr[] = { 1 };
int test() { return f(iarr); }
}
+
+// radar 7574896
+struct Foo { int foo; };
+Foo& ignoreSetMutex = *(new Foo);
+
+// Binding to a bit-field that requires a temporary.
+struct { int bitfield : 3; } s = { 3 };
+const int &s2 = s.bitfield;
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index 6bec8bd8c384..39b5909fb9a4 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -38,6 +38,8 @@ void test_bool() {
bool_reference_return() = true;
a = bool_reference_return();
+
+ struct { const bool& b; } b = { true };
}
void test_scalar() {
@@ -54,6 +56,8 @@ void test_scalar() {
int_reference_return() = 10;
a = int_reference_return();
+
+ struct { const int& a; } agg = { 10 };
}
void test_complex() {
@@ -64,6 +68,8 @@ void test_complex() {
complex_int_reference_return() = 10i;
a = complex_int_reference_return();
+
+ struct { const _Complex int &a; } agg = { 10i };
}
void test_aggregate() {
@@ -74,6 +80,8 @@ void test_aggregate() {
aggregate_reference_return().a = 10;
c = aggregate_reference_return();
+
+ struct { const C& a; } agg = { C() };
}
int& reference_return() {
diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp
index 53a1d5e4c450..b3a2af2aafe3 100644
--- a/test/CodeGenCXX/static-data-member.cpp
+++ b/test/CodeGenCXX/static-data-member.cpp
@@ -1,4 +1,14 @@
// RUN: %clang_cc1 -emit-llvm -o - %s
+
+// CHECK: @_ZN1A1aE = constant i32 10
+
+// PR5564.
+struct A {
+ static const int a = 10;
+};
+
+const int A::a;
+
struct S {
static int i;
};
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index cbd90e789406..a67d137d6a1d 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -1,4 +1,10 @@
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
+
+// CHECK: @_ZZ2h2vE1i = weak global i32 0
+// CHECK: @_ZGVZ2h2vE1i = weak global i64 0
+
struct A {
A();
~A();
@@ -15,3 +21,16 @@ void g() {
// CHECK: call void @_ZN1AC1Ev(
static A& a = *new A;
}
+
+int a();
+void h() {
+ static const int i = a();
+}
+
+inline void h2() {
+ static int i = a();
+}
+
+void h3() {
+ h2();
+}
diff --git a/test/CodeGenCXX/temp-order.cpp b/test/CodeGenCXX/temp-order.cpp
index 05a9aed2defa..341cd0ca134a 100644
--- a/test/CodeGenCXX/temp-order.cpp
+++ b/test/CodeGenCXX/temp-order.cpp
@@ -129,10 +129,30 @@ static unsigned f6() {
return tt.Product;
}
+// 5, 2
+static unsigned f7() {
+ TempTracker tt;
+ {
+ (void)((A(tt, 2, false) && A(tt, 3, false)) || A(tt, 5, false));
+ }
+ return tt.Product;
+}
+
+// 5, 2
+static unsigned f8() {
+ TempTracker tt;
+
+ {
+ (void)((A(tt, 2) || A(tt, 3)) && A(tt, 5));
+ }
+ return tt.Product;
+}
+
extern "C" void error();
extern "C" void print(const char *Name, unsigned N);
-#define ORDER3(a, b, c) (pow(a, 1) * pow(b, 2) * pow(c, 3))
+#define ORDER2(a, b) (pow(a, 1) * pow(b, 2))
+#define ORDER3(a, b, c) (ORDER2(a, b) * pow(c, 3))
#define ORDER4(a, b, c, d) (ORDER3(a, b, c) * pow(d, 4))
#define ORDER5(a, b, c, d, e) (ORDER4(a, b, c, d) * pow(e, 5))
#define ORDER6(a, b, c, d, e, f) (ORDER5(a, b, c, d, e) * pow(f, 6))
@@ -171,6 +191,16 @@ void test() {
print("f6", f6());
if (f6() != ORDER6(3, 7, 11, 5, 13, 2))
error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 20)
+ print("f7", f7());
+ if (f7() != ORDER2(5, 2))
+ error();
+
+// CHECK: call void @print(i8* {{.*}}, i32 20)
+ print("f8", f8());
+ if (f8() != ORDER2(5, 2))
+ error();
}
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index 611781886b3e..3b624afd0ad1 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -249,3 +249,42 @@ namespace PR5867 {
g2(17);
}
}
+
+// PR6199
+namespace PR6199 {
+ struct A { ~A(); };
+
+ struct B { operator A(); };
+
+ // CHECK: define void @_ZN6PR61992f2IiEENS_1AET_
+ template<typename T> A f2(T) {
+ B b;
+ // CHECK: call void @_ZN6PR61991BcvNS_1AEEv
+ // CHECK-NEXT: ret void
+ return b;
+ }
+
+ template A f2<int>(int);
+
+}
+
+namespace T12 {
+
+struct A {
+ A();
+ ~A();
+ int f();
+};
+
+int& f(int);
+
+// CHECK: define void @_ZN3T121gEv
+void g() {
+ // CHECK: call void @_ZN3T121AC1Ev
+ // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
+ // CHECK-NEXT: call i32* @_ZN3T121fEi(
+ // CHECK-NEXT: call void @_ZN3T121AD1Ev(
+ int& i = f(A().f());
+}
+
+}
diff --git a/test/CodeGenCXX/threadsafe-statics.cpp b/test/CodeGenCXX/threadsafe-statics.cpp
new file mode 100644
index 000000000000..65ebc43c5d25
--- /dev/null
+++ b/test/CodeGenCXX/threadsafe-statics.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=WITH-TSS %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -fno-threadsafe-statics | FileCheck -check-prefix=NO-TSS %s
+
+int f();
+
+// WITH-TSS: define void @_Z1gv() nounwind
+// WITH-TSS: call i32 @__cxa_guard_acquire
+// WITH-TSS: call void @__cxa_guard_release
+// WITH-TSS: ret void
+void g() {
+ static int a = f();
+}
+
+// NO-TSS: define void @_Z1gv() nounwind
+// NO-TSS-NOT: call i32 @__cxa_guard_acquire
+// NO-TSS-NOT: call void @__cxa_guard_release
+// NO-TSS: ret void
diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp
index 9449618f2f2c..1670e4450237 100644
--- a/test/CodeGenCXX/throw-expressions.cpp
+++ b/test/CodeGenCXX/throw-expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// RUN: %clang_cc1 -emit-llvm-only -verify %s -Wno-unreachable-code
int val = 42;
int& test1() {
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
index 22e11fd76e31..9d671c4e5f0e 100644
--- a/test/CodeGenCXX/virt.cpp
+++ b/test/CodeGenCXX/virt.cpp
@@ -384,11 +384,11 @@ struct test16_D : test16_NV1, virtual test16_B2 {
// CHECK-LP64-NEXT: .quad __ZTcv0_n48_v0_n24_N8test16_D4foo1Ev
// CHECK-LP64-NEXT: .quad __ZN9test16_B24foo2Ev
// CHECK-LP64-NEXT: .quad __ZN9test16_B26foo_B2Ev
-// CHECK-LP64-NEXT .quad 16
-// CHECK-LP64-NEXT .quad 16
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 16
// CHECK-LP64-NEXT: .quad 0
// CHECK-LP64-NEXT: .quad 0
-// CHECK-LP64: .quad -16
+// CHECK-LP64-NEXT: .quad -16
// CHECK-LP64-NEXT: .quad -32
// CHECK-LP64-NEXT: .quad 0
// CHECK-LP64-NEXT: .quad 0
@@ -402,8 +402,8 @@ struct test16_D : test16_NV1, virtual test16_B2 {
// CHECK-LP64-NEXT: .quad __ZN8test16_B5foo_BEv
// CHECK-LP64-NEXT: .quad -48
// CHECK-LP64-NEXT: .quad __ZTI8test16_D
-// CHECK-LP64-NEXT .quad __ZTcvn16_n40_v16_n32_N8test16_D4foo1Ev
-// CHECK-LP64: .quad __ZN10test16_NV27foo_NV2Ev
+// CHECK-LP64-NEXT: .quad __ZTcvn16_n40_v16_n32_N8test16_D4foo1Ev
+// CHECK-LP64-NEXT: .quad __ZN10test16_NV27foo_NV2Ev
// CHECK-LP64-NEXT: .quad __ZN10test16_NV28foo_NV2bEv
@@ -696,32 +696,32 @@ void test12_foo() {
// FIXME: This is the wrong thunk, but until these issues are fixed, better
// than nothing.
-// CHECK-LPLL64:define weak %class.test8_D* @_ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev(%class.test8_D*)
-// CHECK-LPLL64: %{{retval|2}} = alloca %class.test8_D*
-// CHECK-LPLL64: %.addr = alloca %class.test8_D*
-// CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %.addr
-// CHECK-LPLL64: %{{this|3}} = load %class.test8_D** %.addr
-// CHECK-LPLL64: %{{1|4}} = bitcast %class.test8_D* %{{this|3}} to i8*
-// CHECK-LPLL64: %{{2|5}} = getelementptr inbounds i8* %{{1|4}}, i64 -16
-// CHECK-LPLL64: %{{3|6}} = bitcast i8* %{{2|5}} to %class.test8_D*
-// CHECK-LPLL64: %{{4|7}} = bitcast %class.test8_D* %{{3|6}} to i8*
-// CHECK-LPLL64: %{{5|8}} = bitcast %class.test8_D* %3 to i64**
-// CHECK-LPLL64: %{{vtable|9}} = load i64** %{{5|8}}
-// CHECK-LPLL64: %{{6|10}} = getelementptr inbounds i64* %{{vtable|9}}, i64 -9
-// CHECK-LPLL64: %{{7|11}} = load i64* %{{6|10}}
-// CHECK-LPLL64: %{{8|12}} = getelementptr i8* %{{4|7}}, i64 %{{7|11}}
-// CHECK-LPLL64: %{{9|13}} = bitcast i8* %{{8|12}} to %class.test8_D*
-// CHECK-LPLL64: %{{call|14}} = call %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D* %{{9|13}})
-// CHECK-LPLL64: store %class.test8_D* %{{call|14}}, %class.test8_D** %{{retval|2}}
-// CHECK-LPLL64: %{{10|15}} = load %class.test8_D** %{{retval|2}}
-// CHECK-LPLL64: ret %class.test8_D* %{{10|15}}
-// CHECK-LPLL64:}
+// CHECK-LPLL64define weak %class.test8_D* @_ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev(%class.test8_D*)
+// CHECK-LPLL64 %{{retval|2}} = alloca %class.test8_D*
+// CHECK-LPLL64 %.addr = alloca %class.test8_D*
+// CHECK-LPLL64 store %class.test8_D* %0, %class.test8_D** %.addr
+// CHECK-LPLL64 %{{this|3}} = load %class.test8_D** %.addr
+// CHECK-LPLL64 %{{1|4}} = bitcast %class.test8_D* %{{this|3}} to i8*
+// CHECK-LPLL64 %{{2|5}} = getelementptr inbounds i8* %{{1|4}}, i64 -16
+// CHECK-LPLL64 %{{3|6}} = bitcast i8* %{{2|5}} to %class.test8_D*
+// CHECK-LPLL64 %{{4|7}} = bitcast %class.test8_D* %{{3|6}} to i8*
+// CHECK-LPLL64 %{{5|8}} = bitcast %class.test8_D* %3 to i64**
+// CHECK-LPLL64 %{{vtable|9}} = load i64** %{{5|8}}
+// CHECK-LPLL64 %{{6|10}} = getelementptr inbounds i64* %{{vtable|9}}, i64 -9
+// CHECK-LPLL64 %{{7|11}} = load i64* %{{6|10}}
+// CHECK-LPLL64 %{{8|12}} = getelementptr i8* %{{4|7}}, i64 %{{7|11}}
+// CHECK-LPLL64 %{{9|13}} = bitcast i8* %{{8|12}} to %class.test8_D*
+// CHECK-LPLL64 %{{call|14}} = call %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D* %{{9|13}})
+// CHECK-LPLL64 store %class.test8_D* %{{call|14}}, %class.test8_D** %{{retval|2}}
+// CHECK-LPLL64 %{{10|15}} = load %class.test8_D** %{{retval|2}}
+// CHECK-LPLL64 ret %class.test8_D* %{{10|15}}
+// CHECK-LPLL64}
// CHECK-LPLL64:define weak %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%{{class.test8_D|.*}}*)
-// CHECK-LPLL64: %{{retval|2}} = alloca %class.test8_D*
-// CHECK-LPLL64: %.addr = alloca %class.test8_D*
-// CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %.addr
-// CHECK-LPLL64: %{{this|3}} = load %class.test8_D** %.addr
+// CHECK-LPLL64: %{{retval|1}} = alloca %class.test8_D*
+// CHECK-LPLL64: %{{.addr|2}} = alloca %class.test8_D*
+// CHECK-LPLL64: store %class.test8_D* %0, %class.test8_D** %{{.addr|2}}
+// CHECK-LPLL64: %{{this|3}} = load %class.test8_D** %{{.addr|2}}
// CHECK-LPLL64: %{{call|4}} = call %class.test8_D* @_ZN8test16_D4foo1Ev(%class.test8_D* %{{this|3}})
// CHECK-LPLL64: %{{1|5}} = icmp ne %class.test8_D* %{{call|4}}, null
// CHECK-LPLL64: br i1 %{{1|5}}, label %{{2|6}}, label %{{12|17}}
diff --git a/test/CodeGenCXX/virtual-bases.cpp b/test/CodeGenCXX/virtual-bases.cpp
index 1eaef3fa3af4..200f21a5da72 100644
--- a/test/CodeGenCXX/virtual-bases.cpp
+++ b/test/CodeGenCXX/virtual-bases.cpp
@@ -15,3 +15,11 @@ struct B : virtual A {
// CHECK: define void @_ZN1BC1Ev(%struct.B* %this)
// CHECK: define void @_ZN1BC2Ev(%struct.B* %this, i8** %vtt)
B::B() { }
+
+struct C : virtual A {
+ C(bool);
+};
+
+// CHECK: define void @_ZN1CC1Eb(%struct.B* %this, i1 zeroext)
+// CHECK: define void @_ZN1CC2Eb(%struct.B* %this, i8** %vtt, i1 zeroext)
+C::C(bool) { }
diff --git a/test/CodeGenCXX/virtual-function-calls.cpp b/test/CodeGenCXX/virtual-function-calls.cpp
index 0b3a684301eb..46e7b2d37f77 100644
--- a/test/CodeGenCXX/virtual-function-calls.cpp
+++ b/test/CodeGenCXX/virtual-function-calls.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
// PR5021
+namespace PR5021 {
+
struct A {
virtual void f(char);
};
@@ -16,4 +18,21 @@ struct B : virtual A {
void f(B * b) {
b->f();
-} \ No newline at end of file
+}
+
+}
+
+namespace Test1 {
+ struct A {
+ virtual ~A();
+ };
+
+ struct B : A {
+ virtual ~B();
+ virtual void f();
+ };
+
+ void f(B *b) {
+ b->f();
+ }
+}
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
new file mode 100644
index 000000000000..5edd27b8b279
--- /dev/null
+++ b/test/CodeGenCXX/visibility.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+#define HIDDEN __attribute__((visibility("hidden")))
+#define PROTECTED __attribute__((visibility("protected")))
+#define DEFAULT __attribute__((visibility("default")))
+
+// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
+
+namespace Test1 {
+ // CHECK: define hidden void @_ZN5Test11fEv
+ void HIDDEN f() { }
+
+}
+
+namespace Test2 {
+ struct HIDDEN A {
+ void f();
+ };
+
+ // A::f is a member function of a hidden class.
+ // CHECK: define hidden void @_ZN5Test21A1fEv
+ void A::f() { }
+}
+
+namespace Test3 {
+ struct HIDDEN A {
+ struct B {
+ void f();
+ };
+ };
+
+ // B is a nested class where its parent class is hidden.
+ // CHECK: define hidden void @_ZN5Test31A1B1fEv
+ void A::B::f() { }
+}
+
+namespace Test4 HIDDEN {
+ int VariableInHiddenNamespace = 10;
+
+ // Test4::g is in a hidden namespace.
+ // CHECK: define hidden void @_ZN5Test41gEv
+ void g() { }
+
+ struct DEFAULT A {
+ void f();
+ };
+
+ // A has default visibility.
+ // CHECK: define void @_ZN5Test41A1fEv
+ void A::f() { }
+}
+
+namespace Test5 {
+
+ namespace NS HIDDEN {
+ // f is in NS which is hidden.
+ // CHECK: define hidden void @_ZN5Test52NS1fEv()
+ void f() { }
+ }
+
+ namespace NS {
+ // g is in NS, but this NS decl is not hidden.
+ // CHECK: define void @_ZN5Test52NS1gEv
+ void g() { }
+ }
+}
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
new file mode 100644
index 000000000000..8fbe486faa47
--- /dev/null
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -0,0 +1,367 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+// For now, just verify this doesn't crash.
+namespace test0 {
+ struct Obj {};
+
+ struct Base { virtual const Obj *foo() = 0; };
+ struct Derived : Base { virtual Obj *foo() { return new Obj(); } };
+
+ void test(Derived *D) { D->foo(); }
+}
+
+namespace Test1 {
+// CHECK: Vtable for 'Test1::A' (3 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test1::A RTTI
+// CHECK-NEXT: -- (Test1::A, 0) vtable address --
+// CHECK-NEXT: 2 | void Test1::A::f()
+struct A {
+ virtual void f();
+};
+void A::f() { }
+
+}
+
+namespace Test2 {
+
+// This is a smoke test of the vtable dumper.
+// CHECK: Vtable for 'Test2::A' (9 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test2::A RTTI
+// CHECK-NEXT: -- (Test2::A, 0) vtable address --
+// CHECK-NEXT: 2 | void Test2::A::f()
+// CHECK-NEXT: 3 | void Test2::A::f() const
+// CHECK-NEXT: 4 | Test2::A *Test2::A::g(int)
+// CHECK-NEXT: 5 | Test2::A::~A() [complete]
+// CHECK-NEXT: 6 | Test2::A::~A() [deleting]
+// CHECK-NEXT: 7 | void Test2::A::h()
+// CHECK-NEXT: 8 | Test2::A &Test2::A::operator=(Test2::A const &)
+struct A {
+ virtual void f();
+ virtual void f() const;
+
+ virtual A* g(int a);
+ virtual ~A();
+ virtual void h();
+ virtual A& operator=(const A&);
+};
+void A::f() { }
+
+// Another simple vtable dumper test.
+
+// CHECK: Vtable for 'Test2::B' (6 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test2::B RTTI
+// CHECK-NEXT: -- (Test2::B, 0) vtable address --
+// CHECK-NEXT: 2 | void Test2::B::f()
+// CHECK-NEXT: 3 | void Test2::B::g() [pure]
+// CHECK-NEXT: 4 | Test2::B::~B() [complete] [pure]
+// CHECK-NEXT: 5 | Test2::B::~B() [deleting] [pure]
+struct B {
+ virtual void f();
+ virtual void g() = 0;
+ virtual ~B() = 0;
+};
+void B::f() { }
+
+}
+
+namespace Test3 {
+
+// If a function in a derived class overrides a function in a primary base,
+// then the function should not have an entry in the derived class (unless the return
+// value requires adjusting).
+
+// CHECK: Vtable for 'Test3::A' (3 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test3::A RTTI
+// CHECK-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-NEXT: 2 | void Test3::A::f()
+struct A {
+ virtual void f();
+};
+void A::f() { }
+
+// CHECK: Vtable for 'Test3::B' (4 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test3::B RTTI
+// CHECK-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-NEXT: -- (Test3::B, 0) vtable address --
+// CHECK-NEXT: 2 | void Test3::B::f()
+// CHECK-NEXT: 3 | void Test3::B::g()
+struct B : A {
+ virtual void f();
+ virtual void g();
+};
+void B::f() { }
+
+// CHECK: Vtable for 'Test3::C' (5 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test3::C RTTI
+// CHECK-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-NEXT: 2 | void Test3::A::f()
+// CHECK-NEXT: 3 | void Test3::C::g()
+// CHECK-NEXT: 4 | void Test3::C::h()
+struct C : A {
+ virtual void g();
+ virtual void h();
+};
+void C::g() { }
+
+// CHECK: Vtable for 'Test3::D' (5 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test3::D RTTI
+// CHECK-NEXT: -- (Test3::A, 0) vtable address --
+// CHECK-NEXT: -- (Test3::B, 0) vtable address --
+// CHECK-NEXT: -- (Test3::D, 0) vtable address --
+// CHECK-NEXT: 2 | void Test3::D::f()
+// CHECK-NEXT: 3 | void Test3::D::g()
+// CHECK-NEXT: 4 | void Test3::D::h()
+struct D : B {
+ virtual void f();
+ virtual void g();
+ virtual void h();
+};
+
+void D::f() { }
+}
+
+namespace Test4 {
+
+// Test non-virtual result adjustments.
+
+struct R1 { int r1; };
+struct R2 { int r2; };
+struct R3 : R1, R2 { int r3; };
+
+struct A {
+ virtual R2 *f();
+};
+
+// CHECK: Vtable for 'Test4::B' (4 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test4::B RTTI
+// CHECK-NEXT: -- (Test4::A, 0) vtable address --
+// CHECK-NEXT: -- (Test4::B, 0) vtable address --
+// CHECK-NEXT: 2 | Test4::R3 *Test4::B::f()
+// CHECK-NEXT: [return adjustment: 4 non-virtual]
+// CHECK-NEXT: 3 | Test4::R3 *Test4::B::f()
+
+struct B : A {
+ virtual R3 *f();
+};
+R3 *B::f() { return 0; }
+
+// Test virtual result adjustments.
+struct V1 { int v1; };
+struct V2 : virtual V1 { int v1; };
+
+struct C {
+ virtual V1 *f();
+};
+
+// CHECK: Vtable for 'Test4::D' (4 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test4::D RTTI
+// CHECK-NEXT: -- (Test4::C, 0) vtable address --
+// CHECK-NEXT: -- (Test4::D, 0) vtable address --
+// CHECK-NEXT: 2 | Test4::V2 *Test4::D::f()
+// CHECK-NEXT: [return adjustment: 0 non-virtual, -24 vbase offset offset]
+// CHECK-NEXT: 3 | Test4::V2 *Test4::D::f()
+struct D : C {
+ virtual V2 *f();
+};
+V2 *D::f() { return 0; };
+
+// Virtual result adjustments with an additional non-virtual adjustment.
+struct V3 : virtual R3 { int r3; };
+
+// CHECK: Vtable for 'Test4::E' (4 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test4::E RTTI
+// CHECK-NEXT: -- (Test4::A, 0) vtable address --
+// CHECK-NEXT: -- (Test4::E, 0) vtable address --
+// CHECK-NEXT: 2 | Test4::V3 *Test4::E::f()
+// CHECK-NEXT: [return adjustment: 4 non-virtual, -24 vbase offset offset]
+// CHECK-NEXT: 3 | Test4::V3 *Test4::E::f()
+
+struct E : A {
+ virtual V3 *f();
+};
+V3 *E::f() { return 0;}
+
+// Test that a pure virtual member doesn't get a thunk.
+
+// CHECK: Vtable for 'Test4::F' (5 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test4::F RTTI
+// CHECK-NEXT: -- (Test4::A, 0) vtable address --
+// CHECK-NEXT: -- (Test4::F, 0) vtable address --
+// CHECK-NEXT: 2 | Test4::R3 *Test4::F::f() [pure]
+// CHECK-NEXT: 3 | void Test4::F::g()
+// CHECK-NEXT: 4 | Test4::R3 *Test4::F::f() [pure]
+struct F : A {
+ virtual void g();
+ virtual R3 *f() = 0;
+};
+void F::g() { }
+
+}
+
+namespace Test5 {
+
+// Simple secondary vtables without 'this' pointer adjustments.
+struct A {
+ virtual void f();
+ virtual void g();
+ int a;
+};
+
+struct B1 : A {
+ virtual void f();
+ int b1;
+};
+
+struct B2 : A {
+ virtual void g();
+ int b2;
+};
+
+// CHECK: Vtable for 'Test5::C' (9 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test5::C RTTI
+// CHECK-NEXT: -- (Test5::A, 0) vtable address --
+// CHECK-NEXT: -- (Test5::B1, 0) vtable address --
+// CHECK-NEXT: -- (Test5::C, 0) vtable address --
+// CHECK-NEXT: 2 | void Test5::B1::f()
+// CHECK-NEXT: 3 | void Test5::A::g()
+// CHECK-NEXT: 4 | void Test5::C::h()
+// CHECK-NEXT: 5 | offset_to_top (-16)
+// CHECK-NEXT: 6 | Test5::C RTTI
+// CHECK-NEXT: -- (Test5::A, 16) vtable address --
+// CHECK-NEXT: -- (Test5::B2, 16) vtable address --
+// CHECK-NEXT: 7 | void Test5::A::f()
+// CHECK-NEXT: 8 | void Test5::B2::g()
+struct C : B1, B2 {
+ virtual void h();
+};
+void C::h() { }
+}
+
+namespace Test6 {
+
+// Simple non-virtual 'this' pointer adjustments.
+struct A1 {
+ virtual void f();
+ int a;
+};
+
+struct A2 {
+ virtual void f();
+ int a;
+};
+
+// CHECK: Vtable for 'Test6::C' (6 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test6::C RTTI
+// CHECK-NEXT: -- (Test6::A1, 0) vtable address --
+// CHECK-NEXT: -- (Test6::C, 0) vtable address --
+// CHECK-NEXT: 2 | void Test6::C::f()
+// CHECK-NEXT: 3 | offset_to_top (-16)
+// CHECK-NEXT: 4 | Test6::C RTTI
+// CHECK-NEXT: -- (Test6::A2, 16) vtable address --
+// CHECK-NEXT: 5 | void Test6::C::f()
+// CHECK-NEXT: [this adjustment: -16 non-virtual]
+struct C : A1, A2 {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test7 {
+
+// Test that the D::f overrider for A::f have different 'this' pointer
+// adjustments in the two A base subobjects.
+
+struct A {
+ virtual void f();
+ int a;
+};
+
+struct B1 : A { };
+struct B2 : A { };
+
+struct C { virtual void c(); };
+
+// CHECK: Vtable for 'Test7::D' (10 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test7::D RTTI
+// CHECK-NEXT: -- (Test7::C, 0) vtable address --
+// CHECK-NEXT: -- (Test7::D, 0) vtable address --
+// CHECK-NEXT: 2 | void Test7::C::c()
+// CHECK-NEXT: 3 | void Test7::D::f()
+// CHECK-NEXT: 4 | offset_to_top (-8)
+// CHECK-NEXT: 5 | Test7::D RTTI
+// CHECK-NEXT: -- (Test7::A, 8) vtable address --
+// CHECK-NEXT: -- (Test7::B1, 8) vtable address --
+// CHECK-NEXT: 6 | void Test7::D::f()
+// CHECK-NEXT: [this adjustment: -8 non-virtual]
+// CHECK-NEXT: 7 | offset_to_top (-24)
+// CHECK-NEXT: 8 | Test7::D RTTI
+// CHECK-NEXT: -- (Test7::A, 24) vtable address --
+// CHECK-NEXT: -- (Test7::B2, 24) vtable address --
+// CHECK-NEXT: 9 | void Test7::D::f()
+// CHECK-NEXT: [this adjustment: -24 non-virtual]
+struct D : C, B1, B2 {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test8 {
+
+// Test that we don't try to layout vtables for classes that don't have
+// virtual bases or virtual member functions.
+
+struct A { };
+
+// CHECK: Vtable for 'Test8::B' (3 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test8::B RTTI
+// CHECK-NEXT: -- (Test8::B, 0) vtable address --
+// CHECK-NEXT: 2 | void Test8::B::f()
+struct B : A {
+ virtual void f();
+};
+void B::f() { }
+
+}
+
+namespace Test9 {
+
+// Simple test of vbase offsets.
+
+struct A1 { int a1; };
+struct A2 { int a2; };
+
+// CHECK: Vtable for 'Test9::B' (5 entries).
+// CHECK-NEXT: 0 | vbase_offset (16)
+// CHECK-NEXT: 1 | vbase_offset (12)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test9::B RTTI
+// CHECK-NEXT: -- (Test9::B, 0) vtable address --
+// CHECK-NEXT: 4 | void Test9::B::f()
+struct B : virtual A1, virtual A2 {
+ int b;
+
+ virtual void f();
+};
+
+
+void B::f() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
new file mode 100644
index 000000000000..92e011752f3f
--- /dev/null
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Field {
+ Field();
+ ~Field();
+};
+
+struct Base {
+ Base();
+ ~Base();
+};
+
+struct A : Base {
+ A();
+ ~A();
+
+ virtual void f();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN1AC1Ev(
+// CHECK: call void @_ZN4BaseC2Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldC1Ev(
+// CHECK: ret void
+A::A() { }
+
+// CHECK: define void @_ZN1AD1Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldD1Ev(
+// CHECK: call void @_ZN4BaseD2Ev(
+// CHECK: ret void
+A::~A() { }
+
+struct B : Base {
+ virtual void f();
+
+ Field field;
+};
+
+void f() { B b; }
+
+// CHECK: define linkonce_odr void @_ZN1BC1Ev(
+// CHECK: call void @_ZN4BaseC2Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldC1Ev
+// CHECK: ret void
+
+// CHECK: define linkonce_odr void @_ZN1BD1Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldD1Ev(
+// CHECK: call void @_ZN4BaseD2Ev(
+// CHECK: ret void
diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp
new file mode 100644
index 000000000000..d13c0e4888fd
--- /dev/null
+++ b/test/CodeGenCXX/x86_32-arguments.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// Non-trivial dtors, should both be passed indirectly.
+struct S {
+ ~S();
+ int s;
+};
+
+// CHECK: define void @_Z1fv(%struct.S* noalias sret %
+S f() { return S(); }
+// CHECK: define void @_Z1f1S(%struct.S*)
+void f(S) { }
+
+// Non-trivial dtors, should both be passed indirectly.
+class C {
+ ~C();
+ double c;
+};
+
+// CHECK: define void @_Z1gv(%class.C* noalias sret %
+C g() { return C(); }
+
+// CHECK: define void @_Z1f1C(%class.C*)
+void f(C) { }