diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:49:47 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-12-15 18:49:47 +0000 |
commit | 77212133072dc40f070a280af8217032f55a9eb4 (patch) | |
tree | 2fd5819f49caecc5f520219b6b9254fe94ebb138 /test/CodeGenCXX | |
parent | 4b08eb6308ca90a6c08e2fc79d100821b1b1f6aa (diff) | |
download | FreeBSD-src-77212133072dc40f070a280af8217032f55a9eb4.zip FreeBSD-src-77212133072dc40f070a280af8217032f55a9eb4.tar.gz |
Update clang to 91430.
Diffstat (limited to 'test/CodeGenCXX')
47 files changed, 664 insertions, 32 deletions
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp index 7663d2e..d4fc627 100644 --- a/test/CodeGenCXX/class-layout.cpp +++ b/test/CodeGenCXX/class-layout.cpp @@ -1,5 +1,9 @@ -// RUN: clang-cc %s -emit-llvm -o %t +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s // An extra byte shoudl be allocated for an empty class. -// RUN: grep '%.truct.A = type { i8 }' %t +// CHECK: %struct.A = type { i8 } struct A { } a; + +// No need to add tail padding here. +// CHECK: %struct.B = type { i8*, i32 } +struct B { void *a; int b; } b; diff --git a/test/CodeGenCXX/constructor-convert.cpp b/test/CodeGenCXX/constructor-convert.cpp new file mode 100644 index 0000000..6fa6d55 --- /dev/null +++ b/test/CodeGenCXX/constructor-convert.cpp @@ -0,0 +1,19 @@ +// RUN: clang -emit-llvm -S -o - %s + +// PR5775 +class Twine { + Twine(const char *Str) { } +}; + +static void error(const Twine &Message); + +template<typename> +struct opt_storage { + void f() { + error("cl::location(x) specified more than once!"); + } +}; + +void f(opt_storage<int> o) { + o.f(); +} diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp index 66ec9ea..1142aac 100644 --- a/test/CodeGenCXX/constructor-template.cpp +++ b/test/CodeGenCXX/constructor-template.cpp @@ -44,12 +44,10 @@ int main() { delete node; } -// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev: -// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED2Ev: // CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev: // CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev: +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev: -// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev: -// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED2Ev: // CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev: // CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev: +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev: diff --git a/test/CodeGenCXX/conversion-operator-base.cpp b/test/CodeGenCXX/conversion-operator-base.cpp new file mode 100644 index 0000000..49796d0 --- /dev/null +++ b/test/CodeGenCXX/conversion-operator-base.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm-only %s -verify +// PR5730 + +struct A { operator int(); float y; }; +struct B : A { double z; }; +void a() { switch(B()) {} } + diff --git a/test/CodeGenCXX/copy-assign-synthesis-3.cpp b/test/CodeGenCXX/copy-assign-synthesis-3.cpp new file mode 100644 index 0000000..3dab0f2a --- /dev/null +++ b/test/CodeGenCXX/copy-assign-synthesis-3.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -emit-llvm-only -verify %s + +struct A { + A& operator=(const A&); +}; + +struct B { + A a; + float b; + int (A::*c)(); + _Complex float d; +}; +void a(B& x, B& y) { + x = y; +} + diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp new file mode 100644 index 0000000..b4add46 --- /dev/null +++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm -o - %s | FileCheck %s + +struct A { virtual void a(); }; +A x(A& y) { return y; } + +// CHECK: define linkonce_odr void @_ZN1AC1ERKS_( +// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp index b89435a..c5e3c79 100644 --- a/test/CodeGenCXX/debug-info.cpp +++ b/test/CodeGenCXX/debug-info.cpp @@ -11,3 +11,10 @@ template<typename T> struct A { A<T> *next; }; void f(A<int>) { } + +struct B { }; + +void f() { + int B::*a = 0; + void (B::*b)() = 0; +} diff --git a/test/CodeGenCXX/default-constructor-template-member.cpp b/test/CodeGenCXX/default-constructor-template-member.cpp new file mode 100644 index 0000000..e0a17e0 --- /dev/null +++ b/test/CodeGenCXX/default-constructor-template-member.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s + +template <class T> struct A { A(); }; +struct B { A<int> x; }; +void a() { + B b; +} +// CHECK: call void @_ZN1BC1Ev +// CHECK: define linkonce_odr void @_ZN1BC1Ev +// CHECK: call void @_ZN1AIiEC1Ev diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index 3dd7219..5570fb4 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -11,7 +11,9 @@ void test1() { // CHECK: define void @_Z5test1v() nounwind { // CHECK-NEXT:entry: +// CHECK-NEXT: %exception.ptr = alloca i8* // CHECK-NEXT: %exception = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: store i8* %exception, i8** %exception.ptr // CHECK-NEXT: %0 = bitcast i8* %exception to %struct.test1_D* // CHECK-NEXT: %tmp = bitcast %struct.test1_D* %0 to i8* // CHECK-NEXT: call void @llvm.memcpy.i64(i8* %tmp, i8* bitcast (%struct.test1_D* @d1 to i8*), i64 8, i32 8) @@ -32,10 +34,13 @@ void test2() { // CHECK: define void @_Z5test2v() nounwind { // CHECK-NEXT:entry: +// CHECK-NEXT: %exception.ptr = alloca i8* // CHECK-NEXT: %exception = call i8* @__cxa_allocate_exception(i64 16) +// CHECK-NEXT: store i8* %exception, i8** %exception.ptr // CHECK-NEXT: %0 = bitcast i8* %exception to %struct.test2_D* -// CHECK-NEXT: call void @_ZN7test2_DC1ERKS_(%struct.test2_D* %0, %struct.test2_D* @d2) -// CHECK-NEXT: call void @__cxa_throw(i8* %exception, i8* bitcast (%0* @_ZTI7test2_D to i8*), i8* null) noreturn +// CHECK: invoke void @_ZN7test2_DC1ERKS_(%struct.test2_D* %0, %struct.test2_D* @d2) +// CHECK-NEXT: to label %invoke.cont unwind label %terminate.handler +// CHECK: call void @__cxa_throw(i8* %exception, i8* bitcast (%0* @_ZTI7test2_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -51,7 +56,9 @@ void test3() { // CHECK: define void @_Z5test3v() nounwind { // CHECK-NEXT: entry: +// CHECK-NEXT: %exception.ptr = alloca i8* // CHECK-NEXT: %exception = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: store i8* %exception, i8** %exception.ptr // CHECK-NEXT: %0 = bitcast i8* %exception to %struct.test3_D** // CHECK-NEXT: store %struct.test3_D* null, %struct.test3_D** %0 // CHECK-NEXT: call void @__cxa_throw(i8* %exception, i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn diff --git a/test/CodeGenCXX/elide-call-reference.cpp b/test/CodeGenCXX/elide-call-reference.cpp new file mode 100644 index 0000000..863e69c --- /dev/null +++ b/test/CodeGenCXX/elide-call-reference.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s +// PR5695 + +struct A { A(const A&); ~A(); }; +A& a(); +void b() { + A x = a(); +} + +// CHECK: call void @_ZN1AC1ERKS_ +// CHECK: call void @_ZN1AD1Ev diff --git a/test/CodeGenCXX/enum.cpp b/test/CodeGenCXX/enum.cpp new file mode 100644 index 0000000..6ce04a3 --- /dev/null +++ b/test/CodeGenCXX/enum.cpp @@ -0,0 +1,4 @@ +// RUN: clang-cc -emit-llvm-only -verify %s + +enum A { a } __attribute((packed)); +int func(A x) { return x==a; } diff --git a/test/CodeGenCXX/eval-recursive-constant.cpp b/test/CodeGenCXX/eval-recursive-constant.cpp new file mode 100644 index 0000000..b60070f --- /dev/null +++ b/test/CodeGenCXX/eval-recursive-constant.cpp @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -emit-llvm-only + +extern const int a,b; +const int a=b,b=a; +int c() { if (a) return 1; return 0; } diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp new file mode 100644 index 0000000..396ff44 --- /dev/null +++ b/test/CodeGenCXX/exceptions.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fexceptions + +struct allocator { + allocator(); + allocator(const allocator&); + ~allocator(); +}; + +void f(); +void g(bool b, bool c) { + if (b) { + if (!c) + throw allocator(); + + return; + } + f(); +} diff --git a/test/CodeGenCXX/function-template-explicit-specialization.cpp b/test/CodeGenCXX/function-template-explicit-specialization.cpp new file mode 100644 index 0000000..046bc32 --- /dev/null +++ b/test/CodeGenCXX/function-template-explicit-specialization.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s + +template<typename T> void a(T); +template<> void a(int) {} + +// CHECK: define void @_Z1aIiEvT_ + +namespace X { +template<typename T> void b(T); +template<> void b(int) {} +} + +// CHECK: define void @_ZN1X1bIiEEvT_ diff --git a/test/CodeGenCXX/global-llvm-constant.cpp b/test/CodeGenCXX/global-llvm-constant.cpp new file mode 100644 index 0000000..bd43196 --- /dev/null +++ b/test/CodeGenCXX/global-llvm-constant.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm -o - %s | FileCheck %s + +struct A { + A() { x = 10; } + int x; +}; + +const A x; + +// CHECK: @x = internal global diff --git a/test/CodeGenCXX/inline-functions.cpp b/test/CodeGenCXX/inline-functions.cpp new file mode 100644 index 0000000..9af4c6e --- /dev/null +++ b/test/CodeGenCXX/inline-functions.cpp @@ -0,0 +1,23 @@ +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// CHECK: ; ModuleID + +struct A { + inline void f(); +}; + +// CHECK-NOT: define void @_ZN1A1fEv +void A::f() { } + +template<typename> struct B { }; + +template<> struct B<char> { + inline void f(); +}; + +// CHECK-NOT: _ZN1BIcE1fEv +void B<char>::f() { } + +// We need a final CHECK line here. + +// CHECK: define void @_Z1fv +void f() { } diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp new file mode 100644 index 0000000..e61f33a --- /dev/null +++ b/test/CodeGenCXX/key-function-vtable.cpp @@ -0,0 +1,42 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +// Simple key function test +struct testa { virtual void a(); }; +void testa::a() {} + +// Simple key function test +struct testb { virtual void a() {} }; +testb *testbvar = new testb; + +// Key function with out-of-line inline definition +struct testc { virtual void a(); }; +inline void testc::a() {} + +// Key functions with inline specifier (PR5705) +struct testd { inline virtual void a(); }; +void testd::a() {} + +// Key functions with inline specifier (PR5705) +struct teste { inline virtual void a(); }; +teste *testevar = new teste; + +// Key functions with namespace (PR5711) +namespace { + struct testf { virtual void a(); }; +} +void testf::a() {} + +// Key functions with namespace (PR5711) +namespace { + struct testg { virtual void a(); }; +} +testg *testgvar = new testg; + +// FIXME: The checks are extremely difficult to get right when the globals +// aren't alphabetized +// CHECK: @_ZTV5testa = constant [3 x i8*] [i8* null +// CHECK: @_ZTV5testc = weak_odr constant [3 x i8*] [i8* null +// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal constant [3 x i8*] [i8* null +// CHECK: @_ZTV5teste = weak_odr constant [3 x i8*] [i8* null +// CHECK: @_ZTV5testb = weak_odr constant [3 x i8*] [i8* null + diff --git a/test/CodeGenCXX/mangle-extern-local.cpp b/test/CodeGenCXX/mangle-extern-local.cpp new file mode 100644 index 0000000..7c25859 --- /dev/null +++ b/test/CodeGenCXX/mangle-extern-local.cpp @@ -0,0 +1,45 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +// CHECK: @var1 = external global i32 +// CHECK: @_ZN1N4var2E = external global i32 +// CHECK: @var5 = external global i32 +// CHECK: @_ZN1N4var3E = external global i32 +// CHECK: @_ZN1N4var4E = external global i32 + +// CHECK: declare i32 @_Z5func1v() +// CHECK: declare i32 @_ZN1N5func2Ev() +// CHECK: declare i32 @func4() +// CHECK: declare i32 @_ZN1N5func3Ev() + +int f1() { + extern int var1, func1(); + return var1 + func1(); +} + +namespace N { + +int f2() { + extern int var2, func2(); + return var2 + func2(); +} + +struct S { + static int f3() { + extern int var3, func3(); + struct LC { int localfunc() { extern int var4; return var4; } }; + LC localobj; + return var3 + func3() + localobj.localfunc(); + } +}; + +int anchorf3() { return S::f3(); } + +extern "C" { +int f4() { + extern int var5, func4(); + return var5 + func4(); +} +} + +} + diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp index fbce204..a2994c4 100644 --- a/test/CodeGenCXX/mangle-subst-std.cpp +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -32,8 +32,26 @@ namespace std { void f(std::string) { } namespace std { + template<typename, typename> struct basic_istream { }; template<typename, typename> struct basic_ostream { }; + template<typename, typename> struct basic_iostream { }; } +// CHECK: _Z1fSi +void f(std::basic_istream<char, std::char_traits<char> >) { } + // CHECK: _Z1fSo void f(std::basic_ostream<char, std::char_traits<char> >) { } + +// CHECK: _Z1fSd +void f(std::basic_iostream<char, std::char_traits<char> >) { } + +extern "C++" { +namespace std +{ + typedef void (*terminate_handler) (); + + // CHECK: _ZSt13set_terminatePFvvE + terminate_handler set_terminate(terminate_handler) { return 0; } +} +} diff --git a/test/CodeGenCXX/mangle-unnamed.cpp b/test/CodeGenCXX/mangle-unnamed.cpp new file mode 100644 index 0000000..66c81e5 --- /dev/null +++ b/test/CodeGenCXX/mangle-unnamed.cpp @@ -0,0 +1,39 @@ +// RUN: clang-cc -emit-llvm-only -verify %s + +struct S { + virtual ~S() { } +}; + +// PR5706 +// Make sure this doesn't crash; the mangling doesn't matter because the name +// doesn't have linkage. +static struct : S { } obj8; + +void f() { + // Make sure this doesn't crash; the mangling doesn't matter because the + // generated vtable/etc. aren't modifiable (although it would be nice for + // codesize to make it consistent inside inline functions). + static struct : S { } obj8; +} + +inline int f2() { + // FIXME: We don't mangle the names of a or x correctly! + static struct { int a() { static int x; return ++x; } } obj; + return obj.a(); +} + +int f3() { return f2(); } + +struct A { + typedef struct { int x; } *ptr; + ptr m; + int a() { + static struct x { + // FIXME: We don't mangle the names of a or x correctly! + int a(ptr A::*memp) { static int x; return ++x; } + } a; + return a.a(&A::m); + } +}; + +int f4() { return A().a(); } diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 03e405e..62d8c6c 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -208,8 +208,9 @@ void extern_f(void); void extern_f(void) { } struct S7 { - struct S { S(); }; + S7(); + struct S { S(); }; struct { S s; } a; @@ -227,3 +228,31 @@ template<typename T> typename __enable_if<(__is_scalar<T>::__value), void>::__ty template void ft8<int>(); // CHECK: @_Z3ft8IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv template void ft8<void*>(); + +namespace Expressions { +// Unary operators. + +// CHECK: define void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i +template <int i> void f1(int (*)[(-i) + 2]) { }; +template void f1<1>(int (*)[1]); + +// CHECK: define void @_ZN11Expressions2f2ILi1EEEvPApsT__i +template <int i> void f2(int (*)[+i]) { }; +template void f2<1>(int (*)[1]); + +// Binary operators. + +// CHECK: define void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i +template <int i> void f3(int (*)[i+i]) { }; +template void f3<1>(int (*)[2]); + +// CHECK: define void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i +template <int i> void f4(int (*)[2 + i+i]) { }; +template void f4<1>(int (*)[4]); + +// The ternary operator. +// CHECK: define void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i +template <bool b> void f4(int (*)[b ? 1 : 2]) { }; +template void f4<true>(int (*)[1]); + +} diff --git a/test/CodeGenCXX/member-call-parens.cpp b/test/CodeGenCXX/member-call-parens.cpp new file mode 100644 index 0000000..0b808e0 --- /dev/null +++ b/test/CodeGenCXX/member-call-parens.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-llvm-only -verify %s + +struct A { int a(); }; +typedef int B; +void a() { + A x; + ((x.a))(); + ((x.*&A::a))(); + B y; + // FIXME: Sema doesn't like this for some reason... + //(y.~B)(); +} diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 05bf396..491ca53 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -105,3 +105,26 @@ namespace PR5593 { return f && f; } } + +namespace PR5718 { + struct A { }; + + bool f(void (A::*f)(), void (A::*g)()) { + return f == g; + } +} + +namespace BoolMemberPointer { + struct A { }; + + bool f(void (A::*f)()) { + return !f; + } + + bool g(void (A::*f)()) { + if (!!f) + return true; + return false; + } +} + diff --git a/test/CodeGenCXX/member-pointer-type-convert.cpp b/test/CodeGenCXX/member-pointer-type-convert.cpp new file mode 100644 index 0000000..290daf2 --- /dev/null +++ b/test/CodeGenCXX/member-pointer-type-convert.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s + +struct A; +typedef int A::*param_t; +struct { + const char *name; + param_t par; +} *ptr; + +// CHECK: type { i8*, {{i..}} } diff --git a/test/CodeGenCXX/predefined-expr.cpp b/test/CodeGenCXX/predefined-expr.cpp index 95bc255..45b4e9f 100644 --- a/test/CodeGenCXX/predefined-expr.cpp +++ b/test/CodeGenCXX/predefined-expr.cpp @@ -12,12 +12,12 @@ // 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 [30 x i8] c"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 [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00" +// CHECK: private constant [34 x i8] c"NS::Constructor::Constructor(int)\00" +// CHECK: private constant [31 x i8] c"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" diff --git a/test/CodeGenCXX/reference-init.cpp b/test/CodeGenCXX/reference-init.cpp new file mode 100644 index 0000000..9baad94 --- /dev/null +++ b/test/CodeGenCXX/reference-init.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -emit-llvm-only -verify %s + +struct XPTParamDescriptor {}; +struct nsXPTParamInfo { + nsXPTParamInfo(const XPTParamDescriptor& desc); +}; +void a(XPTParamDescriptor *params) { + const nsXPTParamInfo& paramInfo = params[0]; +} diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp index eaaf346..74dc0ea 100644 --- a/test/CodeGenCXX/references.cpp +++ b/test/CodeGenCXX/references.cpp @@ -1,5 +1,4 @@ // RUN: clang-cc -verify -emit-llvm -o - %s | FileCheck %s - void t1() { extern int& a; int b = a; @@ -19,7 +18,6 @@ void t3() { // Test reference binding. struct C { int a; }; - void f(const bool&); void f(const int&); void f(const _Complex int&); diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp new file mode 100644 index 0000000..a2a1cdd --- /dev/null +++ b/test/CodeGenCXX/rtti-linkage.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +// CHECK: _ZTS1B = constant +// CHECK: _ZTS1A = weak_odr constant +// CHECK: _ZTI1A = weak_odr constant +// CHECK: _ZTI1B = constant + +// A has no key function, so its RTTI data should be weak_odr. +struct A { }; + +// B has a key function defined in the translation unit, so the RTTI data should +// be emitted in this translation unit and have external linkage. +struct B : A { + virtual void f(); +}; +void B::f() { } diff --git a/test/CodeGenCXX/rtti.cpp b/test/CodeGenCXX/rtti.cpp index a1ff1ff..7ba4d56 100644 --- a/test/CodeGenCXX/rtti.cpp +++ b/test/CodeGenCXX/rtti.cpp @@ -3,6 +3,7 @@ // RUN: clang-cc -I%S -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll // RUN: FileCheck -check-prefix LL --input-file=%t.ll %s +// XFAIL: * #include <typeinfo> @@ -31,6 +32,11 @@ class test1_D : public test1_B7 { virtual void foo() { } } d1; +// CHECK:__ZTI7test1_D: +// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16 +// CHECK-NEXT: .quad __ZTS7test1_D +// CHECK-NEXT: .quad __ZTI8test1_B7 + // CHECK: __ZTSPVi: // CHECK-NEXT: .asciz "PVi" @@ -77,13 +83,6 @@ class test1_D : public test1_B7 { // CHECK-NEXT: .quad __ZTIFvvE // CHECK-NEXT: .quad __ZTI7test3_A - - -// CHECK:__ZTI7test1_D: -// CHECK-NEXT: .quad (__ZTVN10__cxxabiv120__si_class_type_infoE) + 16 -// CHECK-NEXT: .quad __ZTS7test1_D -// CHECK-NEXT: .quad __ZTI8test1_B7 - // CHECK:__ZTI8test1_B7: // CHECK-NEXT: .quad (__ZTVN10__cxxabiv121__vmi_class_type_infoE) + 16 // CHECK-NEXT: .quad __ZTS8test1_B7 @@ -141,7 +140,6 @@ class test1_D : public test1_B7 { // CHECK-NEXT: .quad __ZTS8test1_B2 // CHECK-NEXT: .quad __ZTI8test1_B1 - class NP { }; void test2_1(); void test2_2(test1_D *dp) { @@ -166,7 +164,7 @@ void test2_2(test1_D *dp) { // CHECK-LL-NEXT: %2 = load %"class.std::type_info"** %1 // CHECK-LL-NEXT: %call = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* %2, %"class.std::type_info"* bitcast (%{{[0-9]*}}* @_ZTI7test1_D to %"class.std::type_info"*)) -// CHECK-LL: %call2 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* bitcast (%0* @_ZTI2NP to %"class.std::type_info"*), %"class.std::type_info"* bitcast (%{{[0-9]*}}* @_ZTI7test1_D to %"class.std::type_info"*)) +// CHECK-LL: %call2 = call zeroext i1 @_ZNKSt9type_infoeqERKS_(%"class.std::type_info"* bitcast (%{{[0-9]*}}* @_ZTI2NP to %"class.std::type_info"*), %"class.std::type_info"* bitcast (%{{[0-9]*}}* @_ZTI7test1_D to %"class.std::type_info"*)) // CHECK-LL: %3 = bitcast %class.test1_B7* %tmp5 to %"class.std::type_info"*** // CHECK-LL-NEXT: %4 = icmp ne %"class.std::type_info"*** %3, null diff --git a/test/CodeGenCXX/static-assert.cpp b/test/CodeGenCXX/static-assert.cpp index 7757acd..e103b99 100644 --- a/test/CodeGenCXX/static-assert.cpp +++ b/test/CodeGenCXX/static-assert.cpp @@ -1,3 +1,7 @@ -// RUN: clang-cc %s -emit-llvm -o - -std=c++0x +// RUN: clang-cc %s -emit-llvm -o - -std=c++0x -verify static_assert(true, ""); + +void f() { + static_assert(true, ""); +} diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index 55877b2..9108544 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -1,13 +1,17 @@ -// 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 - +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s struct A { A(); ~A(); }; void f() { + // CHECK: call void @_ZN1AC1Ev( + // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) static A a; } +void g() { + // CHECK: call i8* @_Znwm(i64 1) + // CHECK: call void @_ZN1AC1Ev( + static A& a = *new A; +} diff --git a/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp new file mode 100644 index 0000000..d439cbd --- /dev/null +++ b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// CHECK: ; ModuleID +template<typename> struct A { static int a; }; + +// CHECK-NOT: @_ZN1AIcE1aE +template<> int A<char>::a; + +// CHECK: @_ZN1AIbE1aE = global i32 10 +template<> int A<bool>::a = 10; + + diff --git a/test/CodeGenCXX/template-linkage.cpp b/test/CodeGenCXX/template-linkage.cpp new file mode 100644 index 0000000..8013ba4 --- /dev/null +++ b/test/CodeGenCXX/template-linkage.cpp @@ -0,0 +1,24 @@ +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +template<typename T> struct A { + virtual void f(T) { } + inline void g() { } +}; + +// Explicit instantiations have external linkage. + +// CHECK: define void @_ZN1AIiE1gEv( +template void A<int>::g(); + +// CHECK: define void @_ZN1AIfE1fEf( +// CHECK: define void @_ZN1AIfE1gEv( +// FIXME: This should also emit the vtable. +template struct A<float>; + +// CHECK: define void @_Z1fIiEvT_ +template <typename T> void f(T) { } +template void f<int>(int); + +// CHECK: define void @_Z1gIiEvT_ +template <typename T> inline void g(T) { } +template void g<int>(int); + diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp new file mode 100644 index 0000000..7fe5563 --- /dev/null +++ b/test/CodeGenCXX/throw-expressions.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -emit-llvm-only -verify %s + +int val = 42; +int& test1() { + return throw val, val; +} + +int test2() { + return val ? throw val : val; +} diff --git a/test/CodeGenCXX/unary-type-trait.cpp b/test/CodeGenCXX/unary-type-trait.cpp new file mode 100644 index 0000000..b65b9f9 --- /dev/null +++ b/test/CodeGenCXX/unary-type-trait.cpp @@ -0,0 +1,3 @@ +// RUN: clang-cc -emit-llvm-only -verify %s + +bool a() { return __is_pod(int); } diff --git a/test/CodeGenCXX/virt-call-offsets.cpp b/test/CodeGenCXX/virt-call-offsets.cpp new file mode 100644 index 0000000..db0ba2f --- /dev/null +++ b/test/CodeGenCXX/virt-call-offsets.cpp @@ -0,0 +1,8 @@ +// RUN: clang -cc1 %s -emit-llvm -o - | FileCheck %s + +struct A { virtual void a(); }; +struct B : A {}; +struct C : B { virtual void a(); }; +void (C::*x)() = &C::a; + +// CHECK: @x = global %0 { i{{[0-9]+}} 1, i{{[0-9]+}} 0 } diff --git a/test/CodeGenCXX/virt-canonical-decl.cpp b/test/CodeGenCXX/virt-canonical-decl.cpp new file mode 100644 index 0000000..c1a8c23 --- /dev/null +++ b/test/CodeGenCXX/virt-canonical-decl.cpp @@ -0,0 +1,19 @@ +// RUN: clang-cc %s -emit-llvm-only + +class Base { +public: + virtual ~Base(); +}; + +Base::~Base() +{ +} + +class Foo : public Base { +public: + virtual ~Foo(); +}; + +Foo::~Foo() +{ +} diff --git a/test/CodeGenCXX/virt-dtor-key.cpp b/test/CodeGenCXX/virt-dtor-key.cpp index 30f3563..9cfd58d 100644 --- a/test/CodeGenCXX/virt-dtor-key.cpp +++ b/test/CodeGenCXX/virt-dtor-key.cpp @@ -1,5 +1,5 @@ // RUN: clang-cc -emit-llvm %s -o - | FileCheck %s -// CHECK: @_ZTI3foo = linkonce_odr constant +// CHECK: @_ZTI3foo = constant class foo { foo(); virtual ~foo(); diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp new file mode 100644 index 0000000..3fbdd2d --- /dev/null +++ b/test/CodeGenCXX/virt-template-vtable.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +template<class T> class A { + A() {} + virtual void a() {} +}; +class B : A<int> { + B(); +}; +B::B() {} + +// CHECK: @_ZTV1AIiE = weak_odr constant diff --git a/test/CodeGenCXX/virt-thunk-reference.cpp b/test/CodeGenCXX/virt-thunk-reference.cpp new file mode 100644 index 0000000..4b361cf --- /dev/null +++ b/test/CodeGenCXX/virt-thunk-reference.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -emit-llvm-only %s + +struct A { int a; virtual void aa(int&); }; +struct B { int b; virtual void bb(int&); }; +struct C : A,B { virtual void aa(int&), bb(int&); }; +void C::aa(int&) {} +void C::bb(int&) {} diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp index 7135aaf..e3b2afe2 100644 --- a/test/CodeGenCXX/virt.cpp +++ b/test/CodeGenCXX/virt.cpp @@ -768,7 +768,7 @@ struct test16_D : test16_NV1, virtual test16_B2 { // FIXME: This is the wrong thunk, but until these issues are fixed, better // than nothing. -// CHECK-LPLL64:define weak %class.test8_D* @_ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) { +// CHECK-LPLL64:define weak %class.test8_D* @_ZTcvn16_n72_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) // CHECK-LPLL64:entry: // CHECK-LPLL64: %retval = alloca %class.test8_D* // CHECK-LPLL64: %.addr = alloca %class.test8_D* @@ -790,7 +790,7 @@ struct test16_D : test16_NV1, virtual test16_B2 { // CHECK-LPLL64: ret %class.test8_D* %10 // CHECK-LPLL64:} -// CHECK-LPLL64:define weak %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) { +// CHECK-LPLL64:define weak %class.test8_D* @_ZTch0_v16_n32_N8test16_D4foo1Ev(%class.test8_D*) // CHECK-LPLL64:entry: // CHECK-LPLL64: %retval = alloca %class.test8_D* // CHECK-LPLL64: %.addr = alloca %class.test8_D* diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp new file mode 100644 index 0000000..976f562 --- /dev/null +++ b/test/CodeGenCXX/virtual-destructor-calls.cpp @@ -0,0 +1,24 @@ +// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s + +struct A { + virtual ~A(); +}; + +struct B : A { + virtual ~B(); +}; + +// Deleting dtor. +// CHECK: define void @_ZN1BD0Ev +// CHECK: call void @_ZN1AD2Ev +// check: call void @_ZdlPv + +// Complete dtor. +// CHECK: define void @_ZN1BD1Ev +// CHECK: call void @_ZN1AD2Ev + +// Base dtor. +// CHECK: define void @_ZN1BD2Ev +// CHECK: call void @_ZN1AD2Ev + +B::~B() { } diff --git a/test/CodeGenCXX/virtual-destructor-synthesis.cpp b/test/CodeGenCXX/virtual-destructor-synthesis.cpp new file mode 100644 index 0000000..b95218a --- /dev/null +++ b/test/CodeGenCXX/virtual-destructor-synthesis.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s + +struct box { + virtual ~box(); +}; + +struct pile_box : public box { + pile_box(box *); +}; + +pile_box::pile_box(box *pp) +{ +} + +// CHECK: call void @_ZdlPv + diff --git a/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp b/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp new file mode 100644 index 0000000..d179e9b --- /dev/null +++ b/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -emit-llvm -o - %s | FileCheck %s + +struct D; +struct B { + virtual D& operator = (const D&); +}; +struct D : B { D(); virtual void a(); }; +void D::a() {} + +// CHECK: @_ZTV1D = {{.*}} @_ZN1DaSERKS_ +// CHECK: define linkonce_odr {{.*}} @_ZN1DaSERKS_ diff --git a/test/CodeGenCXX/virtual-inherited-destructor.cpp b/test/CodeGenCXX/virtual-inherited-destructor.cpp new file mode 100644 index 0000000..52b62ed --- /dev/null +++ b/test/CodeGenCXX/virtual-inherited-destructor.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc %s -emit-llvm-only + +struct A { virtual ~A(); }; +struct B : A { + ~B() { } +}; +B x; + diff --git a/test/CodeGenCXX/vtable-key-function.cpp b/test/CodeGenCXX/vtable-key-function.cpp new file mode 100644 index 0000000..b0371c0 --- /dev/null +++ b/test/CodeGenCXX/vtable-key-function.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s +// PR5697 +namespace PR5697 { +struct A { + virtual void f() { } + A(); + A(int); +}; + +// A does not have a key function, so the first constructor we emit should +// cause the vtable to be defined (without assertions.) +// CHECK: @_ZTVN6PR56971AE = weak_odr constant +A::A() { } +A::A(int) { } +} diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp new file mode 100644 index 0000000..f2d914f --- /dev/null +++ b/test/CodeGenCXX/vtable-linkage.cpp @@ -0,0 +1,58 @@ +// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +namespace { + struct A { + virtual void f() { } + }; +} + +void f() { A b; } + +struct B { + B(); + virtual void f(); +}; + +B::B() { } + +struct C { + C(); + virtual void f() { } +}; + +C::C() { } + +struct D { + virtual void f(); +}; + +void D::f() { } + +static struct : D { } e; + +// B has a key function that is not defined in this translation unit so its vtable +// has external linkage. +// CHECK: @_ZTV1B = external constant + +// C has no key function, so its vtable should have weak_odr linkage. +// CHECK: @_ZTS1C = weak_odr constant +// CHECK: @_ZTI1C = weak_odr constant +// CHECK: @_ZTV1C = weak_odr constant + +// D has a key function that is defined in this translation unit so its vtable is +// defined in the translation unit. +// CHECK: @_ZTS1D = constant +// CHECK: @_ZTI1D = constant +// CHECK: @_ZTV1D = constant + +// The anonymous struct for e has no linkage, so the vtable should have +// internal linkage. +// CHECK: @"_ZTS3$_0" = internal constant +// CHECK: @"_ZTI3$_0" = internal constant +// CHECK: @"_ZTV3$_0" = internal constant + +// The A vtable should have internal linkage since it is inside an anonymous +// namespace. +// CHECK: @_ZTSN12_GLOBAL__N_11AE = internal constant +// CHECK: @_ZTIN12_GLOBAL__N_11AE = internal constant +// CHECK: @_ZTVN12_GLOBAL__N_11AE = internal constant |