aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX')
-rw-r--r--test/CodeGenCXX/PR4827-cast.cpp5
-rw-r--r--test/CodeGenCXX/PR4890-debug-info-dtor.cpp6
-rw-r--r--test/CodeGenCXX/PR4983-constructor-conversion.cpp16
-rw-r--r--test/CodeGenCXX/PR5050-constructor-conversion.cpp19
-rw-r--r--test/CodeGenCXX/PR5093-static-member-function.cpp9
-rw-r--r--test/CodeGenCXX/anonymous-namespaces.cpp22
-rw-r--r--test/CodeGenCXX/anonymous-union-member-initializer.cpp12
-rw-r--r--test/CodeGenCXX/array-pointer-decay.cpp7
-rw-r--r--test/CodeGenCXX/attr.cpp36
-rw-r--r--test/CodeGenCXX/cast-conversion.cpp33
-rw-r--r--test/CodeGenCXX/class-layout.cpp5
-rw-r--r--test/CodeGenCXX/conditional-expr-lvalue.cpp7
-rw-r--r--test/CodeGenCXX/constructor-conversion.cpp55
-rw-r--r--test/CodeGenCXX/constructor-default-arg.cpp40
-rw-r--r--test/CodeGenCXX/constructor-for-array-members.cpp44
-rw-r--r--test/CodeGenCXX/constructor-init-reference.cpp9
-rw-r--r--test/CodeGenCXX/constructor-init.cpp61
-rw-r--r--test/CodeGenCXX/constructor-template.cpp56
-rw-r--r--test/CodeGenCXX/conversion-function.cpp115
-rw-r--r--test/CodeGenCXX/convert-to-fptr.cpp47
-rw-r--r--test/CodeGenCXX/copy-assign-synthesis-1.cpp109
-rw-r--r--test/CodeGenCXX/copy-assign-synthesis.cpp79
-rw-r--r--test/CodeGenCXX/copy-constructor-elim.cpp43
-rw-r--r--test/CodeGenCXX/copy-constructor-synthesis.cpp110
-rw-r--r--test/CodeGenCXX/decl-ref-init.cpp31
-rw-r--r--test/CodeGenCXX/default-arg-temps.cpp14
-rw-r--r--test/CodeGenCXX/default-constructor-for-members.cpp24
-rw-r--r--test/CodeGenCXX/default-destructor-synthesis.cpp60
-rw-r--r--test/CodeGenCXX/delete.cpp37
-rw-r--r--test/CodeGenCXX/derived-to-base.cpp16
-rw-r--r--test/CodeGenCXX/destructor-calls.cpp41
-rw-r--r--test/CodeGenCXX/destructors.cpp30
-rw-r--r--test/CodeGenCXX/devirtualize-virtual-function-calls.cpp47
-rw-r--r--test/CodeGenCXX/explicit-instantiation.cpp13
-rw-r--r--test/CodeGenCXX/function-template-specialization.cpp15
-rw-r--r--test/CodeGenCXX/global-init.cpp16
-rw-r--r--test/CodeGenCXX/mangle-extreme.cpp47
-rw-r--r--test/CodeGenCXX/mangle-subst-std.cpp39
-rw-r--r--test/CodeGenCXX/mangle-subst.cpp56
-rw-r--r--test/CodeGenCXX/mangle.cpp190
-rw-r--r--test/CodeGenCXX/member-function-pointers.cpp73
-rw-r--r--test/CodeGenCXX/member-functions.cpp2
-rw-r--r--test/CodeGenCXX/member-pointers-zero-init.cpp34
-rw-r--r--test/CodeGenCXX/namespace-aliases.cpp3
-rw-r--r--test/CodeGenCXX/nested-base-member-access.cpp52
-rw-r--r--test/CodeGenCXX/new.cpp23
-rw-r--r--test/CodeGenCXX/nullptr.cpp7
-rw-r--r--test/CodeGenCXX/overload-binop-implicitconvert.cpp22
-rw-r--r--test/CodeGenCXX/predefined-expr-sizeof.cpp30
-rw-r--r--test/CodeGenCXX/predefined-expr.cpp226
-rw-r--r--test/CodeGenCXX/references.cpp13
-rw-r--r--test/CodeGenCXX/reinterpret-cast.cpp12
-rw-r--r--test/CodeGenCXX/static-data-member.cpp8
-rw-r--r--test/CodeGenCXX/static-init.cpp13
-rw-r--r--test/CodeGenCXX/temp-1.cpp83
-rw-r--r--test/CodeGenCXX/template-anonymous-union-member-initializer.cpp10
-rw-r--r--test/CodeGenCXX/trivial-constructor-init.cpp21
-rw-r--r--test/CodeGenCXX/virt.cpp1024
-rw-r--r--test/CodeGenCXX/virtual-base-cast.cpp9
-rw-r--r--test/CodeGenCXX/virtual-function-calls.cpp11
-rw-r--r--test/CodeGenCXX/vtable-cast-crash.cpp21
-rw-r--r--test/CodeGenCXX/x86_64-arguments.cpp10
62 files changed, 3282 insertions, 46 deletions
diff --git a/test/CodeGenCXX/PR4827-cast.cpp b/test/CodeGenCXX/PR4827-cast.cpp
new file mode 100644
index 000000000000..958798d77f60
--- /dev/null
+++ b/test/CodeGenCXX/PR4827-cast.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-cc -emit-llvm -o - %s
+struct A;
+struct B;
+extern A *f();
+void a() { (B *) f(); }
diff --git a/test/CodeGenCXX/PR4890-debug-info-dtor.cpp b/test/CodeGenCXX/PR4890-debug-info-dtor.cpp
new file mode 100644
index 000000000000..a0d3a8ddac23
--- /dev/null
+++ b/test/CodeGenCXX/PR4890-debug-info-dtor.cpp
@@ -0,0 +1,6 @@
+// RUN: clang-cc -emit-llvm-only -g %s
+struct X {
+ ~X();
+};
+
+X::~X() { }
diff --git a/test/CodeGenCXX/PR4983-constructor-conversion.cpp b/test/CodeGenCXX/PR4983-constructor-conversion.cpp
new file mode 100644
index 000000000000..31eae2e791f6
--- /dev/null
+++ b/test/CodeGenCXX/PR4983-constructor-conversion.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-cc -emit-llvm-only %s
+
+struct A {
+ A(const char *s){}
+};
+
+struct B {
+ A a;
+
+ B() : a("test") { }
+};
+
+void f() {
+ A a("test");
+}
+
diff --git a/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
new file mode 100644
index 000000000000..e5f722c513de
--- /dev/null
+++ b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
@@ -0,0 +1,19 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+struct A { A(const A&, int i1 = 1); };
+
+struct B : A { };
+
+A f(const B &b) {
+ return b;
+}
+
+// CHECK-LP64: call __ZN1AC1ERKS_i
+
+// CHECK-LP32: call L__ZN1AC1ERKS_i
+
+
diff --git a/test/CodeGenCXX/PR5093-static-member-function.cpp b/test/CodeGenCXX/PR5093-static-member-function.cpp
new file mode 100644
index 000000000000..a27b08f6ada7
--- /dev/null
+++ b/test/CodeGenCXX/PR5093-static-member-function.cpp
@@ -0,0 +1,9 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+struct a {
+ static void f();
+};
+
+void g(a *a) {
+ // CHECK: call void @_ZN1a1fEv()
+ a->f();
+}
diff --git a/test/CodeGenCXX/anonymous-namespaces.cpp b/test/CodeGenCXX/anonymous-namespaces.cpp
new file mode 100644
index 000000000000..dcfd518d684b
--- /dev/null
+++ b/test/CodeGenCXX/anonymous-namespaces.cpp
@@ -0,0 +1,22 @@
+// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s
+
+namespace {
+ // CHECK: @_ZN12_GLOBAL__N_11aE = internal global i32 0
+ int a = 0;
+
+ // CHECK: define internal i32 @_ZN12_GLOBAL__N_13fooEv()
+ int foo() {
+ return 32;
+ }
+
+ // CHECK: define internal i32 @_ZN12_GLOBAL__N_11A3fooEv()
+ namespace A {
+ int foo() {
+ return 45;
+ }
+ }
+}
+
+int concrete() {
+ return a + foo() + A::foo();
+}
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
new file mode 100644
index 000000000000..2030f4053c90
--- /dev/null
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -0,0 +1,12 @@
+// RUN: clang-cc -emit-llvm -o - %s
+
+struct A {
+ union {
+ int a;
+ void* b;
+ };
+
+ A() : a(0) { }
+};
+
+A a;
diff --git a/test/CodeGenCXX/array-pointer-decay.cpp b/test/CodeGenCXX/array-pointer-decay.cpp
new file mode 100644
index 000000000000..5751b67b7491
--- /dev/null
+++ b/test/CodeGenCXX/array-pointer-decay.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-cc %s -emit-llvm -o -
+
+void f(const char*);
+
+void g() {
+ f("hello");
+}
diff --git a/test/CodeGenCXX/attr.cpp b/test/CodeGenCXX/attr.cpp
new file mode 100644
index 000000000000..8077b7839d88
--- /dev/null
+++ b/test/CodeGenCXX/attr.cpp
@@ -0,0 +1,36 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -O0 -S %s -o %t.s &&
+// RUN: FileCheck --input-file=%t.s %s
+
+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;
+
+void C::bar1() { }
+
+// CHECK:.align 1, 0x90
+// CHECK-NEXT:.globl __ZN1C4bar1Ev
+// CHECK-NEXT:__ZN1C4bar1Ev:
+
+
+void C::bar2() { }
+
+// CHECK:.align 1, 0x90
+// CHECK-NEXT:.globl __ZN1C4bar2Ev
+// CHECK-NEXT:__ZN1C4bar2Ev:
+
+
+void C::bar3() { }
+
+// CHECK:.align 10, 0x90
+// CHECK-NEXT:.globl __ZN1C4bar3Ev
+// CHECK-NEXT:__ZN1C4bar3Ev:
diff --git a/test/CodeGenCXX/cast-conversion.cpp b/test/CodeGenCXX/cast-conversion.cpp
new file mode 100644
index 000000000000..f571f549d094
--- /dev/null
+++ b/test/CodeGenCXX/cast-conversion.cpp
@@ -0,0 +1,33 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+struct A {
+ A(int);
+};
+
+struct B {
+ B(A);
+};
+
+int main () {
+ (B)10;
+ B(10);
+ static_cast<B>(10);
+}
+
+// CHECK-LP64: call __ZN1AC1Ei
+// CHECK-LP64: call __ZN1BC1E1A
+// CHECK-LP64: call __ZN1AC1Ei
+// CHECK-LP64: call __ZN1BC1E1A
+// CHECK-LP64: call __ZN1AC1Ei
+// CHECK-LP64: call __ZN1BC1E1A
+
+// CHECK-LP32: call L__ZN1AC1Ei
+// CHECK-LP32: call L__ZN1BC1E1A
+// CHECK-LP32: call L__ZN1AC1Ei
+// CHECK-LP32: call L__ZN1BC1E1A
+// CHECK-LP32: call L__ZN1AC1Ei
+// CHECK-LP32: call L__ZN1BC1E1A
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp
new file mode 100644
index 000000000000..7255d3e4f94d
--- /dev/null
+++ b/test/CodeGenCXX/class-layout.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-cc %s -emit-llvm -o %t &&
+
+// An extra byte shoudl be allocated for an empty class.
+// RUN: grep '%.truct.A = type { i8 }' %t
+struct A { } a;
diff --git a/test/CodeGenCXX/conditional-expr-lvalue.cpp b/test/CodeGenCXX/conditional-expr-lvalue.cpp
new file mode 100644
index 000000000000..7b3233a5bed0
--- /dev/null
+++ b/test/CodeGenCXX/conditional-expr-lvalue.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-cc -emit-llvm-only %s
+void f(bool flag) {
+ int a = 1;
+ int b = 2;
+
+ (flag ? a : b) = 3;
+}
diff --git a/test/CodeGenCXX/constructor-conversion.cpp b/test/CodeGenCXX/constructor-conversion.cpp
new file mode 100644
index 000000000000..980b230118d8
--- /dev/null
+++ b/test/CodeGenCXX/constructor-conversion.cpp
@@ -0,0 +1,55 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+class X { // ...
+public:
+ X(int) : iX(2), fX(2.3) , name("HELLO\n") { }
+
+ X(const char* arg, int ix=0) { iX = ix; fX = 6.0; name = arg+ix; }
+ X(): iX(100), fX(1.2) {}
+ int iX;
+ float fX;
+ const char *name;
+ void pr(void) {
+ printf("iX = %d fX = %f name = %s\n", iX, fX, name);
+ }
+};
+
+void g(X arg) {
+ arg.pr();
+}
+
+void f(X arg) {
+ X a = 1; // a = X(1)
+
+ a.pr();
+
+ X b = "Jessie"; // b=X("Jessie",0)
+
+ b.pr();
+
+
+ a = 2; // a = X(2)
+
+ a.pr();
+}
+
+
+int main() {
+ X x;
+ f(x);
+ g(3); // g(X(3))
+}
+
+// CHECK-LP64: call __ZN1XC1Ei
+// CHECK-LP64: call __ZN1XC1EPKci
+// CHECK-LP64: call __ZN1XC1Ev
+
+// CHECK-LP32: call L__ZN1XC1Ei
+// CHECK-LP32: call L__ZN1XC1EPKci
+// CHECK-LP32: call L__ZN1XC1Ev
diff --git a/test/CodeGenCXX/constructor-default-arg.cpp b/test/CodeGenCXX/constructor-default-arg.cpp
new file mode 100644
index 000000000000..7e6a7cd8f71a
--- /dev/null
+++ b/test/CodeGenCXX/constructor-default-arg.cpp
@@ -0,0 +1,40 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+
+struct C {
+ C() : iC(6) {}
+ int iC;
+};
+
+int foo() {
+ return 6;
+};
+
+class X { // ...
+public:
+ X(int) {}
+ X(const X&, int i = 1, int j = 2, int k = foo()) {
+ printf("X(const X&, %d, %d, %d)\n", i, j, k);
+ }
+};
+
+int main() {
+ X a(1);
+ X b(a, 2);
+ X c = b;
+ X d(a, 5, 6);
+}
+
+// CHECK-LP64: call __ZN1XC1ERKS_iii
+// CHECK-LP64: call __ZN1XC1ERKS_iii
+// CHECK-LP64: call __ZN1XC1ERKS_iii
+
+// CHECK-LP32: call L__ZN1XC1ERKS_iii
+// CHECK-LP32: call L__ZN1XC1ERKS_iii
+// CHECK-LP32: call L__ZN1XC1ERKS_iii
diff --git a/test/CodeGenCXX/constructor-for-array-members.cpp b/test/CodeGenCXX/constructor-for-array-members.cpp
new file mode 100644
index 000000000000..fbb13e0aa3c2
--- /dev/null
+++ b/test/CodeGenCXX/constructor-for-array-members.cpp
@@ -0,0 +1,44 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+int i = 1234;
+float vf = 1.00;
+
+struct S {
+ S() : iS(i++), f1(vf++) {printf("S::S()\n");}
+ ~S(){printf("S::~S(iS = %d f1 = %f)\n", iS, f1); }
+ int iS;
+ float f1;
+};
+
+struct M {
+ double dM;
+ S ARR_S[3];
+ void pr() {
+ for (int i = 0; i < 3; i++)
+ printf("ARR_S[%d].iS = %d ARR_S[%d].f1 = %f\n", i, ARR_S[i].iS, i, ARR_S[i].f1);
+
+ for (int i = 0; i < 2; i++)
+ for (int j = 0; j < 3; j++)
+ for (int k = 0; k < 4; k++)
+ printf("MULTI_ARR[%d][%d][%d].iS = %d MULTI_ARR[%d][%d][%d].f1 = %f\n",
+ i,j,k, MULTI_ARR[i][j][k].iS, i,j,k, MULTI_ARR[i][j][k].f1);
+
+ }
+
+ S MULTI_ARR[2][3][4];
+};
+
+int main() {
+ M m1;
+ m1.pr();
+}
+
+// CHECK-LP64: call __ZN1SC1Ev
+
+// CHECK-LP32: call L__ZN1SC1Ev
diff --git a/test/CodeGenCXX/constructor-init-reference.cpp b/test/CodeGenCXX/constructor-init-reference.cpp
new file mode 100644
index 000000000000..040441fde0f8
--- /dev/null
+++ b/test/CodeGenCXX/constructor-init-reference.cpp
@@ -0,0 +1,9 @@
+// RUN: clang-cc -emit-llvm -o - %s | grep "store i32\* @x, i32\*\*"
+
+int x;
+class A {
+ int& y;
+ A() : y(x) {}
+};
+A z;
+
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
new file mode 100644
index 000000000000..1b025126a345
--- /dev/null
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -0,0 +1,61 @@
+// RUN: clang-cc %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+struct M {
+ M() { printf("M()\n"); }
+ M(int i) { iM = i; printf("M(%d)\n", i); }
+ int iM;
+ void MPR() {printf("iM = %d\n", iM); };
+};
+
+struct P {
+ P() { printf("P()\n"); }
+ P(int i) { iP = i; printf("P(%d)\n", i); }
+ int iP;
+ void PPR() {printf("iP = %d\n", iP); };
+};
+
+struct Q {
+ Q() { printf("Q()\n"); }
+ Q(int i) { iQ = i; printf("Q(%d)\n", i); }
+ int iQ;
+ void QPR() {printf("iQ = %d\n", iQ); };
+};
+
+struct N : M , P, Q {
+ N() : f1(1.314), P(2000), ld(00.1234+f1), M(1000), Q(3000),
+ d1(3.4567), i1(1234), m1(100) { printf("N()\n"); }
+ M m1;
+ M m2;
+ float f1;
+ int i1;
+ float d1;
+ void PR() {
+ printf("f1 = %f d1 = %f i1 = %d ld = %f \n", f1,d1,i1, ld);
+ MPR();
+ PPR();
+ QPR();
+ printf("iQ = %d\n", iQ);
+ printf("iP = %d\n", iP);
+ printf("iM = %d\n", iM);
+ // FIXME. We don't yet support this syntax.
+ // printf("iQ = %d\n", (*this).iQ);
+ printf("iQ = %d\n", this->iQ);
+ printf("iP = %d\n", this->iP);
+ printf("iM = %d\n", this->iM);
+ }
+ float ld;
+ float ff;
+ M arr_m[3];
+ P arr_p[1][3];
+ Q arr_q[2][3][4];
+};
+
+int main() {
+ M m1;
+
+ N n1;
+ n1.PR();
+}
+
diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp
new file mode 100644
index 000000000000..8c4f2c912709
--- /dev/null
+++ b/test/CodeGenCXX/constructor-template.cpp
@@ -0,0 +1,56 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+// PR4826
+struct A {
+ A() {
+ }
+};
+
+template<typename T>
+struct B {
+ B(T) {}
+
+ A nodes;
+};
+
+
+// PR4853
+template <typename T> class List {
+public:
+ List(){ } // List<BinomialNode<int>*>::List() remains undefined.
+ ~List() {}
+};
+
+template <typename T> class Node {
+ int i;
+public:
+ Node(){ } // Node<BinomialNode<int>*>::Node() remains undefined.
+ ~Node() {}
+};
+
+
+template<typename T> class BinomialNode : Node<BinomialNode<T>*> {
+public:
+ BinomialNode(T value) {}
+ List<BinomialNode<T>*> nodes;
+};
+
+int main() {
+ B<int> *n = new B<int>(4);
+ BinomialNode<int> *node = new BinomialNode<int>(1);
+ delete node;
+}
+
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev:
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED2Ev:
+// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
+
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED2Ev:
+// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev:
diff --git a/test/CodeGenCXX/conversion-function.cpp b/test/CodeGenCXX/conversion-function.cpp
new file mode 100644
index 000000000000..0bfd4af7e265
--- /dev/null
+++ b/test/CodeGenCXX/conversion-function.cpp
@@ -0,0 +1,115 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+struct S {
+ operator int();
+};
+
+S::operator int() {
+ return 10;
+}
+
+
+class X { // ...
+ public: operator int() { printf("operator int()\n"); return iX; }
+ public: operator float() { printf("operator float()\n"); return fX; }
+ X() : iX(100), fX(1.234) {}
+ int iX;
+ float fX;
+};
+
+X x;
+
+struct Z {
+ operator X() { printf("perator X()\n"); x.iX += iZ; x.fX += fZ; return x; }
+ int iZ;
+ float fZ;
+ Z() : iZ(1), fZ(1.00) {}
+};
+
+Z z;
+
+class Y { // ...
+ public: operator Z(){printf("perator Z()\n"); return z; }
+};
+
+Y y;
+
+int count=0;
+class O { // ...
+public:
+ operator int(){ return ++iO; }
+ O() : iO(count++) {}
+ int iO;
+};
+
+void g(O a, O b) {
+ int i = (a) ? 1+a : 0;
+ int j = (a&&b) ? a+b : i;
+ if (a) { }
+ printf("i = %d j = %d a.iO = %d b.iO = %d\n", i, j, a.iO, b.iO);
+}
+
+int main() {
+ int c = X(Z(y)); // OK: y.operator Z().operator X().operator int()
+ printf("c = %d\n", c);
+ float f = X(Z(y));
+ printf("f = %f\n", f);
+ int i = x;
+ printf("i = %d float = %f\n", i, float(x));
+ i = int(X(Z(y)));
+ f = float(X(Z(y)));
+ printf("i = %d float = %f\n", i,f);
+ f = (float)x;
+ i = (int)x;
+ printf("i = %d float = %f\n", i,f);
+
+ int d = (X)((Z)y);
+ printf("d = %d\n", d);
+
+ int e = (int)((X)((Z)y));
+ printf("e = %d\n", e);
+ O o1, o2;
+ g(o1, o2);
+}
+
+// Test. Conversion in base class is visible in derived class.
+class XB {
+ int a;
+public:
+ operator int();
+};
+
+class Yb : public XB {
+ double b;
+public:
+ operator char();
+};
+
+void f(Yb& a) {
+ int i = a; // OK. calls XB::operator int();
+ char ch = a; // OK. calls Yb::operator char();
+}
+
+
+// CHECK-LP64: .globl __ZN1ScviEv
+// CHECK-LP64-NEXT: __ZN1ScviEv:
+// CHECK-LP64: call __ZN1Ycv1ZEv
+// CHECK-LP64: call __ZN1Zcv1XEv
+// CHECK-LP64: call __ZN1XcviEv
+// CHECK-LP64: call __ZN1XcvfEv
+// CHECK-LP64: call __ZN2XBcviEv
+// CHECK-LP64: call __ZN2YbcvcEv
+
+// CHECK-LP32: .globl __ZN1ScviEv
+// CHECK-LP32-NEXT: __ZN1ScviEv:
+// CHECK-LP32: call L__ZN1Ycv1ZEv
+// CHECK-LP32: call L__ZN1Zcv1XEv
+// CHECK-LP32: call L__ZN1XcviEv
+// CHECK-LP32: call L__ZN1XcvfEv
+// CHECK-LP32: call L__ZN2XBcviEv
+// CHECK-LP32: call L__ZN2YbcvcEv
diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp
new file mode 100644
index 000000000000..c0bd2f7b856e
--- /dev/null
+++ b/test/CodeGenCXX/convert-to-fptr.cpp
@@ -0,0 +1,47 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+int f1(int arg) { return arg; };
+
+int f2(float arg) { return int(arg); };
+
+typedef int (*fp1)(int);
+
+typedef int (*fp2)(float);
+
+struct A {
+ operator fp1() { return f1; }
+ operator fp2() { return f2; }
+} a;
+
+
+// Test for function reference.
+typedef int (&fr1)(int);
+typedef int (&fr2)(float);
+
+struct B {
+ operator fr1() { return f1; }
+ operator fr2() { return f2; }
+} b;
+
+int main()
+{
+ int i = a(10); // Calls f1 via pointer returned from conversion function
+ printf("i = %d\n", i);
+
+ int j = b(20); // Calls f1 via pointer returned from conversion function
+ printf("j = %d\n", j);
+ return 0;
+}
+
+// CHECK-LP64: call __ZN1AcvPFiiEEv
+// CHECK-LP64: call __ZN1BcvRFiiEEv
+
+// CHECK-LP32: call L__ZN1AcvPFiiEEv
+// CHECK-LP32: call L__ZN1BcvRFiiEEv
+
diff --git a/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
new file mode 100644
index 000000000000..d4a93afefbfa
--- /dev/null
+++ b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
@@ -0,0 +1,109 @@
+// RUN: clang-cc -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-cc -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+struct B {
+ B() : B1(3.14), B2(3.15), auB2(3.16) {}
+ float B1;
+ float B2;
+ void pr() {
+ printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1);
+ }
+
+ B& operator=(const B& arg) { B1 = arg.B1; B2 = arg.B2;
+ auB1 = arg.auB1; return *this; }
+ union {
+ float auB1;
+ float auB2;
+ };
+};
+
+struct M {
+ M() : M1(10), M2(11) , auM1(12) {}
+ int M1;
+ int M2;
+ void pr() {
+ printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2);
+ }
+ union {
+ int auM1;
+ int auM2;
+ };
+};
+
+struct N : B {
+ N() : N1(20), N2(21) {}
+ int N1;
+ int N2;
+ void pr() {
+ printf("N1 = %d N2 = %d\n", N1, N2);
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned j = 0; j < 2; j++)
+ printf("arr_b[%d][%d] = %f\n", i,j,arr_b[i][j].B1);
+ B::pr();
+ }
+ N& operator=(const N& arg) {
+ N1 = arg.N1; N2 = arg.N2;
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned j = 0; j < 2; j++)
+ arr_b[i][j] = arg.arr_b[i][j];
+ return *this;
+ }
+ B arr_b[3][2];
+};
+
+struct Q : B {
+ Q() : Q1(30), Q2(31) {}
+ int Q1;
+ int Q2;
+ void pr() {
+ printf("Q1 = %d Q2 = %d\n", Q1, Q2);
+ }
+};
+
+
+struct X : M , N {
+ X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {}
+ double d;
+ double d1;
+ double d2;
+ double d3;
+ void pr() {
+ printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3);
+ M::pr(); N::pr();
+ q1.pr(); q2.pr();
+ }
+
+ Q q1, q2;
+};
+
+
+X srcX;
+X dstX;
+X dstY;
+
+int main() {
+ dstY = dstX = srcX;
+ srcX.pr();
+ dstX.pr();
+ dstY.pr();
+}
+
+// CHECK-LP64: .globl __ZN1XaSERKS_
+// CHECK-LP64: .weak_definition __ZN1XaSERKS_
+// CHECK-LP64: __ZN1XaSERKS_:
+// CHECK-LP64: .globl __ZN1QaSERKS_
+// CHECK-LP64: .weak_definition __ZN1QaSERKS_
+// CHECK-LP64: __ZN1QaSERKS_:
+
+// CHECK-LP32: .globl __ZN1XaSERKS_
+// CHECK-LP32: .weak_definition __ZN1XaSERKS_
+// CHECK-LP32: __ZN1XaSERKS_:
+// CHECK-LP32: .globl __ZN1QaSERKS_
+// CHECK-LP32: .weak_definition __ZN1QaSERKS_
+// CHECK-LP32: __ZN1QaSERKS_:
+
diff --git a/test/CodeGenCXX/copy-assign-synthesis.cpp b/test/CodeGenCXX/copy-assign-synthesis.cpp
new file mode 100644
index 000000000000..f9baa8f03f3c
--- /dev/null
+++ b/test/CodeGenCXX/copy-assign-synthesis.cpp
@@ -0,0 +1,79 @@
+// RUN: clang-cc -emit-llvm -o %t %s &&
+// RUN: grep "_ZN1XaSERK1X" %t | count 0
+
+extern "C" int printf(...);
+
+struct B {
+ B() : B1(3.14), B2(3.15), auB2(3.16) {}
+ float B1;
+ float B2;
+ void pr() {
+ printf("B1 = %f B2 = %f auB1 = %f\n", B1, B2, auB1);
+ }
+
+ union {
+ float auB1;
+ float auB2;
+ };
+};
+
+struct M {
+ M() : M1(10), M2(11) , auM1(12) {}
+ int M1;
+ int M2;
+ void pr() {
+ printf("M1 = %d M2 = %d auM1 = %d auM2 = %d\n", M1, M2, auM1, auM2);
+ }
+ union {
+ int auM1;
+ int auM2;
+ };
+};
+
+struct N : B {
+ N() : N1(20), N2(21) {}
+ int N1;
+ int N2;
+ void pr() {
+ printf("N1 = %d N2 = %d\n", N1, N2);
+ B::pr();
+ }
+};
+
+struct Q {
+ Q() : Q1(30), Q2(31) {}
+ int Q1;
+ int Q2;
+ void pr() {
+ printf("Q1 = %d Q2 = %d\n", Q1, Q2);
+ }
+};
+
+
+struct X : M , N {
+ X() : d(0.0), d1(1.1), d2(1.2), d3(1.3) {}
+ double d;
+ double d1;
+ double d2;
+ double d3;
+ void pr() {
+ printf("d = %f d1 = %f d2 = %f d3 = %f\n", d, d1,d2,d3);
+ M::pr(); N::pr();
+ q1.pr(); q2.pr();
+ }
+
+ Q q1, q2;
+};
+
+
+X srcX;
+X dstX;
+X dstY;
+
+int main() {
+ dstY = dstX = srcX;
+ srcX.pr();
+ dstX.pr();
+ dstY.pr();
+}
+
diff --git a/test/CodeGenCXX/copy-constructor-elim.cpp b/test/CodeGenCXX/copy-constructor-elim.cpp
new file mode 100644
index 000000000000..daef92cdb767
--- /dev/null
+++ b/test/CodeGenCXX/copy-constructor-elim.cpp
@@ -0,0 +1,43 @@
+// RUN: clang-cc -emit-llvm -o %t %s &&
+// RUN: grep "_ZN1CC1ERK1C" %t | count 0 &&
+// RUN: grep "_ZN1SC1ERK1S" %t | count 0 &&
+// RUN: true
+
+extern "C" int printf(...);
+
+
+struct C {
+ C() : iC(6) {printf("C()\n"); }
+ C(const C& c) { printf("C(const C& c)\n"); }
+ int iC;
+};
+
+C foo() {
+ return C();
+};
+
+class X { // ...
+public:
+ X(int) {}
+ X(const X&, int i = 1, int j = 2, C c = foo()) {
+ printf("X(const X&, %d, %d, %d)\n", i, j, c.iC);
+ }
+};
+
+
+struct S {
+ S();
+};
+
+S::S() { printf("S()\n"); }
+
+void Call(S) {};
+
+int main() {
+ X a(1);
+ X b(a, 2);
+ X c = b;
+ X d(a, 5, 6);
+ S s;
+ Call(s);
+}
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
new file mode 100644
index 000000000000..47971afe61d4
--- /dev/null
+++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -0,0 +1,110 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s &&
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s &&
+// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+int init = 100;
+
+struct M {
+ int iM;
+ M() : iM(init++) {}
+};
+
+struct N {
+ int iN;
+ N() : iN(200) {}
+ N(N const & arg){this->iN = arg.iN; }
+};
+
+struct P {
+ int iP;
+ P() : iP(init++) {}
+};
+
+
+struct X : M, N, P { // ...
+ X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd),
+ au_i1(1234), au1_4("MASKED") {}
+ P p0;
+ void pr() {
+ printf("iM = %d iN = %d, m1.iM = %d\n", iM, iN, m1.iM);
+ printf("im = %d p0.iP = %d, p1.iP = %d\n", iP, p0.iP, p1.iP);
+ printf("f1 = %f d1 = %f i1 = %d name(%s) \n", f1, d1, i1, name);
+ printf("bf1 = %x bf2 = %x\n", bf1, bf2);
+ printf("au_i2 = %d\n", au_i2);
+ printf("au1_1 = %s\n", au1_1);
+ }
+ M m1;
+ P p1;
+ float f1;
+ double d1;
+ int i1;
+ const char *name;
+ unsigned bf1 : 8;
+ unsigned bf2 : 16;
+
+ union {
+ int au_i1;
+ int au_i2;
+ };
+ union {
+ const char * au1_1;
+ float au1_2;
+ int au1_3;
+ const char * au1_4;
+ };
+};
+
+static int ix = 1;
+// class with user-defined copy constructor.
+struct S {
+ S() : iS(ix++) { }
+ S(const S& arg) { *this = arg; }
+ int iS;
+};
+
+// class with trivial copy constructor.
+struct I {
+ I() : iI(ix++) { }
+ int iI;
+};
+
+struct XM {
+ XM() { }
+ double dXM;
+ S ARR_S[3][4][2];
+ void pr() {
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned j = 0; j < 4; j++)
+ for (unsigned k = 0; k < 2; k++)
+ printf("ARR_S[%d][%d][%d] = %d\n", i,j,k, ARR_S[i][j][k].iS);
+ for (unsigned i = 0; i < 3; i++)
+ for (unsigned k = 0; k < 2; k++)
+ printf("ARR_I[%d][%d] = %d\n", i,k, ARR_I[i][k].iI);
+ }
+ I ARR_I[3][2];
+};
+
+int main() {
+ X a;
+ X b(a);
+ b.pr();
+ X x;
+ X c(x);
+ c.pr();
+
+ XM m0;
+ XM m1 = m0;
+ m1.pr();
+}
+
+// CHECK-LP64: .globl __ZN1XC1ERKS_
+// CHECK-LP64: .weak_definition __ZN1XC1ERKS_
+// CHECK-LP64: __ZN1XC1ERKS_:
+
+// CHECK-LP32: .globl __ZN1XC1ERKS_
+// CHECK-LP32: .weak_definition __ZN1XC1ERKS_
+// CHECK-LP32: __ZN1XC1ERKS_:
diff --git a/test/CodeGenCXX/decl-ref-init.cpp b/test/CodeGenCXX/decl-ref-init.cpp
new file mode 100644
index 000000000000..27d200f4635b
--- /dev/null
+++ b/test/CodeGenCXX/decl-ref-init.cpp
@@ -0,0 +1,31 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s &&
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s &&
+// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+struct A {};
+
+struct B
+{
+ operator A&();
+};
+
+
+struct D : public B {
+ operator A();
+};
+
+extern B f();
+extern D d();
+
+int main() {
+ const A& rca = f();
+ const A& rca2 = d();
+}
+
+// CHECK-LP64: call __ZN1BcvR1AEv
+// CHECK-LP64: call __ZN1BcvR1AEv
+
+// CHECK-LP32: call L__ZN1BcvR1AEv
+// CHECK-LP32: call L__ZN1BcvR1AEv
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
index 2dcf773346a8..2651446669b8 100644
--- a/test/CodeGenCXX/default-arg-temps.cpp
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -7,9 +7,19 @@ struct T {
void f(const T& t = T());
+class X { // ...
+public:
+ X();
+ X(const X&, const T& t = T());
+};
+
void g() {
- // RUN: grep "call void @_ZN1TC1Ev" %t | count 2 &&
- // RUN: grep "call void @_ZN1TD1Ev" %t | count 2
+ // RUN: grep "call void @_ZN1TC1Ev" %t | count 4 &&
+ // RUN: grep "call void @_ZN1TD1Ev" %t | count 4
f();
f();
+
+ X a;
+ X b(a);
+ X c = a;
}
diff --git a/test/CodeGenCXX/default-constructor-for-members.cpp b/test/CodeGenCXX/default-constructor-for-members.cpp
new file mode 100644
index 000000000000..2d04bc941427
--- /dev/null
+++ b/test/CodeGenCXX/default-constructor-for-members.cpp
@@ -0,0 +1,24 @@
+// RUN: clang-cc -triple x86_64-apple-darwin -S %s -o %t-64.s &&
+// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s &&
+// RUN: clang-cc -triple i386-apple-darwin -S %s -o %t-32.s &&
+// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+struct S {
+ S() { printf("S::S()\n"); }
+ int iS;
+};
+
+struct M {
+ S ARR_S;
+};
+
+int main() {
+ M m1;
+}
+
+// CHECK-LP64: call __ZN1SC1Ev
+
+// CHECK-LP32: call L__ZN1SC1Ev
diff --git a/test/CodeGenCXX/default-destructor-synthesis.cpp b/test/CodeGenCXX/default-destructor-synthesis.cpp
new file mode 100644
index 000000000000..9cc802c85dfa
--- /dev/null
+++ b/test/CodeGenCXX/default-destructor-synthesis.cpp
@@ -0,0 +1,60 @@
+// RUN: clang-cc -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-cc -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 &&
+// RUN: true
+
+extern "C" int printf(...);
+
+int count = 1;
+
+struct S {
+ S() : iS(count++), fS(1.23) {};
+ ~S(){printf("S::~S(%d, %f)\n", iS, fS); };
+ int iS;
+ float fS;
+};
+
+struct Q {
+ Q() : iQ(count++), dQ(2.34) {};
+ ~Q(){printf("Q::~Q(%d, %f)\n", iQ, dQ); };
+ int iQ;
+ double dQ;
+};
+
+struct P {
+ P() : fP(3.45) , iP(count++) {};
+ ~P(){printf("P::~P(%d, %f)\n", iP, fP); };
+ float fP;
+ int iP;
+};
+
+struct M : Q, P {
+ S s;
+
+ Q q;
+
+ P p;
+
+ P p_arr[3];
+
+ Q q_arr[2][3];
+
+};
+
+M gm;
+
+int main() {M m1;}
+
+// CHECK-LP64: call __ZN1MC1Ev
+// CHECK-LP64: call __ZN1MD1Ev
+// CHECK-LP64: .globl __ZN1MD1Ev
+// CHECK-LP64-NEXT: .weak_definition __ZN1MD1Ev
+// CHECK-LP64-NEXT: __ZN1MD1Ev:
+
+
+// CHECK-LP32: call L__ZN1MC1Ev
+// CHECK-LP32: call L__ZN1MD1Ev
+// CHECK-LP32: .globl __ZN1MD1Ev
+// CHECK-LP32-NEXT: .weak_definition __ZN1MD1Ev
+// CHECK-LP32-NEXT:__ZN1MD1Ev:
diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp
new file mode 100644
index 000000000000..9e3feefefeda
--- /dev/null
+++ b/test/CodeGenCXX/delete.cpp
@@ -0,0 +1,37 @@
+// RUN: clang-cc %s -emit-llvm -o %t &&
+
+void t1(int *a) {
+ delete a;
+}
+
+struct S {
+ int a;
+};
+
+// POD types.
+void t3(S *s) {
+ delete s;
+}
+
+// Non-POD
+struct T {
+ ~T();
+ int a;
+};
+
+void t4(T *t) {
+ // RUN: grep "call void @_ZN1TD1Ev" %t | count 1
+ delete t;
+}
+
+// PR5102
+template <typename T>
+class A {
+ operator T *() const;
+};
+
+void f() {
+ A<char*> a;
+
+ delete a;
+}
diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp
new file mode 100644
index 000000000000..63492d604d17
--- /dev/null
+++ b/test/CodeGenCXX/derived-to-base.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-cc -emit-llvm %s -o -
+struct A {
+ void f();
+
+ int a;
+};
+
+struct B : A {
+ double b;
+};
+
+void f() {
+ B b;
+
+ b.f();
+}
diff --git a/test/CodeGenCXX/destructor-calls.cpp b/test/CodeGenCXX/destructor-calls.cpp
new file mode 100644
index 000000000000..3f0288b85c14
--- /dev/null
+++ b/test/CodeGenCXX/destructor-calls.cpp
@@ -0,0 +1,41 @@
+// RUN: clang-cc %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+static int val;
+
+struct B {
+ B() : iB(++val) { printf("B()\n"); }
+ int iB;
+ ~B() { printf("~B(%d)\n", iB); --val; }
+};
+
+struct M : B {
+ M() : iM(++val) { printf("M()\n"); }
+ int iM;
+ ~M() { printf("~M(%d)\n", iM); --val; }
+};
+
+struct P {
+ P() : iP(++val) { printf("P()\n"); }
+ int iP;
+ ~P() { printf("~P(%d)\n", iP); --val; }
+};
+
+struct N : M, P {
+ N() { printf("N()\n"); iN = ++val; }
+ ~N() { printf("~N(%d) val = %d\n", iN, --val); }
+ int iN;
+ M m;
+ P p;
+};
+
+struct O : B {
+ ~O() { return; }
+};
+
+int main() {
+ N n1;
+ N n2;
+ O o;
+}
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
new file mode 100644
index 000000000000..44d2b2936864
--- /dev/null
+++ b/test/CodeGenCXX/destructors.cpp
@@ -0,0 +1,30 @@
+// RUN: clang-cc %s -emit-llvm -o -
+struct A {
+ int a;
+
+ ~A();
+};
+
+// Base with non-trivial destructor
+struct B : A {
+ ~B();
+};
+
+B::~B() { }
+
+// Field with non-trivial destructor
+struct C {
+ A a;
+
+ ~C();
+};
+
+C::~C() { }
+
+// PR5084
+template<typename T>
+class A1 {
+ ~A1();
+};
+
+template<> A1<char>::~A1();
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
new file mode 100644
index 000000000000..cbf55ad61331
--- /dev/null
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -0,0 +1,47 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+ virtual void f();
+
+ A h();
+};
+
+A g();
+
+void f(A a, A *ap, A& ar) {
+ // This should not be a virtual function call.
+
+ // CHECK: call void @_ZN1A1fEv(%struct.A* %a)
+ a.f();
+
+ // CHECK: call void %
+ ap->f();
+
+ // CHECK: call void %
+ ar.f();
+
+ // CHECK: call void @_ZN1A1fEv
+ A().f();
+
+ // CHECK: call void @_ZN1A1fEv
+ g().f();
+
+ // CHECK: call void @_ZN1A1fEv
+ a.h().f();
+}
+
+struct B {
+ virtual void f();
+ ~B();
+
+ B h();
+};
+
+
+void f() {
+ // CHECK: call void @_ZN1B1fEv
+ B().f();
+
+ // CHECK: call void @_ZN1B1fEv
+ B().h().f();
+}
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 38966aad2deb..8a9e65c4e2e3 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -1,11 +1,14 @@
-// RUN: clang-cc -emit-llvm -femit-all-decls -o %t %s &&
-// RUN: grep "_ZNK4plusIillEclERKiRKl" %t | count 1
+// RUN: clang-cc -emit-llvm -triple i686-pc-linue-gnu -o %t %s &&
+// RUN: grep "define i32 @_ZNK4plusIillEclERKiRKl" %t | count 1
template<typename T, typename U, typename Result>
struct plus {
- Result operator()(const T& t, const U& u) const {
- return t + u;
- }
+ Result operator()(const T& t, const U& u) const;
};
+template<typename T, typename U, typename Result>
+Result plus<T, U, Result>::operator()(const T& t, const U& u) const {
+ return t + u;
+}
+
template struct plus<int, long, long>;
diff --git a/test/CodeGenCXX/function-template-specialization.cpp b/test/CodeGenCXX/function-template-specialization.cpp
index bea3af2bb5af..677be4cc0f9a 100644
--- a/test/CodeGenCXX/function-template-specialization.cpp
+++ b/test/CodeGenCXX/function-template-specialization.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-cc -emit-llvm %s -o %t &&
+// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s
template<typename T, typename U>
T* next(T* ptr, const U& diff);
@@ -8,11 +8,10 @@ T* next(T* ptr, const U& diff) {
}
void test(int *iptr, float *fptr, int diff) {
- // FIXME: should be "_Z4nextIiiEPT_S1_RKT0_"
- // RUN: grep "_Z4nextIiiEPiPiRKi" %t &&
+ // CHECK: _Z4nextIiiEPT_S1_RKT0_
iptr = next(iptr, diff);
- // FIXME: should be "_Z4nextIfiEPT_S1_RKT0_"
- // RUN: grep "_Z4nextIfiEPfPfRKi" %t &&
+
+ // CHECK: _Z4nextIfiEPT_S1_RKT0_
fptr = next(fptr, diff);
}
@@ -21,7 +20,7 @@ T* next(T* ptr, const U& diff);
void test2(int *iptr, double *dptr, int diff) {
iptr = next(iptr, diff);
- // FIXME: should be "_Z4nextIdiEPT_S1_RKT0_"
- // RUN: grep "_Z4nextIdiEPdPdRKi" %t
+
+ // CHECK: _Z4nextIdiEPT_S1_RKT0_
dptr = next(dptr, diff);
-} \ No newline at end of file
+}
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
new file mode 100644
index 000000000000..ae450e17e85e
--- /dev/null
+++ b/test/CodeGenCXX/global-init.cpp
@@ -0,0 +1,16 @@
+// RUN: clang-cc -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
+
+struct A {
+ A();
+ ~A();
+};
+
+struct B { B(); ~B(); };
+
+// 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;
+
+// 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;
diff --git a/test/CodeGenCXX/mangle-extreme.cpp b/test/CodeGenCXX/mangle-extreme.cpp
new file mode 100644
index 000000000000..77558d29d824
--- /dev/null
+++ b/test/CodeGenCXX/mangle-extreme.cpp
@@ -0,0 +1,47 @@
+// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct X { };
+
+// CHECK: define void @_Z1fPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP1XS13_S12_S11_S10_SZ_SY_SX_SW_SV_SU_ST_SS_SR_SQ_SP_SO_SN_SM_SL_SK_SJ_SI_SH_SG_SF_SE_SD_SC_SB_SA_S9_S8_S7_S6_S5_S4_S3_S2_S1_S0_S_(
+void f(X****************************************,
+ X****************************************,
+ X***************************************,
+ X**************************************,
+ X*************************************,
+ X************************************,
+ X***********************************,
+ X**********************************,
+ X*********************************,
+ X********************************,
+ X*******************************,
+ X******************************,
+ X*****************************,
+ X****************************,
+ X***************************,
+ X**************************,
+ X*************************,
+ X************************,
+ X***********************,
+ X**********************,
+ X*********************,
+ X********************,
+ X*******************,
+ X******************,
+ X*****************,
+ X****************,
+ X***************,
+ X**************,
+ X*************,
+ X************,
+ X***********,
+ X**********,
+ X*********,
+ X********,
+ X*******,
+ X******,
+ X*****,
+ X****,
+ X***,
+ X**,
+ X*,
+ X) { }
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
new file mode 100644
index 000000000000..fbce20451264
--- /dev/null
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -0,0 +1,39 @@
+// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+namespace std {
+ struct A { A(); };
+
+ // CHECK: define void @_ZNSt1AC1Ev
+ // CHECK: define void @_ZNSt1AC2Ev
+ A::A() { }
+};
+
+namespace std {
+ template<typename> struct allocator { };
+}
+
+// CHECK: define void @_Z1fSaIcESaIiE
+void f(std::allocator<char>, std::allocator<int>) { }
+
+namespace std {
+ template<typename, typename, typename> struct basic_string { };
+}
+
+// CHECK: define void @_Z1fSbIcciE
+void f(std::basic_string<char, char, int>) { }
+
+namespace std {
+ template<typename> struct char_traits { };
+
+ typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > string;
+}
+
+// CHECK: _Z1fSs
+void f(std::string) { }
+
+namespace std {
+ template<typename, typename> struct basic_ostream { };
+}
+
+// CHECK: _Z1fSo
+void f(std::basic_ostream<char, std::char_traits<char> >) { }
diff --git a/test/CodeGenCXX/mangle-subst.cpp b/test/CodeGenCXX/mangle-subst.cpp
new file mode 100644
index 000000000000..c53a6300aa19
--- /dev/null
+++ b/test/CodeGenCXX/mangle-subst.cpp
@@ -0,0 +1,56 @@
+// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct X {};
+
+// CHECK: define void @_Z1f1XS_(
+void f(X, X) { }
+
+// CHECK: define void @_Z1fR1XS0_(
+void f(X&, X&) { }
+
+// CHECK: define void @_Z1fRK1XS1_(
+void f(const X&, const X&) { }
+
+typedef void T();
+struct S {};
+
+// CHECK: define void @_Z1fPFvvEM1SFvvE(
+void f(T*, T (S::*)) {}
+
+namespace A {
+ struct A { };
+ struct B { };
+};
+
+// CHECK: define void @_Z1fN1A1AENS_1BE(
+void f(A::A a, A::B b) { }
+
+struct C {
+ struct D { };
+};
+
+// CHECK: define void @_Z1fN1C1DERS_PS_S1_(
+void f(C::D, C&, C*, C&) { }
+
+template<typename T>
+struct V {
+ typedef int U;
+};
+
+template <typename T> void f1(typename V<T>::U, V<T>) { }
+
+// CHECK: @_Z2f1IiEvN1VIT_E1UES2_
+template void f1<int>(int, V<int>);
+
+template <typename T> void f2(V<T>, typename V<T>::U) { }
+
+// CHECK: @_Z2f2IiEv1VIT_ENS2_1UE
+template void f2<int>(V<int>, int);
+
+namespace NS {
+template <typename T> struct S1 {};
+template<typename T> void ft3(S1<T>, S1<char>) { }
+
+// CHECK: @_ZN2NS3ft3IiEEvNS_2S1IT_EENS1_IcEE
+template void ft3<int>(S1<int>, S1<char>);
+}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index ef36a8b23cfc..2ffbae71da01 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -1,87 +1,223 @@
-// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 &&
+// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
-// FIXME: This test is intentionally trivial, because we can't yet
-// CodeGen anything real in C++.
struct X { };
struct Y { };
-// RUN: grep _ZplRK1YRA100_P1X %t | count 1 &&
+// CHECK: @unmangled_variable = global
+// CHECK: @_ZN1N1iE = global
+// CHECK: @_ZZN1N1fEiiE1b = internal global
+// CHECK: @_ZZN1N1gEvE1a = internal global
+// CHECK: @_ZGVZN1N1gEvE1a = internal global
+
+// CHECK: define zeroext i1 @_ZplRK1YRA100_P1X
bool operator+(const Y&, X* (&xs)[100]) { return false; }
-// RUN: grep _Z1f1s %t | count 1 &&
+// CHECK: define void @_Z1f1s
typedef struct { int a; } s;
void f(s) { }
-// RUN: grep _Z1f1e %t| count 1 &&
+// CHECK: define void @_Z1f1e
typedef enum { foo } e;
void f(e) { }
-// RUN: grep _Z1f1u %t | count 1 &&
+// CHECK: define void @_Z1f1u
typedef union { int a; } u;
void f(u) { }
-// RUN: grep _Z1f1x %t | count 1 &&
+// CHECK: define void @_Z1f1x
typedef struct { int a; } x,y;
void f(y) { }
-// RUN: grep _Z1fv %t | count 1 &&
+// CHECK: define void @_Z1fv
void f() { }
-// RUN: grep _ZN1N1fEv %t | count 1 &&
+// CHECK: define void @_ZN1N1fEv
namespace N { void f() { } }
-// RUN: grep _ZN1N1N1fEv %t | count 1 &&
+// CHECK: define void @_ZN1N1N1fEv
namespace N { namespace N { void f() { } } }
-// RUN: grep unmangled_function %t | count 1 &&
+// CHECK: define void @unmangled_function
extern "C" { namespace N { void unmangled_function() { } } }
-// RUN: grep unmangled_variable %t | count 1 &&
extern "C" { namespace N { int unmangled_variable = 10; } }
-// RUN: grep _ZN1N1iE %t | count 1 &&
namespace N { int i; }
-// RUN: grep _ZZN1N1fEiiE1b %t | count 2 &&
namespace N { int f(int, int) { static int b; return b; } }
-// RUN: grep "_ZZN1N1gEvE1a =" %t | count 1 &&
-// RUN: grep "_ZGVZN1N1gEvE1a =" %t | count 1 &&
namespace N { int h(); void g() { static int a = h(); } }
-// RUN: grep "_Z1fno" %t | count 1 &&
+// CHECK: define void @_Z1fno
void f(__int128_t, __uint128_t) { }
template <typename T> struct S1 {};
-// RUN: grep "_Z1f2S1IiE" %t | count 1 &&
+// CHECK: define void @_Z1f2S1IiE
void f(S1<int>) {}
-// RUN: grep "_Z1f2S1IdE" %t | count 1 &&
+// CHECK: define void @_Z1f2S1IdE
void f(S1<double>) {}
template <int N> struct S2 {};
-// RUN: grep "_Z1f2S2ILi100EE" %t | count 1 &&
+// CHECK: define void @_Z1f2S2ILi100EE
void f(S2<100>) {}
-// RUN: grep "_Z1f2S2ILin100EE" %t | count 1 &&
+// CHECK: define void @_Z1f2S2ILin100EE
void f(S2<-100>) {}
template <bool B> struct S3 {};
-// RUN: grep "_Z1f2S3ILb1EE" %t | count 1 &&
+// CHECK: define void @_Z1f2S3ILb1EE
void f(S3<true>) {}
-// RUN: grep "_Z1f2S3ILb0EE" %t | count 1 &&
+// CHECK: define void @_Z1f2S3ILb0EE
void f(S3<false>) {}
-// RUN: grep "_Z2f22S3ILb1EE" %t | count 1 &&
+// CHECK: define void @_Z2f22S3ILb1EE
void f2(S3<100>) {}
struct S;
-// RUN: grep "_Z1fM1SKFvvE" %t | count 1 &&
+// CHECK: define void @_Z1fM1SKFvvE
void f(void (S::*)() const) {}
-// RUN: grep "_Z1fM1SFvvE" %t | count 1
+// CHECK: define void @_Z1fM1SFvvE
void f(void (S::*)()) {}
+
+// CHECK: define void @_Z1fi
+void f(const int) { }
+
+template<typename T, typename U> void ft1(U u, T t) { }
+
+template<typename T> void ft2(T t, void (*)(T), void (*)(T)) { }
+
+template<typename T, typename U = S1<T> > struct S4 { };
+template<typename T> void ft3(S4<T>*) { }
+
+namespace NS {
+ template<typename T> void ft1(T) { }
+}
+
+void g1() {
+ // CHECK: @_Z3ft1IidEvT0_T_
+ ft1<int, double>(1, 0);
+
+ // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_
+ ft2<char>(1, 0, 0);
+
+ // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE
+ ft3<int>(0);
+
+ // CHECK: @_ZN2NS3ft1IiEEvT_
+ NS::ft1<int>(1);
+}
+
+// Expressions
+template<int I> struct S5 { };
+
+template<int I> void ft4(S5<I>) { }
+void g2() {
+ // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE
+ ft4(S5<10>());
+
+ // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE
+ ft4(S5<20>());
+}
+
+extern "C++" {
+ // CHECK: @_Z1hv
+ void h() { }
+}
+
+// PR5019
+extern "C" { struct a { int b; }; }
+
+// CHECK: @_Z1fP1a
+int f(struct a *x) {
+ return x->b;
+}
+
+// PR5017
+extern "C" {
+struct Debug {
+ const Debug& operator<< (unsigned a) const { }
+};
+Debug dbg;
+// CHECK: @_ZNK5DebuglsEj
+int main(void) { dbg << 32 ;}
+}
+
+template<typename T> struct S6 {
+ typedef int B;
+};
+
+template<typename T> void ft5(typename S6<T>::B) { }
+// CHECK: @_Z3ft5IiEvN2S6IT_E1BE
+template void ft5<int>(int);
+
+template<typename T> class A {};
+
+namespace NS {
+template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
+}
+
+// CHECK: @_ZN2NSeqIcEEbRK1AIT_ES5_
+template bool NS::operator==(const ::A<char>&, const ::A<char>&);
+
+namespace std {
+template<typename T> bool operator==(const A<T>&, const A<T>&) { return true; }
+}
+
+// CHECK: @_ZSteqIcEbRK1AIT_ES4_
+template bool std::operator==(const ::A<char>&, const ::A<char>&);
+
+struct S {
+ typedef int U;
+};
+
+template <typename T> typename T::U ft6(const T&) { return 0; }
+
+// CHECK: @_Z3ft6I1SENT_1UERKS1_
+template int ft6<S>(const S&);
+
+template<typename> struct __is_scalar {
+ enum { __value = 1 };
+};
+
+template<bool, typename> struct __enable_if { };
+
+template<typename T> struct __enable_if<true, T> {
+ typedef T __type;
+};
+
+// PR5063
+template<typename T> typename __enable_if<__is_scalar<T>::__value, void>::__type ft7() { }
+
+// CHECK: @_Z3ft7IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+template void ft7<int>();
+// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+template void ft7<void*>();
+
+// PR5144
+extern "C" {
+void extern_f(void);
+};
+
+// CHECK: @extern_f
+void extern_f(void) { }
+
+struct S7 {
+ struct S { S(); };
+
+ struct {
+ S s;
+ } a;
+};
+
+// PR5139
+// CHECK: @_ZN2S7C1Ev
+// CHECK: @_ZN2S7C2Ev
+// CHECK: @"_ZN2S73$_0C1Ev"
+S7::S7() {}
+
diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp
new file mode 100644
index 000000000000..13f7de5a631b
--- /dev/null
+++ b/test/CodeGenCXX/member-function-pointers.cpp
@@ -0,0 +1,73 @@
+// RUN: clang-cc %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+
+struct A { int a; void f(); virtual void vf(); };
+struct B { int b; virtual void g(); };
+struct C : B, A { };
+
+void (A::*pa)();
+void (A::*volatile vpa)();
+void (B::*pb)();
+void (C::*pc)();
+
+// CHECK: @pa2 = global %0 { i64 ptrtoint (void ()* @_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;
+
+// CHECK: @pc2 = global %0 { i64 ptrtoint (void ()* @_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 f() {
+ // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
+ // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
+ pa = 0;
+
+ // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0)
+ // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1)
+ vpa = 0;
+
+ // CHECK: store i64 %0, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0)
+ // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 %1, 16
+ // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1)
+ pc = pa;
+}
+
+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: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1
+ // CHECK: store i64 0, i64* [[pa2adj]]
+ void (A::*pa2)() = &A::f;
+
+ // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0
+ // 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* [[pa2adj]]
+ void (A::*pa3)() = &A::vf;
+}
+
+void f3(A *a, A &ar) {
+ (a->*pa)();
+ (ar.*pa)();
+}
+
+// PR5177
+namespace PR5177 {
+ struct A {
+ bool foo(int*) const;
+ } a;
+
+ struct B1 {
+ bool (A::*pmf)(int*) const;
+ const A* pa;
+
+ B1() : pmf(&A::foo), pa(&a) {}
+ bool operator()() const { return (pa->*pmf)(new int); }
+ };
+
+ void bar(B1 b2) { while (b2()) ; }
+}
diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp
index 8ada907117be..29629d5bf824 100644
--- a/test/CodeGenCXX/member-functions.cpp
+++ b/test/CodeGenCXX/member-functions.cpp
@@ -58,6 +58,6 @@ struct T {
void test3() {
T t1, t2;
- // RUN: grep "call void @_ZN1TpsERK1T" %t
+ // RUN: grep "call void @_ZN1TpsERKS_" %t
T result = t1 + t2;
}
diff --git a/test/CodeGenCXX/member-pointers-zero-init.cpp b/test/CodeGenCXX/member-pointers-zero-init.cpp
new file mode 100644
index 000000000000..e7b0fdafba6a
--- /dev/null
+++ b/test/CodeGenCXX/member-pointers-zero-init.cpp
@@ -0,0 +1,34 @@
+// RUN: clang-cc -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/namespace-aliases.cpp b/test/CodeGenCXX/namespace-aliases.cpp
new file mode 100644
index 000000000000..5baea8791ef9
--- /dev/null
+++ b/test/CodeGenCXX/namespace-aliases.cpp
@@ -0,0 +1,3 @@
+// RUN: clang-cc -emit-llvm-only %s
+namespace A { }
+namespace B = A;
diff --git a/test/CodeGenCXX/nested-base-member-access.cpp b/test/CodeGenCXX/nested-base-member-access.cpp
new file mode 100644
index 000000000000..308f952c6dc2
--- /dev/null
+++ b/test/CodeGenCXX/nested-base-member-access.cpp
@@ -0,0 +1,52 @@
+// RUN: clang-cc %s -emit-llvm -o %t
+
+extern "C" int printf(...);
+
+struct M {
+ M(int i){ iM = i; }
+ int iM;
+ void MPR() { printf("iM = %d\n", iM); }
+
+};
+
+struct Q {
+ Q(int i){ iQ = i; }
+ int iQ;
+ void QPR() { printf("iQ = %d\n", iQ); }
+};
+
+struct IQ {
+ IQ(int i) { iIQ = i; }
+ void IQPR() { printf("iIQ = %d\n", iIQ); }
+ int iIQ;
+};
+
+struct L : IQ {
+ L(int i) : IQ(i+100) { iL = i; }
+ int iL;
+};
+
+struct P : Q, L {
+ P(int i) : Q(i+100), L(i+200) { iP = i; }
+ int iP;
+ void PPR() { printf("iP = %d\n", iP); }
+};
+
+
+struct N : M,P {
+ N() : M(100), P(200) {}
+ void PR() {
+ this->MPR(); this->PPR(); this->QPR();
+ IQPR();
+ printf("iM = %d\n", iM);
+ printf("iP = %d\n", iP);
+ printf("iQ = %d\n", iQ);
+ printf("iL = %d\n", iL);
+ printf("iIQ = %d\n", iIQ);
+ }
+};
+
+int main() {
+ N n1;
+ n1.PR();
+}
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 480bbcefc08d..c6cee1845670 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-cc %s -emit-llvm -o %t &&
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
void t1() {
int* a = new int;
@@ -32,7 +32,7 @@ struct T {
};
void t4() {
- // RUN: grep "call void @_ZN1TC1Ev" %t | count 1 &&
+ // CHECK: call void @_ZN1TC1Ev
T *t = new T;
}
@@ -42,7 +42,7 @@ struct T2 {
};
void t5() {
- // RUN: grep "call void @_ZN2T2C1Eii" %t | count 1
+ // CHECK: call void @_ZN2T2C1Eii
T2 *t2 = new T2(10, 10);
}
@@ -54,3 +54,20 @@ int *t6() {
void t7() {
new int();
}
+
+struct U {
+ ~U();
+};
+
+void t8(int n) {
+ new int[10];
+ new int[n];
+
+ // Non-POD
+ new T[10];
+ new T[n];
+
+ // Cookie required
+ new U[10];
+ new U[n];
+}
diff --git a/test/CodeGenCXX/nullptr.cpp b/test/CodeGenCXX/nullptr.cpp
new file mode 100644
index 000000000000..7bc52ad5210a
--- /dev/null
+++ b/test/CodeGenCXX/nullptr.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-cc -std=c++0x %s -emit-llvm -o %t
+
+int* a = nullptr;
+
+void f() {
+ int* a = nullptr;
+}
diff --git a/test/CodeGenCXX/overload-binop-implicitconvert.cpp b/test/CodeGenCXX/overload-binop-implicitconvert.cpp
new file mode 100644
index 000000000000..f17a4585e69f
--- /dev/null
+++ b/test/CodeGenCXX/overload-binop-implicitconvert.cpp
@@ -0,0 +1,22 @@
+// RUN: clang-cc %s -emit-llvm-only
+class T
+{};
+
+void print(const char *t);
+
+T& operator<< (T& t,const char* c)
+{
+ print(c);
+ return t;
+}
+
+
+int main()
+{
+ T t;
+ print("foo");
+ t<<"foo";
+
+ return 0;
+}
+
diff --git a/test/CodeGenCXX/predefined-expr-sizeof.cpp b/test/CodeGenCXX/predefined-expr-sizeof.cpp
new file mode 100644
index 000000000000..e318fbec18ae
--- /dev/null
+++ b/test/CodeGenCXX/predefined-expr-sizeof.cpp
@@ -0,0 +1,30 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: store i32 49, i32* %size
+// CHECK: store i32 52, i32* %size
+template<typename T>
+class TemplateClass {
+public:
+ void templateClassFunction() {
+ int size = sizeof(__PRETTY_FUNCTION__);
+ }
+};
+
+// CHECK: store i32 27, i32* %size
+// CHECK: store i32 30, i32* %size
+template<typename T>
+void functionTemplate(T t) {
+ int size = sizeof(__PRETTY_FUNCTION__);
+}
+
+int main() {
+ TemplateClass<int> t1;
+ t1.templateClassFunction();
+ TemplateClass<double> t2;
+ t2.templateClassFunction();
+
+ functionTemplate<int>(0);
+ functionTemplate(0.0);
+
+ return 0;
+}
diff --git a/test/CodeGenCXX/predefined-expr.cpp b/test/CodeGenCXX/predefined-expr.cpp
new file mode 100644
index 000000000000..95bc255bdde0
--- /dev/null
+++ b/test/CodeGenCXX/predefined-expr.cpp
@@ -0,0 +1,226 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: private constant [15 x i8] c"externFunction\00"
+// CHECK: private constant [26 x i8] c"void NS::externFunction()\00"
+
+// CHECK: private constant [22 x i8] c"classTemplateFunction\00"
+// CHECK: private constant [60 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction()\00"
+// CHECK: private constant [53 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction()\00"
+
+// CHECK: private constant [18 x i8] c"functionTemplate1\00"
+// CHECK: private constant [45 x i8] c"void NS::Base::functionTemplate1(NS::Base *)\00"
+// CHECK: private constant [38 x i8] c"void NS::Base::functionTemplate1(int)\00"
+
+// CHECK: private constant [12 x i8] c"~Destructor\00"
+// CHECK: private constant [35 x i8] c"void NS::Destructor::~Destructor()\00"
+
+// CHECK: private constant [12 x i8] c"Constructor\00"
+// CHECK: private constant [46 x i8] c"void NS::Constructor::Constructor(NS::Base *)\00"
+// CHECK: private constant [39 x i8] c"void NS::Constructor::Constructor(int)\00"
+// CHECK: private constant [36 x i8] c"void NS::Constructor::Constructor()\00"
+
+// CHECK: private constant [16 x i8] c"virtualFunction\00"
+// CHECK: private constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00"
+
+// CHECK: private constant [26 x i8] c"functionReturingTemplate2\00"
+// CHECK: private constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00"
+
+// CHECK: private constant [26 x i8] c"functionReturingTemplate1\00"
+// CHECK: private constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00"
+
+// CHECK: private constant [23 x i8] c"withTemplateParameter2\00"
+// CHECK: private constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00"
+
+// CHECK: private constant [23 x i8] c"withTemplateParameter1\00"
+// CHECK: private constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00"
+
+// CHECK: private constant [23 x i8] c"functionReturningClass\00"
+// CHECK: private constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00"
+
+// CHECK: private constant [23 x i8] c"functionWithParameters\00"
+// CHECK: private constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00"
+
+// CHECK: private constant [17 x i8] c"variadicFunction\00"
+// CHECK: private constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00"
+
+// CHECK: private constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00"
+
+// CHECK: private constant [15 x i8] c"inlineFunction\00"
+// CHECK: private constant [32 x i8] c"void NS::Base::inlineFunction()\00"
+
+// CHECK: private constant [11 x i8] c"staticFunc\00"
+// CHECK: private constant [28 x i8] c"void NS::Base::staticFunc()\00"
+
+int printf(const char * _Format, ...);
+
+namespace NS {
+
+template<typename T>
+class ClassTemplate {
+public:
+ void classTemplateFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class Base {
+public:
+ static void staticFunc() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ inline void inlineFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ virtual void virtualFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void functionWithParameters(int, float*, Base* base) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ Base *functionReturningClass() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return 0;
+ }
+
+ void variadicFunction(int, ...) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void withTemplateParameter1(ClassTemplate<int>) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ void withTemplateParameter2(ClassTemplate<Base *>) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ ClassTemplate<int> functionReturingTemplate1() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return ClassTemplate<int>();
+ }
+
+ ClassTemplate<Base *> functionReturingTemplate2() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ return ClassTemplate<Base *>();
+ }
+
+ template<typename T>
+ void functionTemplate1(T t) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class Derived : public Base {
+public:
+ // Virtual function without being explicitally written.
+ void virtualFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+class Constructor {
+public:
+ Constructor() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ Constructor(int) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+ Constructor(Base *) {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+
+};
+
+class Destructor {
+public:
+ ~Destructor() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+ }
+};
+
+extern void externFunction() {
+ printf("__func__ %s\n", __func__);
+ printf("__FUNCTION__ %s\n", __FUNCTION__);
+ printf("__PRETTY_FUNCTION__ %s\n\n", __PRETTY_FUNCTION__);
+}
+
+}
+
+int main() {
+ NS::Base::staticFunc();
+
+ NS::Base b;
+ b.inlineFunction();
+ b.virtualFunction();
+ b.variadicFunction(0);
+ b.functionWithParameters(0, 0, 0);
+ b.functionReturningClass();
+
+ b.withTemplateParameter1(NS::ClassTemplate<int>());
+ b.withTemplateParameter2(NS::ClassTemplate<NS::Base *>());
+ b.functionReturingTemplate1();
+ b.functionReturingTemplate2();
+ b.functionTemplate1<int>(0);
+ b.functionTemplate1<NS::Base *>(0);
+
+ NS::Derived d;
+ d.virtualFunction();
+
+ NS::ClassTemplate<int> t1;
+ t1.classTemplateFunction();
+ NS::ClassTemplate<NS::Base *> t2;
+ t2.classTemplateFunction();
+
+ NS::Constructor c1;
+ NS::Constructor c2(0);
+ NS::Constructor c3((NS::Base *)0);
+
+ {
+ NS::Destructor destructor;
+ }
+
+ NS::externFunction();
+
+ return 0;
+}
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index 8e1935675766..c235521d43b1 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -87,3 +87,16 @@ int reference_decl() {
const int& b = 1;
return a+b;
}
+
+struct A {
+ int& b();
+};
+
+void f(A* a) {
+ int b = a->b();
+}
+
+// PR5122
+void *foo = 0;
+void * const & kFoo = foo;
+
diff --git a/test/CodeGenCXX/reinterpret-cast.cpp b/test/CodeGenCXX/reinterpret-cast.cpp
new file mode 100644
index 000000000000..ae3ab2f8b0d7
--- /dev/null
+++ b/test/CodeGenCXX/reinterpret-cast.cpp
@@ -0,0 +1,12 @@
+// RUN: clang-cc -emit-llvm -o - %s -std=c++0x
+void *f1(unsigned long l) {
+ return reinterpret_cast<void *>(l);
+}
+
+unsigned long f2() {
+ return reinterpret_cast<unsigned long>(nullptr);
+}
+
+unsigned long f3(void *p) {
+ return reinterpret_cast<unsigned long>(p);
+} \ No newline at end of file
diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp
new file mode 100644
index 000000000000..6e2abcc1adea
--- /dev/null
+++ b/test/CodeGenCXX/static-data-member.cpp
@@ -0,0 +1,8 @@
+// RUN: clang-cc -emit-llvm -o - %s
+struct S {
+ static int i;
+};
+
+void f() {
+ int a = S::i;
+}
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
new file mode 100644
index 000000000000..44dd14284107
--- /dev/null
+++ b/test/CodeGenCXX/static-init.cpp
@@ -0,0 +1,13 @@
+// RUN: clang-cc -triple=x86_64-apple-darwin9 -emit-llvm %s -o %t &&
+// RUN: grep "call void @_ZN1AC1Ev" %t | count 1 &&
+// RUN: grep "call i32 @__cxa_atexit(void (i8\*)\* bitcast (void (%.truct.A\*)\* @_ZN1AD1Ev to void (i8\*)\*), i8\* getelementptr inbounds (%.truct.A\* @_ZZ1fvE1a, i32 0, i32 0), i8\* bitcast (i8\*\* @__dso_handle to i8\*))" %t | count 1
+
+struct A {
+ A();
+ ~A();
+};
+
+void f() {
+ static A a;
+}
+
diff --git a/test/CodeGenCXX/temp-1.cpp b/test/CodeGenCXX/temp-1.cpp
new file mode 100644
index 000000000000..9b97f0083c83
--- /dev/null
+++ b/test/CodeGenCXX/temp-1.cpp
@@ -0,0 +1,83 @@
+// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 &&
+struct A {
+ A();
+ ~A();
+ void f();
+};
+
+// RUN: grep "call void @_ZN1AC1Ev" %t | count 2 &&
+// RUN: grep "call void @_ZN1AD1Ev" %t | count 2 &&
+void f1() {
+ (void)A();
+ A().f();
+}
+
+// Function calls
+struct B {
+ B();
+ ~B();
+};
+
+B g();
+
+// RUN: grep "call void @_ZN1BC1Ev" %t | count 0 &&
+// RUN: grep "call void @_ZN1BD1Ev" %t | count 1 &&
+void f2() {
+ (void)g();
+}
+
+// Member function calls
+struct C {
+ C();
+ ~C();
+
+ C f();
+};
+
+// RUN: grep "call void @_ZN1CC1Ev" %t | count 1 &&
+// RUN: grep "call void @_ZN1CD1Ev" %t | count 2 &&
+void f3() {
+ C().f();
+}
+
+// Function call operator
+struct D {
+ D();
+ ~D();
+
+ D operator()();
+};
+
+// RUN: grep "call void @_ZN1DC1Ev" %t | count 1 &&
+// RUN: grep "call void @_ZN1DD1Ev" %t | count 2 &&
+void f4() {
+ D()();
+}
+
+// Overloaded operators
+struct E {
+ E();
+ ~E();
+ E operator+(const E&);
+ E operator!();
+};
+
+// RUN: grep "call void @_ZN1EC1Ev" %t | count 3 &&
+// RUN: grep "call void @_ZN1ED1Ev" %t | count 5 &&
+void f5() {
+ E() + E();
+ !E();
+}
+
+struct F {
+ F();
+ ~F();
+ F& f();
+};
+
+// RUN: grep "call void @_ZN1FC1Ev" %t | count 1 &&
+// RUN: grep "call void @_ZN1FD1Ev" %t | count 1
+void f6() {
+ F().f();
+}
+
diff --git a/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp
new file mode 100644
index 000000000000..f8454282badc
--- /dev/null
+++ b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-cc -emit-llvm -o %t %s
+template <typename T>
+class A
+{
+ union { void *d; };
+
+ A() : d(0) { }
+};
+
+A<int> a0;
diff --git a/test/CodeGenCXX/trivial-constructor-init.cpp b/test/CodeGenCXX/trivial-constructor-init.cpp
new file mode 100644
index 000000000000..183b31a801e3
--- /dev/null
+++ b/test/CodeGenCXX/trivial-constructor-init.cpp
@@ -0,0 +1,21 @@
+// RUN: clang-cc -S %s -o %t-64.s &&
+// RUN: clang-cc -S %s -o %t-32.s &&
+// RUN: true
+
+extern "C" int printf(...);
+
+struct S {
+ S() { printf("S::S\n"); }
+};
+
+struct A {
+ double x;
+ A() : x(), y(), s() { printf("x = %f y = %x \n", x, y); }
+ int *y;
+ S s;
+};
+
+A a;
+
+int main() {
+}
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
new file mode 100644
index 000000000000..9ae81e5d3f33
--- /dev/null
+++ b/test/CodeGenCXX/virt.cpp
@@ -0,0 +1,1024 @@
+// RUN: clang-cc -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-cc -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 &&
+
+// RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -O3 -S %s -o %t-O3-64.s &&
+// RUN: FileCheck -check-prefix LPOPT64 --input-file=%t-O3-64.s %s &&
+// RUN: clang-cc -triple i386-apple-darwin -std=c++0x -O3 -S %s -o %t-O3-32.s &&
+// RUN: FileCheck -check-prefix LPOPT32 -input-file=%t-O3-32.s %s &&
+
+// RUN: true
+
+struct B {
+ virtual void bar1();
+ virtual void bar2();
+ int b;
+};
+void B::bar1() { }
+void B::bar2() { }
+
+struct C {
+ virtual void bee1();
+ virtual void bee2();
+};
+void C::bee1() { }
+void C::bee2() { }
+
+struct D {
+ virtual void boo();
+};
+void D::boo() { }
+
+struct D1 {
+ virtual void bar();
+ virtual void bar2();
+ virtual void bar3();
+ virtual void bar4();
+ virtual void bar5();
+ void *d1;
+};
+void D1::bar() { }
+
+class F : virtual public D1, virtual public D {
+public:
+ virtual void foo();
+ void *f;
+};
+void F::foo() { }
+
+int j;
+void test2() {
+ F f;
+ static int sz = (char *)(&f.f) - (char *)(&f);
+ j = sz;
+ // FIXME: These should result in a frontend constant a la fold, no run time
+ // initializer
+ // CHECK-LPOPT32: movl $4, __ZZ5test2vE2sz
+ // CHECK-LPOPT64: movl $8, __ZZ5test2vE2sz(%rip)
+}
+
+static_assert(sizeof(F) == sizeof(void*)*4, "invalid vbase size");
+
+struct E {
+ int e;
+};
+
+static_assert (sizeof (C) == (sizeof(void *)), "vtable pointer layout");
+
+class A : public E, public B, public C {
+public:
+ virtual void foo1();
+ virtual void foo2();
+ A() { }
+ int a;
+} *ap;
+void A::foo1() { }
+void A::foo2() { }
+
+int main() {
+ A a;
+ B b;
+ ap->e = 1;
+ ap->b = 2;
+}
+
+// CHECK-LP32: main:
+// CHECK-LP32: movl $1, 8(%eax)
+// CHECK-LP32: movl $2, 4(%eax)
+
+// CHECK-LP64: main:
+// CHECK-LP64: movl $1, 12(%rax)
+// CHECK-LP64: movl $2, 8(%rax)
+
+struct test12_A {
+ virtual void foo0() { }
+ virtual void foo();
+} *test12_pa;
+
+struct test12_B : public test12_A {
+ virtual void foo() { }
+} *test12_pb;
+
+struct test12_D : public test12_B {
+} *test12_pd;
+void test12_foo() {
+ test12_pa->foo0();
+ test12_pb->foo0();
+ test12_pd->foo0();
+ test12_pa->foo();
+ test12_pb->foo();
+ test12_pd->foo();
+ test12_pa->test12_A::foo();
+}
+
+// CHECK-LPOPT32:__Z10test12_foov:
+// CHECK-LPOPT32: movl _test12_pa, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pb, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pd, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pa, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *4(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pb, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *4(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pd, %eax
+// CHECK-LPOPT32-NEXT: movl (%eax), %ecx
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call *4(%ecx)
+// CHECK-LPOPT32-NEXT: movl _test12_pa, %eax
+// CHECK-LPOPT32-NEXT: movl %eax, (%esp)
+// CHECK-LPOPT32-NEXT: call L__ZN8test12_A3fooEv$stub
+
+// CHECK-LPOPT64:__Z10test12_foov:
+// CHECK-LPOPT64: movq _test12_pa(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pb(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pd(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pa(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *8(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pb(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *8(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pd(%rip), %rdi
+// CHECK-LPOPT64-NEXT: movq (%rdi), %rax
+// CHECK-LPOPT64-NEXT: call *8(%rax)
+// CHECK-LPOPT64-NEXT: movq _test12_pa(%rip), %rdi
+// CHECK-LPOPT64-NEXT: call __ZN8test12_A3fooEv
+
+struct test6_B2 { virtual void funcB2(); char b[1000]; };
+struct test6_B1 : virtual test6_B2 { virtual void funcB1(); };
+
+struct test6_D : test6_B2, virtual test6_B1 {
+};
+
+// CHECK-LP32: .zerofill __DATA, __common, _d6, 2012, 4
+// CHECK-LP64: .zerofill __DATA, __common, _d6, 2024, 4
+
+struct test7_B2 { virtual void funcB2(); };
+struct test7_B1 : virtual test7_B2 { virtual void funcB1(); };
+
+struct test7_D : test7_B2, virtual test7_B1 {
+};
+
+// CHECK-LP32: .zerofill __DATA, __common, _d7, 8, 3
+// CHECK-LP64: .zerofill __DATA, __common, _d7, 16, 3
+
+
+struct test3_B3 { virtual void funcB3(); };
+struct test3_B2 : virtual test3_B3 { virtual void funcB2(); };
+struct test3_B1 : virtual test3_B2 { virtual void funcB1(); };
+
+struct test3_D : virtual test3_B1 {
+ virtual void funcD() { }
+};
+
+// CHECK-LP32:__ZTV7test3_D:
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI7test3_D
+// CHECK-LP32-NEXT: .long __ZN8test3_B36funcB3Ev
+// CHECK-LP32-NEXT: .long __ZN8test3_B26funcB2Ev
+// CHECK-LP32-NEXT: .long __ZN8test3_B16funcB1Ev
+// CHECK-LP32-NEXT: .long __ZN7test3_D5funcDEv
+
+// CHECK-LP64:__ZTV7test3_D:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI7test3_D
+// CHECK-LP64-NEXT: .quad __ZN8test3_B36funcB3Ev
+// CHECK-LP64-NEXT: .quad __ZN8test3_B26funcB2Ev
+// CHECK-LP64-NEXT: .quad __ZN8test3_B16funcB1Ev
+// CHECK-LP64-NEXT: .quad __ZN7test3_D5funcDEv
+
+struct test4_D : virtual B, virtual C {
+};
+
+// CHECK-LP32:__ZTV7test4_D:
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI7test4_D
+// CHECK-LP32-NEXT: .long __ZN1C4bee1Ev
+// CHECK-LP32-NEXT: .long __ZN1C4bee2Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .long __ZTI7test4_D
+// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
+// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
+
+// CHECK-LP64:__ZTV7test4_D:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI7test4_D
+// CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev
+// CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad __ZTI7test4_D
+// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
+// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
+
+
+struct test5_B3 { virtual void funcB3(); };
+struct test5_B2 : virtual test5_B3 { virtual void funcB2(); };
+struct test5_B1 : virtual test5_B2 { virtual void funcB1(); };
+
+struct test5_B23 { virtual void funcB23(); };
+struct test5_B22 : virtual test5_B23 { virtual void funcB22(); };
+struct test5_B21 : virtual test5_B22 { virtual void funcB21(); };
+
+
+struct B232 { virtual void funcB232(); };
+struct B231 { virtual void funcB231(); };
+
+struct test5_B33 { virtual void funcB33(); };
+struct test5_B32 : virtual test5_B33, virtual B232 { virtual void funcB32(); };
+struct test5_B31 : virtual test5_B32, virtual B231 { virtual void funcB31(); };
+
+struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
+ virtual void funcD() { }
+};
+
+// CHECK-LP32:__ZTV7test5_D:
+// CHECK-LP32-NEXT: .long 16
+// CHECK-LP32-NEXT: .long 12
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4
+// CHECK-LP32-NEXT: .long 4
+// CHECK-LP32-NEXT: .long 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI7test5_D
+// CHECK-LP32-NEXT: .long __ZN8test5_B36funcB3Ev
+// CHECK-LP32-NEXT: .long __ZN8test5_B26funcB2Ev
+// CHECK-LP32-NEXT: .long __ZN8test5_B16funcB1Ev
+// CHECK-LP32-NEXT: .long __ZN7test5_D5funcDEv
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .long __ZTI7test5_D
+// CHECK-LP32-NEXT: .long __ZN9test5_B237funcB23Ev
+// CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev
+// CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32: .long 8
+// CHECK-LP32 .space 4
+// CHECK-LP32 .space 4 FIXME
+// CHECK-LP32: .long 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967288
+// CHECK-LP32-NEXT: .long __ZTI7test5_D
+// CHECK-LP32-NEXT: .long __ZN9test5_B337funcB33Ev
+// CHECK-LP32-NEXT: .long __ZN9test5_B327funcB32Ev
+// CHECK-LP32-NEXT: .long __ZN9test5_B317funcB31Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long __ZTI7test5_D
+// CHECK-LP32-NEXT: .long __ZN4B2328funcB232Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967280
+// CHECK-LP32-NEXT: .long __ZTI7test5_D
+// CHECK-LP32-NEXT: .long __ZN4B2318funcB231Ev
+
+// CHECK-LP64:__ZTV7test5_D:
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 24
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 8
+// CHECK-LP64-NEXT: .quad 8
+// CHECK-LP64-NEXT: .quad 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI7test5_D
+// CHECK-LP64-NEXT: .quad __ZN8test5_B36funcB3Ev
+// CHECK-LP64-NEXT: .quad __ZN8test5_B26funcB2Ev
+// CHECK-LP64-NEXT: .quad __ZN8test5_B16funcB1Ev
+// CHECK-LP64-NEXT: .quad __ZN7test5_D5funcDEv
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad __ZTI7test5_D
+// CHECK-LP64-NEXT: .quad __ZN9test5_B237funcB23Ev
+// CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev
+// CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64: .quad 16
+// CHECK-LP64 .space 8
+// CHECK-LP64 .space 8
+// CHECK-LP64: .quad 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad __ZTI7test5_D
+// CHECK-LP64-NEXT: .quad __ZN9test5_B337funcB33Ev
+// CHECK-LP64-NEXT: .quad __ZN9test5_B327funcB32Ev
+// CHECK-LP64-NEXT: .quad __ZN9test5_B317funcB31Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad __ZTI7test5_D
+// CHECK-LP64-NEXT: .quad __ZN4B2328funcB232Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551584
+// CHECK-LP64-NEXT: .quad __ZTI7test5_D
+// CHECK-LP64-NEXT: .quad __ZN4B2318funcB231Ev
+
+struct test8_B1 {
+ virtual void ftest8_B1() { }
+};
+struct test8_B2aa {
+ virtual void ftest8_B2aa() { }
+ int i;
+};
+struct test8_B2ab {
+ virtual void ftest8_B2ab() { }
+ int i;
+};
+struct test8_B2a : virtual test8_B2aa, virtual test8_B2ab {
+ virtual void ftest8_B2a() { }
+};
+struct test8_B2b {
+ virtual void ftest8_B2b() { }
+};
+struct test8_B2 : test8_B2a, test8_B2b {
+ virtual void ftest8_B2() { }
+};
+struct test8_B3 {
+ virtual void ftest8_B3() { }
+};
+class test8_D : test8_B1, test8_B2, test8_B3 {
+};
+
+// CHECK-LP32:__ZTV7test8_D:
+// CHECK-LP32-NEXT: .long 24
+// CHECK-LP32-NEXT: .long 16
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZN8test8_B19ftest8_B1Ev
+// CHECK-LP32-NEXT: .long 20
+// CHECK-LP32-NEXT: .long 12
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZN9test8_B2a10ftest8_B2aEv
+// CHECK-LP32-NEXT: .long __ZN8test8_B29ftest8_B2Ev
+// CHECK-LP32-NEXT: .long 4294967288
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZN9test8_B2b10ftest8_B2bEv
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZN8test8_B39ftest8_B3Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967280
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZN10test8_B2aa11ftest8_B2aaEv
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967272
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZN10test8_B2ab11ftest8_B2abEv
+
+// CHECK-LP64:__ZTV7test8_D:
+// CHECK-LP64-NEXT: .quad 48
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZN8test8_B19ftest8_B1Ev
+// CHECK-LP64-NEXT: .quad 40
+// CHECK-LP64-NEXT: .quad 24
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZN9test8_B2a10ftest8_B2aEv
+// CHECK-LP64-NEXT: .quad __ZN8test8_B29ftest8_B2Ev
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZN9test8_B2b10ftest8_B2bEv
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZN8test8_B39ftest8_B3Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551584
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZN10test8_B2aa11ftest8_B2aaEv
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551568
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZN10test8_B2ab11ftest8_B2abEv
+
+
+struct test9_B3 { virtual void funcB3(); int i; };
+struct test9_B2 : virtual test9_B3 { virtual void funcB2(); int i; };
+struct test9_B1 : virtual test9_B2 { virtual void funcB1(); int i; };
+
+struct test9_B23 { virtual void funcB23(); int i; };
+struct test9_B22 : virtual test9_B23 { virtual void funcB22(); int i; };
+struct test9_B21 : virtual test9_B22 { virtual void funcB21(); int i; };
+
+
+struct test9_B232 { virtual void funcB232(); int i; };
+struct test9_B231 { virtual void funcB231(); int i; };
+
+struct test9_B33 { virtual void funcB33(); int i; };
+struct test9_B32 : virtual test9_B33, virtual test9_B232 { virtual void funcB32(); int i; };
+struct test9_B31 : virtual test9_B32, virtual test9_B231 { virtual void funcB31(); int i; };
+
+struct test9_D : virtual test9_B1, virtual test9_B21, virtual test9_B31 {
+ virtual void funcD() { }
+};
+
+// CHECK-LP64: __ZTV7test9_D:
+// CHECK-LP64-NEXT: .quad 168
+// CHECK-LP64-NEXT: .quad 152
+// CHECK-LP64-NEXT: .quad 136
+// CHECK-LP64-NEXT: .quad 120
+// CHECK-LP64-NEXT: .quad 104
+// CHECK-LP64-NEXT: .quad 88
+// CHECK-LP64-NEXT: .quad 72
+// CHECK-LP64-NEXT: .quad 56
+// CHECK-LP64-NEXT: .quad 40
+// CHECK-LP64-NEXT: .quad 24
+// CHECK-LP64-NEXT: .quad 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN7test9_D5funcDEv
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN8test9_B16funcB1Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN8test9_B26funcB2Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551576
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN8test9_B36funcB3Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551560
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN9test9_B217funcB21Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551544
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN9test9_B227funcB22Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551528
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN9test9_B237funcB23Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 64
+// CHECK-LP64-NEXT: .quad 48
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551512
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN9test9_B317funcB31Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551496
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN9test9_B327funcB32Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551480
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN9test9_B337funcB33Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551464
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN10test9_B2328funcB232Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551448
+// CHECK-LP64-NEXT: .quad __ZTI7test9_D
+// CHECK-LP64-NEXT: .quad __ZN10test9_B2318funcB231Ev
+
+// CHECK-LP32: __ZTV7test9_D:
+// CHECK-LP32-NEXT: .long 84
+// CHECK-LP32-NEXT: .long 76
+// CHECK-LP32-NEXT: .long 68
+// CHECK-LP32-NEXT: .long 60
+// CHECK-LP32-NEXT: .long 52
+// CHECK-LP32-NEXT: .long 44
+// CHECK-LP32-NEXT: .long 36
+// CHECK-LP32-NEXT: .long 28
+// CHECK-LP32-NEXT: .long 20
+// CHECK-LP32-NEXT: .long 12
+// CHECK-LP32-NEXT: .long 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN7test9_D5funcDEv
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 16
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN8test9_B16funcB1Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN8test9_B26funcB2Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967276
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN8test9_B36funcB3Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 16
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967268
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN9test9_B217funcB21Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967260
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN9test9_B227funcB22Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967252
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN9test9_B237funcB23Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 32
+// CHECK-LP32-NEXT: .long 24
+// CHECK-LP32-NEXT: .long 16
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967244
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN9test9_B317funcB31Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 16
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967236
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN9test9_B327funcB32Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967228
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN9test9_B337funcB33Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967220
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN10test9_B2328funcB232Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967212
+// CHECK-LP32-NEXT: .long __ZTI7test9_D
+// CHECK-LP32-NEXT: .long __ZN10test9_B2318funcB231Ev
+
+struct test10_O { int i; };
+
+struct test10_B1 : virtual test10_O {
+ virtual void ftest10_B1() { }
+};
+
+struct test10_B2aa : virtual test10_O {
+ int i;
+};
+struct test10_B2ab : virtual test10_O {
+ int i;
+};
+struct test10_B2a : virtual test10_B2aa, virtual test10_B2ab,virtual test10_O {
+ virtual void ftest10_B2a() { }
+};
+struct test10_B2b : virtual test10_O {
+ virtual void ftest10_B2b() { }
+};
+struct test10_B2 : test10_B2a {
+ virtual void ftest10_B2() { }
+};
+class test10_D : test10_B1, test10_B2 {
+
+ void ftest10_B2aa() { }
+};
+
+// CHECK-LP64:__ZTV8test10_D:
+// CHECK-LP64-NEXT: .quad 40
+// CHECK-LP64-NEXT: .quad 24
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI8test10_D
+// CHECK-LP64-NEXT: .quad __ZN9test10_B110ftest10_B1Ev
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 8
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad __ZTI8test10_D
+// CHECK-LP64-NEXT: .quad __ZN10test10_B2a11ftest10_B2aEv
+// CHECK-LP64-NEXT: .quad __ZN9test10_B210ftest10_B2Ev
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad __ZTI8test10_D
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad 18446744073709551576
+// CHECK-LP64-NEXT: .quad __ZTI8test10_D
+
+// CHECK-LP32: __ZTV8test10_D:
+// CHECK-LP32-NEXT: .long 20
+// CHECK-LP32-NEXT: .long 12
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI8test10_D
+// CHECK-LP32-NEXT: .long __ZN9test10_B110ftest10_B1Ev
+// CHECK-LP32-NEXT: .long 16
+// CHECK-LP32-NEXT: .long 4
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .long __ZTI8test10_D
+// CHECK-LP32-NEXT: .long __ZN10test10_B2a11ftest10_B2aEv
+// CHECK-LP32-NEXT: .long __ZN9test10_B210ftest10_B2Ev
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long __ZTI8test10_D
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long 4294967276
+// CHECK-LP32-NEXT: .long __ZTI8test10_D
+
+struct test11_B {
+ virtual void B1() { }
+ virtual void D() { }
+ virtual void B2() { }
+};
+
+struct test11_D : test11_B {
+ virtual void D1() { }
+ virtual void D() { }
+ virtual void D2() { }
+};
+
+// CHECK-LP32:__ZTV8test11_D:
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI8test11_D
+// CHECK-LP32-NEXT: .long __ZN8test11_B2B1Ev
+// CHECK-LP32-NEXT: .long __ZN8test11_D1DEv
+// CHECK-LP32-NEXT: .long __ZN8test11_B2B2Ev
+// CHECK-LP32-NEXT: .long __ZN8test11_D2D1Ev
+// CHECK-LP32-NEXT: .long __ZN8test11_D2D2Ev
+
+
+// CHECK-LP64:__ZTV8test11_D:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI8test11_D
+// CHECK-LP64-NEXT: .quad __ZN8test11_B2B1Ev
+// CHECK-LP64-NEXT: .quad __ZN8test11_D1DEv
+// CHECK-LP64-NEXT: .quad __ZN8test11_B2B2Ev
+// CHECK-LP64-NEXT: .quad __ZN8test11_D2D1Ev
+// CHECK-LP64-NEXT: .quad __ZN8test11_D2D2Ev
+
+struct test13_B {
+ virtual void B1() { }
+ virtual void D() { }
+ virtual void Da();
+ virtual void Db() { }
+ virtual void Dc() { }
+ virtual void B2() { }
+ int i;
+};
+
+
+struct test13_NV1 {
+ virtual void fooNV1() { }
+ virtual void D() { }
+};
+
+
+struct test13_B2 : /* test13_NV1, */ virtual test13_B {
+ virtual void B2a() { }
+ virtual void B2() { }
+ virtual void D() { }
+ virtual void Da();
+ virtual void Dd() { }
+ virtual void B2b() { }
+ int i;
+};
+
+
+struct test13_D : test13_NV1, virtual test13_B2 {
+ virtual void D1() { }
+ virtual void D() { }
+ virtual void Db() { }
+ virtual void Dd() { }
+ virtual void D2() { }
+ virtual void fooNV1() { }
+};
+
+// CHECK-LP64:__ZTV8test13_D:
+// CHECK-LP64-NEXT: .quad 24
+// CHECK-LP64-NEXT: .quad 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI8test13_D
+// CHECK-LP64-NEXT: .quad __ZN8test13_D6fooNV1Ev
+// CHECK-LP64-NEXT: .quad __ZN8test13_D1DEv
+// CHECK-LP64-NEXT: .quad __ZN8test13_D2D1Ev
+// CHECK-LP64-NEXT: .quad __ZN8test13_D2DbEv
+// CHECK-LP64-NEXT: .quad __ZN8test13_D2DdEv
+// CHECK-LP64-NEXT: .quad __ZN8test13_D2D2Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad __ZTI8test13_D
+// CHECK-LP64-NEXT: .quad __ZN9test13_B23B2aEv
+// CHECK-LP64-NEXT: .quad __ZN9test13_B22B2Ev
+// CHECK-LP64-NEXT: .quad __ZTv0_n48_N8test13_D1DEv
+// CHECK-LP64-NEXT: .quad __ZN9test13_B22DaEv
+// CHECK-LP64-NEXT: .quad __ZTv0_n64_N8test13_D2DdEv
+// CHECK-LP64-NEXT: .quad __ZN9test13_B23B2bEv
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad __ZTI8test13_D
+// CHECK-LP64-NEXT: .quad __ZN8test13_B2B1Ev
+// CHECK-LP64-NEXT: .quad __ZTv0_n32_N8test13_D1DEv
+// CHECK-LP64-NEXT: .quad __ZTv0_n40_N9test13_B22DaEv
+// CHECK-LP64-NEXT: .quad __ZTv0_n48_N8test13_D2DbEv
+// CHECK-LP64-NEXT: .quad __ZN8test13_B2DcEv
+// CHECK-LP64-NEXT: .quad __ZTv0_n64_N9test13_B22B2Ev
+
+// CHECK-LP32:__ZTV8test13_D:
+// CHECK-LP32-NEXT: .long 12
+// CHECK-LP32-NEXT: .long 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI8test13_D
+// CHECK-LP32-NEXT: .long __ZN8test13_D6fooNV1Ev
+// CHECK-LP32-NEXT: .long __ZN8test13_D1DEv
+// CHECK-LP32-NEXT: .long __ZN8test13_D2D1Ev
+// CHECK-LP32-NEXT: .long __ZN8test13_D2DbEv
+// CHECK-LP32-NEXT: .long __ZN8test13_D2DdEv
+// CHECK-LP32-NEXT: .long __ZN8test13_D2D2Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .long 4294967292
+// CHECK-LP32-NEXT: .long __ZTI8test13_D
+// CHECK-LP32-NEXT: .long __ZN9test13_B23B2aEv
+// CHECK-LP32-NEXT: .long __ZN9test13_B22B2Ev
+// CHECK-LP32-NEXT: .long __ZTv0_n24_N8test13_D1DEv
+// CHECK-LP32-NEXT: .long __ZN9test13_B22DaEv
+// CHECK-LP32-NEXT: .long __ZTv0_n32_N8test13_D2DdEv
+// CHECK-LP32-NEXT: .long __ZN9test13_B23B2bEv
+// CHECK-LP32-NEXT: .long 4294967288
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long 4294967288
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long __ZTI8test13_D
+// CHECK-LP32-NEXT: .long __ZN8test13_B2B1Ev
+// CHECK-LP32-NEXT: .long __ZTv0_n16_N8test13_D1DEv
+// CHECK-LP32-NEXT: .long __ZTv0_n20_N9test13_B22DaEv
+// CHECK-LP32-NEXT: .long __ZTv0_n24_N8test13_D2DbEv
+// CHECK-LP32-NEXT: .long __ZN8test13_B2DcEv
+// CHECK-LP32-NEXT: .long __ZTv0_n32_N9test13_B22B2Ev
+
+
+class test14 {
+public:
+ virtual void initWithInt(int a);
+ static test14 *withInt(int a);
+};
+
+void test14::initWithInt(int a) { }
+
+test14 *test14::withInt(int a) {
+ test14 *me = new test14;
+ me->initWithInt(a);
+ return me;
+}
+
+
+struct test15_B {
+ virtual test15_B *foo1() { return 0; }
+ virtual test15_B *foo2() { return 0; }
+ virtual test15_B *foo3() { return 0; }
+ int i;
+};
+
+struct test15_NV1 {
+ virtual void fooNV1() { }
+ int i;
+};
+
+struct test15_B2 : test15_NV1, virtual test15_B {
+ virtual test15_B2 *foo1() { return 0; }
+ virtual test15_B2 *foo2() { return 0; }
+ int i;
+};
+
+struct test15_D : test15_NV1, virtual test15_B2 {
+ virtual test15_D *foo1() { return 0; }
+};
+
+// CHECK-LP64:__ZTV8test15_D:
+// CHECK-LP64-NEXT: .quad 32
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI8test15_D
+// CHECK-LP64-NEXT: .quad __ZN10test15_NV16fooNV1Ev
+// CHECK-LP64-NEXT: .quad __ZN8test15_D4foo1Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad __ZTI8test15_D
+// CHECK-LP64-NEXT: .quad __ZN10test15_NV16fooNV1Ev
+// CHECK-LP64-NEXT: .quad __ZTcv0_n40_v0_n24_N8test15_D4foo1Ev
+// CHECK-LP64-NEXT: .quad __ZN9test15_B24foo2Ev
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad 18446744073709551584
+// CHECK-LP64-NEXT: .quad 18446744073709551584
+// CHECK-LP64-NEXT: .quad __ZTI8test15_D
+// CHECK-LP64-NEXT: .quad __ZTcv0_n24_v0_n32_N8test15_D4foo1Ev
+// CHECK-LP64-NEXT: .quad __ZTcv0_n32_v0_n24_N9test15_B24foo2Ev
+// CHECK-LP64-NEXT: .quad __ZN8test15_B4foo3Ev
+
+// CHECK-LP32:__ZTV8test15_D:
+// CHECK-LP32-NEXT: .long 20
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI8test15_D
+// CHECK-LP32-NEXT: .long __ZN10test15_NV16fooNV1Ev
+// CHECK-LP32-NEXT: .long __ZN8test15_D4foo1Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967288
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 12
+// CHECK-LP32-NEXT: .long 4294967288
+// CHECK-LP32-NEXT: .long __ZTI8test15_D
+// CHECK-LP32-NEXT: .long __ZN10test15_NV16fooNV1Ev
+// CHECK-LP32-NEXT: .long __ZTcv0_n20_v0_n12_N8test15_D4foo1Ev
+// CHECK-LP32-NEXT: .long __ZN9test15_B24foo2Ev
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long 4294967276
+// CHECK-LP32-NEXT: .long 4294967276
+// CHECK-LP32-NEXT: .long __ZTI8test15_D
+// CHECK-LP32-NEXT: .long __ZTcv0_n12_v0_n16_N8test15_D4foo1Ev
+// CHECK-LP32-NEXT: .long __ZTcv0_n16_v0_n12_N9test15_B24foo2Ev
+// CHECK-LP32-NEXT: .long __ZN8test15_B4foo3Ev
+
+
+
+// CHECK-LP64: __ZTV1B:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI1B
+// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
+// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
+
+// CHECK-LP32: __ZTV1B:
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI1B
+// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
+// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
+
+// CHECK-LP64: __ZTV1A:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI1A
+// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
+// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
+// CHECK-LP64-NEXT: .quad __ZN1A4foo1Ev
+// CHECK-LP64-NEXT: .quad __ZN1A4foo2Ev
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad __ZTI1A
+// CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev
+// CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev
+
+// CHECK-LP32: __ZTV1A:
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI1A
+// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
+// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
+// CHECK-LP32-NEXT: .long __ZN1A4foo1Ev
+// CHECK-LP32-NEXT: .long __ZN1A4foo2Ev
+// CHECK-LP32-NEXT: .long 4294967284
+// CHECK-LP32-NEXT: .long __ZTI1A
+// CHECK-LP32-NEXT: .long __ZN1C4bee1Ev
+// CHECK-LP32-NEXT: .long __ZN1C4bee2Ev
+
+// CHECK-LP32:__ZTV1F:
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 8
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI1F
+// CHECK-LP32-NEXT: .long __ZN1D3booEv
+// CHECK-LP32-NEXT: .long __ZN1F3fooEv
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long 4294967288
+// CHECK-LP32-NEXT: .long __ZTI1F
+// CHECK-LP32-NEXT: .long __ZN2D13barEv
+// CHECK-LP32-NEXT: .long __ZN2D14bar2Ev
+// CHECK-LP32-NEXT: .long __ZN2D14bar3Ev
+// CHECK-LP32-NEXT: .long __ZN2D14bar4Ev
+// CHECK-LP32-NEXT: .long __ZN2D14bar5Ev
+
+// CHECK-LP64: __ZTV1F:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 16
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI1F
+// CHECK-LP64-NEXT: .quad __ZN1D3booEv
+// CHECK-LP64-NEXT: .quad __ZN1F3fooEv
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad __ZTI1F
+// CHECK-LP64-NEXT: .quad __ZN2D13barEv
+// CHECK-LP64-NEXT: .quad __ZN2D14bar2Ev
+// CHECK-LP64-NEXT: .quad __ZN2D14bar3Ev
+// CHECK-LP64-NEXT: .quad __ZN2D14bar4Ev
+// CHECK-LP64-NEXT: .quad __ZN2D14bar5Ev
+
+test15_D d15;
+test13_D d13;
+test11_D d11;
+test10_D d10;
+test9_D d9;
+test8_D d8;
+
+test5_D d5;
+test4_D d4;
+test3_D d3;
+
+test6_D d6;
+test7_D d7;
diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp
new file mode 100644
index 000000000000..a825120ad229
--- /dev/null
+++ b/test/CodeGenCXX/virtual-base-cast.cpp
@@ -0,0 +1,9 @@
+// RUN: clang-cc -emit-llvm-only %s
+
+struct A { virtual ~A(); };
+struct B : A { virtual ~B(); };
+struct C : virtual B { virtual ~C(); };
+
+void f(C *c) {
+ A* a = c;
+}
diff --git a/test/CodeGenCXX/virtual-function-calls.cpp b/test/CodeGenCXX/virtual-function-calls.cpp
new file mode 100644
index 000000000000..ca5acbabcc99
--- /dev/null
+++ b/test/CodeGenCXX/virtual-function-calls.cpp
@@ -0,0 +1,11 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+
+// PR5021
+struct A {
+ virtual void f(char);
+};
+
+void f(A *a) {
+ // CHECK: call void %
+ a->f('c');
+}
diff --git a/test/CodeGenCXX/vtable-cast-crash.cpp b/test/CodeGenCXX/vtable-cast-crash.cpp
new file mode 100644
index 000000000000..a91d9790fe65
--- /dev/null
+++ b/test/CodeGenCXX/vtable-cast-crash.cpp
@@ -0,0 +1,21 @@
+// RUN: clang-cc -emit-llvm-only %s
+struct A
+{
+A();
+virtual ~A();
+};
+
+struct B: A
+{
+ B();
+ ~B();
+};
+
+B::B()
+{
+}
+
+B::~B()
+{
+}
+
diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp
new file mode 100644
index 000000000000..426c867a7b6b
--- /dev/null
+++ b/test/CodeGenCXX/x86_64-arguments.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o %t %s &&
+struct A { ~A(); };
+
+// RUN: grep 'define void @_Z2f11A(.struct.A\* .a)' %t &&
+void f1(A a) { }
+
+// RUN: grep 'define void @_Z2f2v(.struct.A\* noalias sret .agg.result)' %t &&
+A f2() { return A(); }
+
+// RUN: true