1f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck %s 2f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s 3f4a2713aSLionel Sambuc 4f4a2713aSLionel Sambuc // The 'a' variants ask for the v-table first. 5f4a2713aSLionel Sambuc // The 'b' variants ask for the v-table second. 6f4a2713aSLionel Sambuc // The 'c' variants ask for the v-table third. 7*0a6a1f1dSLionel Sambuc // We do a separate CHECK-LATE pass because the RTTI definition gets 8f4a2713aSLionel Sambuc // changed after the fact, which causes reordering of the globals. 9f4a2713aSLionel Sambuc 10f4a2713aSLionel Sambuc // These are not separated into namespaces because the way that Sema 11f4a2713aSLionel Sambuc // currently reports namespaces to IR-generation (i.e., en masse for 12f4a2713aSLionel Sambuc // the entire namespace at once) subverts the ordering that we're 13f4a2713aSLionel Sambuc // trying to test. 14f4a2713aSLionel Sambuc 15f4a2713aSLionel Sambuc namespace std { class type_info; } 16f4a2713aSLionel Sambuc extern void use(const std::type_info &rtti); 17f4a2713aSLionel Sambuc 18f4a2713aSLionel Sambuc /*** Test0a ******************************************************************/ 19f4a2713aSLionel Sambuc 20f4a2713aSLionel Sambuc struct Test0a { 21f4a2713aSLionel Sambuc Test0a(); 22f4a2713aSLionel Sambuc virtual inline void foo(); 23f4a2713aSLionel Sambuc virtual void bar(); 24f4a2713aSLionel Sambuc }; 25f4a2713aSLionel Sambuc 26f4a2713aSLionel Sambuc // V-table should be defined externally. Test0a()27f4a2713aSLionel SambucTest0a::Test0a() { use(typeid(Test0a)); } 28f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test0a = external unnamed_addr constant 29f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test0a = external constant 30f4a2713aSLionel Sambuc 31f4a2713aSLionel Sambuc // This is not a key function. foo()32f4a2713aSLionel Sambucvoid Test0a::foo() {} 33f4a2713aSLionel Sambuc 34f4a2713aSLionel Sambuc /*** Test0b ******************************************************************/ 35f4a2713aSLionel Sambuc 36f4a2713aSLionel Sambuc struct Test0b { 37f4a2713aSLionel Sambuc Test0b(); 38f4a2713aSLionel Sambuc virtual inline void foo(); 39f4a2713aSLionel Sambuc virtual void bar(); 40f4a2713aSLionel Sambuc }; 41f4a2713aSLionel Sambuc 42f4a2713aSLionel Sambuc // This is not a key function. foo()43f4a2713aSLionel Sambucvoid Test0b::foo() {} 44f4a2713aSLionel Sambuc 45f4a2713aSLionel Sambuc // V-table should be defined externally. Test0b()46f4a2713aSLionel SambucTest0b::Test0b() { use(typeid(Test0b)); } 47f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test0b = external unnamed_addr constant 48f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test0b = external constant 49f4a2713aSLionel Sambuc 50f4a2713aSLionel Sambuc /*** Test1a ******************************************************************/ 51f4a2713aSLionel Sambuc 52f4a2713aSLionel Sambuc struct Test1a { 53f4a2713aSLionel Sambuc Test1a(); 54f4a2713aSLionel Sambuc virtual void foo(); 55f4a2713aSLionel Sambuc virtual void bar(); 56f4a2713aSLionel Sambuc }; 57f4a2713aSLionel Sambuc 58f4a2713aSLionel Sambuc // V-table needs to be defined weakly. Test1a()59f4a2713aSLionel SambucTest1a::Test1a() { use(typeid(Test1a)); } 60f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test1a = linkonce_odr unnamed_addr constant 61f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test1a = linkonce_odr constant 62*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test1a = linkonce_odr constant 63f4a2713aSLionel Sambuc 64f4a2713aSLionel Sambuc // This defines the key function. foo()65f4a2713aSLionel Sambucinline void Test1a::foo() {} 66f4a2713aSLionel Sambuc 67f4a2713aSLionel Sambuc /*** Test1b ******************************************************************/ 68f4a2713aSLionel Sambuc 69f4a2713aSLionel Sambuc struct Test1b { 70f4a2713aSLionel Sambuc Test1b(); 71f4a2713aSLionel Sambuc virtual void foo(); 72f4a2713aSLionel Sambuc virtual void bar(); 73f4a2713aSLionel Sambuc }; 74f4a2713aSLionel Sambuc 75f4a2713aSLionel Sambuc // This defines the key function. foo()76f4a2713aSLionel Sambucinline void Test1b::foo() {} 77f4a2713aSLionel Sambuc 78f4a2713aSLionel Sambuc // V-table should be defined weakly.. Test1b()79f4a2713aSLionel SambucTest1b::Test1b() { use(typeid(Test1b)); } 80f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test1b = linkonce_odr unnamed_addr constant 81f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test1b = linkonce_odr constant 82*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test1b = linkonce_odr constant 83f4a2713aSLionel Sambuc 84f4a2713aSLionel Sambuc /*** Test2a ******************************************************************/ 85f4a2713aSLionel Sambuc 86f4a2713aSLionel Sambuc struct Test2a { 87f4a2713aSLionel Sambuc Test2a(); 88f4a2713aSLionel Sambuc virtual void foo(); 89f4a2713aSLionel Sambuc virtual void bar(); 90f4a2713aSLionel Sambuc }; 91f4a2713aSLionel Sambuc 92f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test2a()93f4a2713aSLionel SambucTest2a::Test2a() { use(typeid(Test2a)); } 94f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2a = linkonce_odr unnamed_addr constant 95f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test2a = linkonce_odr constant 96*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test2a = linkonce_odr constant 97f4a2713aSLionel Sambuc bar()98f4a2713aSLionel Sambucvoid Test2a::bar() {} foo()99f4a2713aSLionel Sambucinline void Test2a::foo() {} 100f4a2713aSLionel Sambuc 101f4a2713aSLionel Sambuc /*** Test2b ******************************************************************/ 102f4a2713aSLionel Sambuc 103f4a2713aSLionel Sambuc struct Test2b { 104f4a2713aSLionel Sambuc Test2b(); 105f4a2713aSLionel Sambuc virtual void foo(); 106f4a2713aSLionel Sambuc virtual void bar(); 107f4a2713aSLionel Sambuc }; 108f4a2713aSLionel Sambuc bar()109f4a2713aSLionel Sambucvoid Test2b::bar() {} 110f4a2713aSLionel Sambuc 111f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test2b()112f4a2713aSLionel SambucTest2b::Test2b() { use(typeid(Test2b)); } 113f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2b = linkonce_odr unnamed_addr constant 114f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test2b = linkonce_odr constant 115*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test2b = linkonce_odr constant 116f4a2713aSLionel Sambuc foo()117f4a2713aSLionel Sambucinline void Test2b::foo() {} 118f4a2713aSLionel Sambuc 119f4a2713aSLionel Sambuc /*** Test2c ******************************************************************/ 120f4a2713aSLionel Sambuc 121f4a2713aSLionel Sambuc struct Test2c { 122f4a2713aSLionel Sambuc Test2c(); 123f4a2713aSLionel Sambuc virtual void foo(); 124f4a2713aSLionel Sambuc virtual void bar(); 125f4a2713aSLionel Sambuc }; 126f4a2713aSLionel Sambuc bar()127f4a2713aSLionel Sambucvoid Test2c::bar() {} foo()128f4a2713aSLionel Sambucinline void Test2c::foo() {} 129f4a2713aSLionel Sambuc 130f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test2c()131f4a2713aSLionel SambucTest2c::Test2c() { use(typeid(Test2c)); } 132f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2c = linkonce_odr unnamed_addr constant 133f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test2c = linkonce_odr constant 134*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test2c = linkonce_odr constant 135f4a2713aSLionel Sambuc 136f4a2713aSLionel Sambuc /*** Test3a ******************************************************************/ 137f4a2713aSLionel Sambuc 138f4a2713aSLionel Sambuc struct Test3a { 139f4a2713aSLionel Sambuc Test3a(); 140f4a2713aSLionel Sambuc virtual void foo(); 141f4a2713aSLionel Sambuc virtual void bar(); 142f4a2713aSLionel Sambuc }; 143f4a2713aSLionel Sambuc 144f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test3a()145f4a2713aSLionel SambucTest3a::Test3a() { use(typeid(Test3a)); } 146f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3a = linkonce_odr unnamed_addr constant 147f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant 148*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test3a = linkonce_odr constant 149f4a2713aSLionel Sambuc 150f4a2713aSLionel Sambuc // This defines the key function. bar()151f4a2713aSLionel Sambucinline void Test3a::bar() {} foo()152f4a2713aSLionel Sambucinline void Test3a::foo() {} 153f4a2713aSLionel Sambuc 154f4a2713aSLionel Sambuc /*** Test3b ******************************************************************/ 155f4a2713aSLionel Sambuc 156f4a2713aSLionel Sambuc struct Test3b { 157f4a2713aSLionel Sambuc Test3b(); 158f4a2713aSLionel Sambuc virtual void foo(); 159f4a2713aSLionel Sambuc virtual void bar(); 160f4a2713aSLionel Sambuc }; 161f4a2713aSLionel Sambuc bar()162f4a2713aSLionel Sambucinline void Test3b::bar() {} 163f4a2713aSLionel Sambuc 164f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test3b()165f4a2713aSLionel SambucTest3b::Test3b() { use(typeid(Test3b)); } 166f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3b = linkonce_odr unnamed_addr constant 167f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant 168*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test3b = linkonce_odr constant 169f4a2713aSLionel Sambuc 170f4a2713aSLionel Sambuc // This defines the key function. foo()171f4a2713aSLionel Sambucinline void Test3b::foo() {} 172f4a2713aSLionel Sambuc 173f4a2713aSLionel Sambuc /*** Test3c ******************************************************************/ 174f4a2713aSLionel Sambuc 175f4a2713aSLionel Sambuc struct Test3c { 176f4a2713aSLionel Sambuc Test3c(); 177f4a2713aSLionel Sambuc virtual void foo(); 178f4a2713aSLionel Sambuc virtual void bar(); 179f4a2713aSLionel Sambuc }; 180f4a2713aSLionel Sambuc 181f4a2713aSLionel Sambuc // This defines the key function. bar()182f4a2713aSLionel Sambucinline void Test3c::bar() {} foo()183f4a2713aSLionel Sambucinline void Test3c::foo() {} 184f4a2713aSLionel Sambuc 185f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test3c()186f4a2713aSLionel SambucTest3c::Test3c() { use(typeid(Test3c)); } 187f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant 188f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test3c = linkonce_odr constant 189*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test3c = linkonce_odr constant 190