diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 4c8b24812ddcd1dedaca343a6d4e76f91f398981 (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /test/CodeGenCXX | |
parent | 5362a71c02e7d448a8ce98cf00c47e353fba5d04 (diff) | |
download | src-4c8b24812ddcd1dedaca343a6d4e76f91f398981.tar.gz src-4c8b24812ddcd1dedaca343a6d4e76f91f398981.zip |
Update clang to r84119.vendor/clang/clang-r84119
Notes
Notes:
svn path=/vendor/clang/dist/; revision=198092
svn path=/vendor/clang/clang-84119/; revision=198093; tag=vendor/clang/clang-r84119
Diffstat (limited to 'test/CodeGenCXX')
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 |