15abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s 25abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian 30e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] 45abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian 55abec14a235bff4026c030672701a9853350e8cfFariborz Jahanianstruct B1 { 65abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian virtual ~B1(); 75abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian}; 85abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian 95abec14a235bff4026c030672701a9853350e8cfFariborz JahanianB1::~B1() {} 105abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian 115abec14a235bff4026c030672701a9853350e8cfFariborz Jahanianvoid DELETE(B1 *pb1) { 125abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian pb1->B1::~B1(); 135abec14a235bff4026c030672701a9853350e8cfFariborz Jahanian} 140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK-LABEL: define void @_ZN2B1D0Ev 153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) 160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]]) 170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK-LABEL: define void @_Z6DELETEP2B1 183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) 190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]]) 200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 210e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate<class T> 220e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstruct Templ { 230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines virtual ~Templ(); // Out-of-line so that the destructor doesn't cause a vtable 240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines virtual void f() {} 250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines virtual void g() {} 260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}; 270e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate<class T> 280e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesstruct SubTempl : public Templ<T> { 290e2c34f92f00628d48968dfea096d36381f494cbStephen Hines virtual ~SubTempl() {} // override 300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines virtual void f() {} // override 310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines virtual void g() {} // override 320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}; 330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 340e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid f(SubTempl<int>* t) { 350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Qualified calls go through the (qualified) vtable in apple-kext mode. 360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // Since t's this pointer points to SubTempl's vtable, the call needs 370e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // to load Templ<int>'s vtable. Hence, Templ<int>::g needs to be 380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // instantiated in this TU, for it's referenced by the vtable. 390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // (This happens only in apple-kext mode; elsewhere virtual calls can always 400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // use the vtable pointer off this instead of having to load the vtable 410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines // symbol.) 420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines t->Templ::~Templ(); 430e2c34f92f00628d48968dfea096d36381f494cbStephen Hines} 440e2c34f92f00628d48968dfea096d36381f494cbStephen Hines 453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([7 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2) 460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: declare void @_ZN5TemplIiED0Ev(%struct.Templ*) 470e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this) 480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this) 49