1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck %s 2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 %s -triple=armv7-unknown-unknown -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s 3*f4a2713aSLionel Sambuc 4*f4a2713aSLionel Sambuc // The 'a' variants ask for the v-table first. 5*f4a2713aSLionel Sambuc // The 'b' variants ask for the v-table second. 6*f4a2713aSLionel Sambuc // The 'c' variants ask for the v-table third. 7*f4a2713aSLionel Sambuc // We do a separate CHECK-LATE pass because the RTTI defintion gets 8*f4a2713aSLionel Sambuc // changed after the fact, which causes reordering of the globals. 9*f4a2713aSLionel Sambuc 10*f4a2713aSLionel Sambuc // These are not separated into namespaces because the way that Sema 11*f4a2713aSLionel Sambuc // currently reports namespaces to IR-generation (i.e., en masse for 12*f4a2713aSLionel Sambuc // the entire namespace at once) subverts the ordering that we're 13*f4a2713aSLionel Sambuc // trying to test. 14*f4a2713aSLionel Sambuc 15*f4a2713aSLionel Sambuc namespace std { class type_info; } 16*f4a2713aSLionel Sambuc extern void use(const std::type_info &rtti); 17*f4a2713aSLionel Sambuc 18*f4a2713aSLionel Sambuc /*** Test0a ******************************************************************/ 19*f4a2713aSLionel Sambuc 20*f4a2713aSLionel Sambuc struct Test0a { 21*f4a2713aSLionel Sambuc Test0a(); 22*f4a2713aSLionel Sambuc virtual inline void foo(); 23*f4a2713aSLionel Sambuc virtual void bar(); 24*f4a2713aSLionel Sambuc }; 25*f4a2713aSLionel Sambuc 26*f4a2713aSLionel Sambuc // V-table should be defined externally. 27*f4a2713aSLionel Sambuc Test0a::Test0a() { use(typeid(Test0a)); } 28*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test0a = external unnamed_addr constant 29*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test0a = external constant 30*f4a2713aSLionel Sambuc 31*f4a2713aSLionel Sambuc // This is still not a key function. 32*f4a2713aSLionel Sambuc void Test0a::foo() {} 33*f4a2713aSLionel Sambuc 34*f4a2713aSLionel Sambuc /*** Test0b ******************************************************************/ 35*f4a2713aSLionel Sambuc 36*f4a2713aSLionel Sambuc struct Test0b { 37*f4a2713aSLionel Sambuc Test0b(); 38*f4a2713aSLionel Sambuc virtual inline void foo(); 39*f4a2713aSLionel Sambuc virtual void bar(); 40*f4a2713aSLionel Sambuc }; 41*f4a2713aSLionel Sambuc 42*f4a2713aSLionel Sambuc // This is still not a key function. 43*f4a2713aSLionel Sambuc void Test0b::foo() {} 44*f4a2713aSLionel Sambuc 45*f4a2713aSLionel Sambuc // V-table should be defined externally. 46*f4a2713aSLionel Sambuc Test0b::Test0b() { use(typeid(Test0b)); } 47*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test0b = external unnamed_addr constant 48*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test0b = external constant 49*f4a2713aSLionel Sambuc 50*f4a2713aSLionel Sambuc /*** Test1a ******************************************************************/ 51*f4a2713aSLionel Sambuc 52*f4a2713aSLionel Sambuc struct Test1a { 53*f4a2713aSLionel Sambuc Test1a(); 54*f4a2713aSLionel Sambuc virtual void foo(); 55*f4a2713aSLionel Sambuc virtual void bar(); 56*f4a2713aSLionel Sambuc }; 57*f4a2713aSLionel Sambuc 58*f4a2713aSLionel Sambuc // V-table should be defined externally. 59*f4a2713aSLionel Sambuc Test1a::Test1a() { use(typeid(Test1a)); } 60*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test1a = external unnamed_addr constant 61*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test1a = external constant 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. 64*f4a2713aSLionel Sambuc inline void Test1a::foo() {} 65*f4a2713aSLionel Sambuc 66*f4a2713aSLionel Sambuc /*** Test1b ******************************************************************/ 67*f4a2713aSLionel Sambuc 68*f4a2713aSLionel Sambuc struct Test1b { 69*f4a2713aSLionel Sambuc Test1b(); 70*f4a2713aSLionel Sambuc virtual void foo(); 71*f4a2713aSLionel Sambuc virtual void bar(); 72*f4a2713aSLionel Sambuc }; 73*f4a2713aSLionel Sambuc 74*f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. 75*f4a2713aSLionel Sambuc inline void Test1b::foo() {} 76*f4a2713aSLionel Sambuc 77*f4a2713aSLionel Sambuc // V-table should be defined externally. 78*f4a2713aSLionel Sambuc Test1b::Test1b() { use(typeid(Test1b)); } 79*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test1b = external unnamed_addr constant 80*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test1b = external constant 81*f4a2713aSLionel Sambuc 82*f4a2713aSLionel Sambuc /*** Test2a ******************************************************************/ 83*f4a2713aSLionel Sambuc 84*f4a2713aSLionel Sambuc struct Test2a { 85*f4a2713aSLionel Sambuc Test2a(); 86*f4a2713aSLionel Sambuc virtual void foo(); 87*f4a2713aSLionel Sambuc virtual void bar(); 88*f4a2713aSLionel Sambuc }; 89*f4a2713aSLionel Sambuc 90*f4a2713aSLionel Sambuc // V-table should be defined with strong linkage. 91*f4a2713aSLionel Sambuc Test2a::Test2a() { use(typeid(Test2a)); } 92*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2a = unnamed_addr constant 93*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test2a = constant 94*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTI6Test2a = unnamed_addr constant 95*f4a2713aSLionel Sambuc 96*f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. 97*f4a2713aSLionel Sambuc void Test2a::bar() {} 98*f4a2713aSLionel Sambuc inline void Test2a::foo() {} 99*f4a2713aSLionel Sambuc 100*f4a2713aSLionel Sambuc /*** Test2b ******************************************************************/ 101*f4a2713aSLionel Sambuc 102*f4a2713aSLionel Sambuc struct Test2b { 103*f4a2713aSLionel Sambuc Test2b(); 104*f4a2713aSLionel Sambuc virtual void foo(); 105*f4a2713aSLionel Sambuc virtual void bar(); 106*f4a2713aSLionel Sambuc }; 107*f4a2713aSLionel Sambuc 108*f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. 109*f4a2713aSLionel Sambuc void Test2b::bar() {} 110*f4a2713aSLionel Sambuc 111*f4a2713aSLionel Sambuc // V-table should be defined with strong linkage. 112*f4a2713aSLionel Sambuc Test2b::Test2b() { use(typeid(Test2b)); } 113*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2b = unnamed_addr constant 114*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test2b = constant 115*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTI6Test2b = unnamed_addr constant 116*f4a2713aSLionel Sambuc 117*f4a2713aSLionel Sambuc inline void Test2b::foo() {} 118*f4a2713aSLionel Sambuc 119*f4a2713aSLionel Sambuc /*** Test2c ******************************************************************/ 120*f4a2713aSLionel Sambuc 121*f4a2713aSLionel Sambuc struct Test2c { 122*f4a2713aSLionel Sambuc Test2c(); 123*f4a2713aSLionel Sambuc virtual void foo(); 124*f4a2713aSLionel Sambuc virtual void bar(); 125*f4a2713aSLionel Sambuc }; 126*f4a2713aSLionel Sambuc 127*f4a2713aSLionel Sambuc // 'bar' becomes the key function when 'foo' is defined inline. 128*f4a2713aSLionel Sambuc void Test2c::bar() {} 129*f4a2713aSLionel Sambuc inline void Test2c::foo() {} 130*f4a2713aSLionel Sambuc 131*f4a2713aSLionel Sambuc // V-table should be defined with strong linkage. 132*f4a2713aSLionel Sambuc Test2c::Test2c() { use(typeid(Test2c)); } 133*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test2c = unnamed_addr constant 134*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test2c = constant 135*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test2c = unnamed_addr constant 136*f4a2713aSLionel Sambuc 137*f4a2713aSLionel Sambuc /*** Test3a ******************************************************************/ 138*f4a2713aSLionel Sambuc 139*f4a2713aSLionel Sambuc struct Test3a { 140*f4a2713aSLionel Sambuc Test3a(); 141*f4a2713aSLionel Sambuc virtual void foo(); 142*f4a2713aSLionel Sambuc virtual void bar(); 143*f4a2713aSLionel Sambuc }; 144*f4a2713aSLionel Sambuc 145*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 146*f4a2713aSLionel Sambuc Test3a::Test3a() { use(typeid(Test3a)); } 147*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3a = linkonce_odr unnamed_addr constant 148*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant 149*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTI6Test3a = linkonce_odr unnamed_addr constant 150*f4a2713aSLionel Sambuc 151*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 152*f4a2713aSLionel Sambuc inline void Test3a::bar() {} 153*f4a2713aSLionel Sambuc inline void Test3a::foo() {} 154*f4a2713aSLionel Sambuc 155*f4a2713aSLionel Sambuc /*** Test3b ******************************************************************/ 156*f4a2713aSLionel Sambuc 157*f4a2713aSLionel Sambuc struct Test3b { 158*f4a2713aSLionel Sambuc Test3b(); 159*f4a2713aSLionel Sambuc virtual void foo(); 160*f4a2713aSLionel Sambuc virtual void bar(); 161*f4a2713aSLionel Sambuc }; 162*f4a2713aSLionel Sambuc 163*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 164*f4a2713aSLionel Sambuc inline void Test3b::bar() {} 165*f4a2713aSLionel Sambuc 166*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 167*f4a2713aSLionel Sambuc Test3b::Test3b() { use(typeid(Test3b)); } 168*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3b = linkonce_odr unnamed_addr constant 169*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant 170*f4a2713aSLionel Sambuc // CHECK-LATE: @_ZTI6Test3b = linkonce_odr unnamed_addr constant 171*f4a2713aSLionel Sambuc 172*f4a2713aSLionel Sambuc inline void Test3b::foo() {} 173*f4a2713aSLionel Sambuc 174*f4a2713aSLionel Sambuc /*** Test3c ******************************************************************/ 175*f4a2713aSLionel Sambuc 176*f4a2713aSLionel Sambuc struct Test3c { 177*f4a2713aSLionel Sambuc Test3c(); 178*f4a2713aSLionel Sambuc virtual void foo(); 179*f4a2713aSLionel Sambuc virtual void bar(); 180*f4a2713aSLionel Sambuc }; 181*f4a2713aSLionel Sambuc 182*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 183*f4a2713aSLionel Sambuc inline void Test3c::bar() {} 184*f4a2713aSLionel Sambuc inline void Test3c::foo() {} 185*f4a2713aSLionel Sambuc 186*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 187*f4a2713aSLionel Sambuc Test3c::Test3c() { use(typeid(Test3c)); } 188*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant 189*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test3c = linkonce_odr constant 190*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test3c = linkonce_odr unnamed_addr constant 191*f4a2713aSLionel Sambuc 192*f4a2713aSLionel Sambuc /*** Test4a ******************************************************************/ 193*f4a2713aSLionel Sambuc 194*f4a2713aSLionel Sambuc template <class T> struct Test4a { 195*f4a2713aSLionel Sambuc Test4a(); 196*f4a2713aSLionel Sambuc virtual void foo(); 197*f4a2713aSLionel Sambuc virtual void bar(); 198*f4a2713aSLionel Sambuc }; 199*f4a2713aSLionel Sambuc 200*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 201*f4a2713aSLionel Sambuc template <> Test4a<int>::Test4a() { use(typeid(Test4a)); } 202*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test4aIiE = linkonce_odr unnamed_addr constant 203*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test4aIiE = linkonce_odr constant 204*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test4aIiE = linkonce_odr unnamed_addr constant 205*f4a2713aSLionel Sambuc 206*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 207*f4a2713aSLionel Sambuc template <> inline void Test4a<int>::bar() {} 208*f4a2713aSLionel Sambuc template <> inline void Test4a<int>::foo() {} 209*f4a2713aSLionel Sambuc 210*f4a2713aSLionel Sambuc /*** Test4b ******************************************************************/ 211*f4a2713aSLionel Sambuc 212*f4a2713aSLionel Sambuc template <class T> struct Test4b { 213*f4a2713aSLionel Sambuc Test4b(); 214*f4a2713aSLionel Sambuc virtual void foo(); 215*f4a2713aSLionel Sambuc virtual void bar(); 216*f4a2713aSLionel Sambuc }; 217*f4a2713aSLionel Sambuc 218*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 219*f4a2713aSLionel Sambuc template <> inline void Test4b<int>::bar() {} 220*f4a2713aSLionel Sambuc 221*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 222*f4a2713aSLionel Sambuc template <> Test4b<int>::Test4b() { use(typeid(Test4b)); } 223*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test4bIiE = linkonce_odr unnamed_addr constant 224*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test4bIiE = linkonce_odr constant 225*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test4bIiE = linkonce_odr unnamed_addr constant 226*f4a2713aSLionel Sambuc 227*f4a2713aSLionel Sambuc template <> inline void Test4b<int>::foo() {} 228*f4a2713aSLionel Sambuc 229*f4a2713aSLionel Sambuc /*** Test4c ******************************************************************/ 230*f4a2713aSLionel Sambuc 231*f4a2713aSLionel Sambuc template <class T> struct Test4c { 232*f4a2713aSLionel Sambuc Test4c(); 233*f4a2713aSLionel Sambuc virtual void foo(); 234*f4a2713aSLionel Sambuc virtual void bar(); 235*f4a2713aSLionel Sambuc }; 236*f4a2713aSLionel Sambuc 237*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 238*f4a2713aSLionel Sambuc template <> inline void Test4c<int>::bar() {} 239*f4a2713aSLionel Sambuc template <> inline void Test4c<int>::foo() {} 240*f4a2713aSLionel Sambuc 241*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 242*f4a2713aSLionel Sambuc template <> Test4c<int>::Test4c() { use(typeid(Test4c)); } 243*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test4cIiE = linkonce_odr unnamed_addr constant 244*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test4cIiE = linkonce_odr constant 245*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test4cIiE = linkonce_odr unnamed_addr constant 246*f4a2713aSLionel Sambuc 247*f4a2713aSLionel Sambuc /*** Test5a ******************************************************************/ 248*f4a2713aSLionel Sambuc 249*f4a2713aSLionel Sambuc template <class T> struct Test5a { 250*f4a2713aSLionel Sambuc Test5a(); 251*f4a2713aSLionel Sambuc virtual void foo(); 252*f4a2713aSLionel Sambuc virtual void bar(); 253*f4a2713aSLionel Sambuc }; 254*f4a2713aSLionel Sambuc 255*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::bar(); 256*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::foo(); 257*f4a2713aSLionel Sambuc 258*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 259*f4a2713aSLionel Sambuc template <> Test5a<int>::Test5a() { use(typeid(Test5a)); } 260*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test5aIiE = linkonce_odr unnamed_addr constant 261*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test5aIiE = linkonce_odr constant 262*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test5aIiE = linkonce_odr unnamed_addr constant 263*f4a2713aSLionel Sambuc 264*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 265*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::bar() {} 266*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::foo() {} 267*f4a2713aSLionel Sambuc 268*f4a2713aSLionel Sambuc /*** Test5b ******************************************************************/ 269*f4a2713aSLionel Sambuc 270*f4a2713aSLionel Sambuc template <class T> struct Test5b { 271*f4a2713aSLionel Sambuc Test5b(); 272*f4a2713aSLionel Sambuc virtual void foo(); 273*f4a2713aSLionel Sambuc virtual void bar(); 274*f4a2713aSLionel Sambuc }; 275*f4a2713aSLionel Sambuc 276*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 277*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::bar(); 278*f4a2713aSLionel Sambuc template <> inline void Test5b<int>::bar() {} 279*f4a2713aSLionel Sambuc 280*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 281*f4a2713aSLionel Sambuc template <> Test5b<int>::Test5b() { use(typeid(Test5b)); } 282*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test5bIiE = linkonce_odr unnamed_addr constant 283*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test5bIiE = linkonce_odr constant 284*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test5bIiE = linkonce_odr unnamed_addr constant 285*f4a2713aSLionel Sambuc 286*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::foo(); 287*f4a2713aSLionel Sambuc template <> inline void Test5b<int>::foo() {} 288*f4a2713aSLionel Sambuc 289*f4a2713aSLionel Sambuc /*** Test5c ******************************************************************/ 290*f4a2713aSLionel Sambuc 291*f4a2713aSLionel Sambuc template <class T> struct Test5c { 292*f4a2713aSLionel Sambuc Test5c(); 293*f4a2713aSLionel Sambuc virtual void foo(); 294*f4a2713aSLionel Sambuc virtual void bar(); 295*f4a2713aSLionel Sambuc }; 296*f4a2713aSLionel Sambuc 297*f4a2713aSLionel Sambuc // There ceases to be a key function after these declarations. 298*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::bar(); 299*f4a2713aSLionel Sambuc template <> inline void Test5a<int>::foo(); 300*f4a2713aSLionel Sambuc template <> inline void Test5c<int>::bar() {} 301*f4a2713aSLionel Sambuc template <> inline void Test5c<int>::foo() {} 302*f4a2713aSLionel Sambuc 303*f4a2713aSLionel Sambuc // V-table should be defined with weak linkage. 304*f4a2713aSLionel Sambuc template <> Test5c<int>::Test5c() { use(typeid(Test5c)); } 305*f4a2713aSLionel Sambuc // CHECK: @_ZTV6Test5cIiE = linkonce_odr unnamed_addr constant 306*f4a2713aSLionel Sambuc // CHECK: @_ZTS6Test5cIiE = linkonce_odr constant 307*f4a2713aSLionel Sambuc // CHECK: @_ZTI6Test5cIiE = linkonce_odr unnamed_addr constant 308