1f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck %s 2f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -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 still 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 still 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 should be defined externally. Test1a()59f4a2713aSLionel SambucTest1a::Test1a() { use(typeid(Test1a)); } 60f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test1a = external unnamed_addr constant 61f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test1a = external constant 62f4a2713aSLionel Sambuc 63f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. foo()64f4a2713aSLionel Sambucinline void Test1a::foo() {} 65f4a2713aSLionel Sambuc 66f4a2713aSLionel Sambuc /*** Test1b ******************************************************************/ 67f4a2713aSLionel Sambuc 68f4a2713aSLionel Sambuc struct Test1b { 69f4a2713aSLionel Sambuc Test1b(); 70f4a2713aSLionel Sambuc virtual void foo(); 71f4a2713aSLionel Sambuc virtual void bar(); 72f4a2713aSLionel Sambuc }; 73f4a2713aSLionel Sambuc 74f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. foo()75f4a2713aSLionel Sambucinline void Test1b::foo() {} 76f4a2713aSLionel Sambuc 77f4a2713aSLionel Sambuc // V-table should be defined externally. Test1b()78f4a2713aSLionel SambucTest1b::Test1b() { use(typeid(Test1b)); } 79f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test1b = external unnamed_addr constant 80f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test1b = external constant 81f4a2713aSLionel Sambuc 82f4a2713aSLionel Sambuc /*** Test2a ******************************************************************/ 83f4a2713aSLionel Sambuc 84f4a2713aSLionel Sambuc struct Test2a { 85f4a2713aSLionel Sambuc Test2a(); 86f4a2713aSLionel Sambuc virtual void foo(); 87f4a2713aSLionel Sambuc virtual void bar(); 88f4a2713aSLionel Sambuc }; 89f4a2713aSLionel Sambuc 90f4a2713aSLionel Sambuc // V-table should be defined with strong linkage. Test2a()91f4a2713aSLionel SambucTest2a::Test2a() { use(typeid(Test2a)); } 92f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2a = unnamed_addr constant 93f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test2a = constant 94*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test2a = constant 95f4a2713aSLionel Sambuc 96f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. bar()97f4a2713aSLionel Sambucvoid Test2a::bar() {} foo()98f4a2713aSLionel Sambucinline void Test2a::foo() {} 99f4a2713aSLionel Sambuc 100f4a2713aSLionel Sambuc /*** Test2b ******************************************************************/ 101f4a2713aSLionel Sambuc 102f4a2713aSLionel Sambuc struct Test2b { 103f4a2713aSLionel Sambuc Test2b(); 104f4a2713aSLionel Sambuc virtual void foo(); 105f4a2713aSLionel Sambuc virtual void bar(); 106f4a2713aSLionel Sambuc }; 107f4a2713aSLionel Sambuc 108f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. bar()109f4a2713aSLionel Sambucvoid Test2b::bar() {} 110f4a2713aSLionel Sambuc 111f4a2713aSLionel Sambuc // V-table should be defined with strong linkage. Test2b()112f4a2713aSLionel SambucTest2b::Test2b() { use(typeid(Test2b)); } 113f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2b = unnamed_addr constant 114f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test2b = constant 115*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test2b = 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 127f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. bar()128f4a2713aSLionel Sambucvoid Test2c::bar() {} foo()129f4a2713aSLionel Sambucinline void Test2c::foo() {} 130f4a2713aSLionel Sambuc 131f4a2713aSLionel Sambuc // V-table should be defined with strong linkage. Test2c()132f4a2713aSLionel SambucTest2c::Test2c() { use(typeid(Test2c)); } 133f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2c = unnamed_addr constant 134f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test2c = constant 135*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test2c = constant 136f4a2713aSLionel Sambuc 137f4a2713aSLionel Sambuc /*** Test3a ******************************************************************/ 138f4a2713aSLionel Sambuc 139f4a2713aSLionel Sambuc struct Test3a { 140f4a2713aSLionel Sambuc Test3a(); 141f4a2713aSLionel Sambuc virtual void foo(); 142f4a2713aSLionel Sambuc virtual void bar(); 143f4a2713aSLionel Sambuc }; 144f4a2713aSLionel Sambuc 145f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test3a()146f4a2713aSLionel SambucTest3a::Test3a() { use(typeid(Test3a)); } 147f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3a = linkonce_odr unnamed_addr constant 148f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant 149*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test3a = linkonce_odr constant 150f4a2713aSLionel Sambuc 151f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. bar()152f4a2713aSLionel Sambucinline void Test3a::bar() {} foo()153f4a2713aSLionel Sambucinline void Test3a::foo() {} 154f4a2713aSLionel Sambuc 155f4a2713aSLionel Sambuc /*** Test3b ******************************************************************/ 156f4a2713aSLionel Sambuc 157f4a2713aSLionel Sambuc struct Test3b { 158f4a2713aSLionel Sambuc Test3b(); 159f4a2713aSLionel Sambuc virtual void foo(); 160f4a2713aSLionel Sambuc virtual void bar(); 161f4a2713aSLionel Sambuc }; 162f4a2713aSLionel Sambuc 163f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. bar()164f4a2713aSLionel Sambucinline void Test3b::bar() {} 165f4a2713aSLionel Sambuc 166f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test3b()167f4a2713aSLionel SambucTest3b::Test3b() { use(typeid(Test3b)); } 168f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3b = linkonce_odr unnamed_addr constant 169f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant 170*0a6a1f1dSLionel Sambuc // CHECK-LATE: @_ZTI6Test3b = linkonce_odr constant 171f4a2713aSLionel Sambuc foo()172f4a2713aSLionel Sambucinline void Test3b::foo() {} 173f4a2713aSLionel Sambuc 174f4a2713aSLionel Sambuc /*** Test3c ******************************************************************/ 175f4a2713aSLionel Sambuc 176f4a2713aSLionel Sambuc struct Test3c { 177f4a2713aSLionel Sambuc Test3c(); 178f4a2713aSLionel Sambuc virtual void foo(); 179f4a2713aSLionel Sambuc virtual void bar(); 180f4a2713aSLionel Sambuc }; 181f4a2713aSLionel Sambuc 182f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. bar()183f4a2713aSLionel Sambucinline void Test3c::bar() {} foo()184f4a2713aSLionel Sambucinline void Test3c::foo() {} 185f4a2713aSLionel Sambuc 186f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test3c()187f4a2713aSLionel SambucTest3c::Test3c() { use(typeid(Test3c)); } 188f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant 189f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test3c = linkonce_odr constant 190*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test3c = linkonce_odr constant 191f4a2713aSLionel Sambuc 192f4a2713aSLionel Sambuc /*** Test4a ******************************************************************/ 193f4a2713aSLionel Sambuc 194f4a2713aSLionel Sambuc template <class T> struct Test4a { 195f4a2713aSLionel Sambuc Test4a(); 196f4a2713aSLionel Sambuc virtual void foo(); 197f4a2713aSLionel Sambuc virtual void bar(); 198f4a2713aSLionel Sambuc }; 199f4a2713aSLionel Sambuc 200f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test4a()201f4a2713aSLionel Sambuctemplate <> Test4a<int>::Test4a() { use(typeid(Test4a)); } 202f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test4aIiE = linkonce_odr unnamed_addr constant 203f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test4aIiE = linkonce_odr constant 204*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test4aIiE = linkonce_odr constant 205f4a2713aSLionel Sambuc 206f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. bar()207f4a2713aSLionel Sambuctemplate <> inline void Test4a<int>::bar() {} foo()208f4a2713aSLionel Sambuctemplate <> inline void Test4a<int>::foo() {} 209f4a2713aSLionel Sambuc 210f4a2713aSLionel Sambuc /*** Test4b ******************************************************************/ 211f4a2713aSLionel Sambuc 212f4a2713aSLionel Sambuc template <class T> struct Test4b { 213f4a2713aSLionel Sambuc Test4b(); 214f4a2713aSLionel Sambuc virtual void foo(); 215f4a2713aSLionel Sambuc virtual void bar(); 216f4a2713aSLionel Sambuc }; 217f4a2713aSLionel Sambuc 218f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. bar()219f4a2713aSLionel Sambuctemplate <> inline void Test4b<int>::bar() {} 220f4a2713aSLionel Sambuc 221f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test4b()222f4a2713aSLionel Sambuctemplate <> Test4b<int>::Test4b() { use(typeid(Test4b)); } 223f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test4bIiE = linkonce_odr unnamed_addr constant 224f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test4bIiE = linkonce_odr constant 225*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test4bIiE = linkonce_odr constant 226f4a2713aSLionel Sambuc foo()227f4a2713aSLionel Sambuctemplate <> inline void Test4b<int>::foo() {} 228f4a2713aSLionel Sambuc 229f4a2713aSLionel Sambuc /*** Test4c ******************************************************************/ 230f4a2713aSLionel Sambuc 231f4a2713aSLionel Sambuc template <class T> struct Test4c { 232f4a2713aSLionel Sambuc Test4c(); 233f4a2713aSLionel Sambuc virtual void foo(); 234f4a2713aSLionel Sambuc virtual void bar(); 235f4a2713aSLionel Sambuc }; 236f4a2713aSLionel Sambuc 237f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. bar()238f4a2713aSLionel Sambuctemplate <> inline void Test4c<int>::bar() {} foo()239f4a2713aSLionel Sambuctemplate <> inline void Test4c<int>::foo() {} 240f4a2713aSLionel Sambuc 241f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test4c()242f4a2713aSLionel Sambuctemplate <> Test4c<int>::Test4c() { use(typeid(Test4c)); } 243f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test4cIiE = linkonce_odr unnamed_addr constant 244f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test4cIiE = linkonce_odr constant 245*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test4cIiE = linkonce_odr constant 246f4a2713aSLionel Sambuc 247f4a2713aSLionel Sambuc /*** Test5a ******************************************************************/ 248f4a2713aSLionel Sambuc 249f4a2713aSLionel Sambuc template <class T> struct Test5a { 250f4a2713aSLionel Sambuc Test5a(); 251f4a2713aSLionel Sambuc virtual void foo(); 252f4a2713aSLionel Sambuc virtual void bar(); 253f4a2713aSLionel Sambuc }; 254f4a2713aSLionel Sambuc 255f4a2713aSLionel Sambuc template <> inline void Test5a<int>::bar(); 256f4a2713aSLionel Sambuc template <> inline void Test5a<int>::foo(); 257f4a2713aSLionel Sambuc 258f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test5a()259f4a2713aSLionel Sambuctemplate <> Test5a<int>::Test5a() { use(typeid(Test5a)); } 260f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test5aIiE = linkonce_odr unnamed_addr constant 261f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test5aIiE = linkonce_odr constant 262*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test5aIiE = linkonce_odr constant 263f4a2713aSLionel Sambuc 264f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. bar()265f4a2713aSLionel Sambuctemplate <> inline void Test5a<int>::bar() {} foo()266f4a2713aSLionel Sambuctemplate <> inline void Test5a<int>::foo() {} 267f4a2713aSLionel Sambuc 268f4a2713aSLionel Sambuc /*** Test5b ******************************************************************/ 269f4a2713aSLionel Sambuc 270f4a2713aSLionel Sambuc template <class T> struct Test5b { 271f4a2713aSLionel Sambuc Test5b(); 272f4a2713aSLionel Sambuc virtual void foo(); 273f4a2713aSLionel Sambuc virtual void bar(); 274f4a2713aSLionel Sambuc }; 275f4a2713aSLionel Sambuc 276f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 277f4a2713aSLionel Sambuc template <> inline void Test5a<int>::bar(); bar()278f4a2713aSLionel Sambuctemplate <> inline void Test5b<int>::bar() {} 279f4a2713aSLionel Sambuc 280f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test5b()281f4a2713aSLionel Sambuctemplate <> Test5b<int>::Test5b() { use(typeid(Test5b)); } 282f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test5bIiE = linkonce_odr unnamed_addr constant 283f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test5bIiE = linkonce_odr constant 284*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test5bIiE = linkonce_odr constant 285f4a2713aSLionel Sambuc 286f4a2713aSLionel Sambuc template <> inline void Test5a<int>::foo(); foo()287f4a2713aSLionel Sambuctemplate <> inline void Test5b<int>::foo() {} 288f4a2713aSLionel Sambuc 289f4a2713aSLionel Sambuc /*** Test5c ******************************************************************/ 290f4a2713aSLionel Sambuc 291f4a2713aSLionel Sambuc template <class T> struct Test5c { 292f4a2713aSLionel Sambuc Test5c(); 293f4a2713aSLionel Sambuc virtual void foo(); 294f4a2713aSLionel Sambuc virtual void bar(); 295f4a2713aSLionel Sambuc }; 296f4a2713aSLionel Sambuc 297f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 298f4a2713aSLionel Sambuc template <> inline void Test5a<int>::bar(); 299f4a2713aSLionel Sambuc template <> inline void Test5a<int>::foo(); bar()300f4a2713aSLionel Sambuctemplate <> inline void Test5c<int>::bar() {} foo()301f4a2713aSLionel Sambuctemplate <> inline void Test5c<int>::foo() {} 302f4a2713aSLionel Sambuc 303f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. Test5c()304f4a2713aSLionel Sambuctemplate <> Test5c<int>::Test5c() { use(typeid(Test5c)); } 305f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test5cIiE = linkonce_odr unnamed_addr constant 306f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test5cIiE = linkonce_odr constant 307*0a6a1f1dSLionel Sambuc // CHECK: @_ZTI6Test5cIiE = linkonce_odr constant 308