xref: /aosp_15_r20/external/clang/test/CodeGenCXX/apple-kext-indirect-call-2.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s
2*67e74705SXin Li 
3*67e74705SXin Li // CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null]
4*67e74705SXin Li // CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null]
5*67e74705SXin Li // CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null]
6*67e74705SXin Li // CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null]
7*67e74705SXin Li 
8*67e74705SXin Li struct A {
9*67e74705SXin Li   virtual const char* abc(void) const;
10*67e74705SXin Li };
11*67e74705SXin Li 
abc(void) const12*67e74705SXin Li const char* A::abc(void) const {return "A"; };
13*67e74705SXin Li 
14*67e74705SXin Li struct B : virtual A {
15*67e74705SXin Li   virtual void VF();
16*67e74705SXin Li };
17*67e74705SXin Li 
VF()18*67e74705SXin Li void B::VF() {}
19*67e74705SXin Li 
FUNC(B * p)20*67e74705SXin Li void FUNC(B* p) {
21*67e74705SXin Li // CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2)
22*67e74705SXin Li // CHECK-NEXT:  [[T2:%.*]] = call i8* [[T1]]
23*67e74705SXin Li   const char* c = p->A::abc();
24*67e74705SXin Li }
25*67e74705SXin Li 
26*67e74705SXin Li 
27*67e74705SXin Li // Test2
28*67e74705SXin Li struct Base { virtual char* abc(void) const; };
29*67e74705SXin Li 
abc() const30*67e74705SXin Li char* Base::abc() const { return 0; }
31*67e74705SXin Li 
32*67e74705SXin Li struct Derived : public Base {
33*67e74705SXin Li };
34*67e74705SXin Li 
FUNC1(Derived * p)35*67e74705SXin Li void FUNC1(Derived* p) {
36*67e74705SXin Li // CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.Base*)**), i64 2)
37*67e74705SXin Li // CHECK-NEXT:  [[U2:%.*]] = call i8* [[U1]]
38*67e74705SXin Li   char* c = p->Base::abc();
39*67e74705SXin Li }
40*67e74705SXin Li 
41*67e74705SXin Li 
42*67e74705SXin Li // Test3
43*67e74705SXin Li struct Base2 { };
44*67e74705SXin Li 
45*67e74705SXin Li struct Derived2 : virtual Base2 {
46*67e74705SXin Li   virtual char* efg(void) const;
47*67e74705SXin Li };
48*67e74705SXin Li 
efg(void) const49*67e74705SXin Li char* Derived2::efg(void) const { return 0; }
50*67e74705SXin Li 
FUNC2(Derived2 * p)51*67e74705SXin Li void FUNC2(Derived2* p) {
52*67e74705SXin Li // CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3)
53*67e74705SXin Li // CHECK-NEXT:  [[V2:%.*]] = call i8* [[V1]]
54*67e74705SXin Li   char* c = p->Derived2::efg();
55*67e74705SXin Li }
56*67e74705SXin Li 
57*67e74705SXin Li // Test4
58*67e74705SXin Li struct Base3 { };
59*67e74705SXin Li 
60*67e74705SXin Li struct D1 : virtual Base3 {
61*67e74705SXin Li };
62*67e74705SXin Li 
63*67e74705SXin Li struct D2 : virtual Base3 {
64*67e74705SXin Li  virtual char *abc(void) const;
65*67e74705SXin Li };
66*67e74705SXin Li 
67*67e74705SXin Li struct Sub : D1, D2 {
68*67e74705SXin Li };
69*67e74705SXin Li 
abc(void) const70*67e74705SXin Li char* D2::abc(void) const { return 0; }
71*67e74705SXin Li 
FUNC3(Sub * p)72*67e74705SXin Li void FUNC3(Sub* p) {
73*67e74705SXin Li // CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3)
74*67e74705SXin Li // CHECK-NEXT:  [[W2:%.*]] = call i8* [[W1]]
75*67e74705SXin Li   char* c = p->D2::abc();
76*67e74705SXin Li }
77*67e74705SXin Li 
78