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