diff options
Diffstat (limited to 'test/CodeGenCXX/vtable-key-function-ios.cpp')
-rw-r--r-- | test/CodeGenCXX/vtable-key-function-ios.cpp | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/test/CodeGenCXX/vtable-key-function-ios.cpp b/test/CodeGenCXX/vtable-key-function-ios.cpp new file mode 100644 index 0000000..bcd3e88 --- /dev/null +++ b/test/CodeGenCXX/vtable-key-function-ios.cpp @@ -0,0 +1,189 @@ +// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s + +// The 'a' variants ask for the v-table first. +// The 'b' variants ask for the v-table second. +// The 'c' variants ask for the v-table third. +// We do a separate CHECK-LATE pass because the RTTI defintion gets +// changed after the fact, which causes reordering of the globals. + +// These are not separated into namespaces because the way that Sema +// currently reports namespaces to IR-generation (i.e., en masse for +// the entire namespace at once) subverts the ordering that we're +// trying to test. + +namespace std { class type_info; } +extern void use(const std::type_info &rtti); + +/*** Test0a ******************************************************************/ + +struct Test0a { + Test0a(); + virtual inline void foo(); + virtual void bar(); +}; + +// V-table should be defined externally. +Test0a::Test0a() { use(typeid(Test0a)); } +// CHECK: @_ZTV6Test0a = external unnamed_addr constant +// CHECK: @_ZTI6Test0a = external constant + +// This is not a key function. +void Test0a::foo() {} + +/*** Test0b ******************************************************************/ + +struct Test0b { + Test0b(); + virtual inline void foo(); + virtual void bar(); +}; + +// This is not a key function. +void Test0b::foo() {} + +// V-table should be defined externally. +Test0b::Test0b() { use(typeid(Test0b)); } +// CHECK: @_ZTV6Test0b = external unnamed_addr constant +// CHECK: @_ZTI6Test0b = external constant + +/*** Test1a ******************************************************************/ + +struct Test1a { + Test1a(); + virtual void foo(); + virtual void bar(); +}; + +// V-table needs to be defined weakly. +Test1a::Test1a() { use(typeid(Test1a)); } +// CHECK: @_ZTV6Test1a = linkonce_odr unnamed_addr constant +// CHECK-LATE: @_ZTS6Test1a = linkonce_odr constant +// CHECK-LATE: @_ZTI6Test1a = linkonce_odr unnamed_addr constant + +// This defines the key function. +inline void Test1a::foo() {} + +/*** Test1b ******************************************************************/ + +struct Test1b { + Test1b(); + virtual void foo(); + virtual void bar(); +}; + +// This defines the key function. +inline void Test1b::foo() {} + +// V-table should be defined weakly.. +Test1b::Test1b() { use(typeid(Test1b)); } +// CHECK: @_ZTV6Test1b = linkonce_odr unnamed_addr constant +// CHECK: @_ZTS6Test1b = linkonce_odr constant +// CHECK: @_ZTI6Test1b = linkonce_odr unnamed_addr constant + +/*** Test2a ******************************************************************/ + +struct Test2a { + Test2a(); + virtual void foo(); + virtual void bar(); +}; + +// V-table should be defined with weak linkage. +Test2a::Test2a() { use(typeid(Test2a)); } +// CHECK: @_ZTV6Test2a = linkonce_odr unnamed_addr constant +// CHECK-LATE: @_ZTS6Test2a = linkonce_odr constant +// CHECK-LATE: @_ZTI6Test2a = linkonce_odr unnamed_addr constant + +void Test2a::bar() {} +inline void Test2a::foo() {} + +/*** Test2b ******************************************************************/ + +struct Test2b { + Test2b(); + virtual void foo(); + virtual void bar(); +}; + +void Test2b::bar() {} + +// V-table should be defined with weak linkage. +Test2b::Test2b() { use(typeid(Test2b)); } +// CHECK: @_ZTV6Test2b = linkonce_odr unnamed_addr constant +// CHECK-LATE: @_ZTS6Test2b = linkonce_odr constant +// CHECK-LATE: @_ZTI6Test2b = linkonce_odr unnamed_addr constant + +inline void Test2b::foo() {} + +/*** Test2c ******************************************************************/ + +struct Test2c { + Test2c(); + virtual void foo(); + virtual void bar(); +}; + +void Test2c::bar() {} +inline void Test2c::foo() {} + +// V-table should be defined with weak linkage. +Test2c::Test2c() { use(typeid(Test2c)); } +// CHECK: @_ZTV6Test2c = linkonce_odr unnamed_addr constant +// CHECK: @_ZTS6Test2c = linkonce_odr constant +// CHECK: @_ZTI6Test2c = linkonce_odr unnamed_addr constant + +/*** Test3a ******************************************************************/ + +struct Test3a { + Test3a(); + virtual void foo(); + virtual void bar(); +}; + +// V-table should be defined with weak linkage. +Test3a::Test3a() { use(typeid(Test3a)); } +// CHECK: @_ZTV6Test3a = linkonce_odr unnamed_addr constant +// CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant +// CHECK-LATE: @_ZTI6Test3a = linkonce_odr unnamed_addr constant + +// This defines the key function. +inline void Test3a::bar() {} +inline void Test3a::foo() {} + +/*** Test3b ******************************************************************/ + +struct Test3b { + Test3b(); + virtual void foo(); + virtual void bar(); +}; + +inline void Test3b::bar() {} + +// V-table should be defined with weak linkage. +Test3b::Test3b() { use(typeid(Test3b)); } +// CHECK: @_ZTV6Test3b = linkonce_odr unnamed_addr constant +// CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant +// CHECK-LATE: @_ZTI6Test3b = linkonce_odr unnamed_addr constant + +// This defines the key function. +inline void Test3b::foo() {} + +/*** Test3c ******************************************************************/ + +struct Test3c { + Test3c(); + virtual void foo(); + virtual void bar(); +}; + +// This defines the key function. +inline void Test3c::bar() {} +inline void Test3c::foo() {} + +// V-table should be defined with weak linkage. +Test3c::Test3c() { use(typeid(Test3c)); } +// CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant +// CHECK: @_ZTS6Test3c = linkonce_odr constant +// CHECK: @_ZTI6Test3c = linkonce_odr unnamed_addr constant |