1*c4f95ef8SRichard Smith // RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu %s -emit-llvm -o - | FileCheck %s
2*c4f95ef8SRichard Smith 
3*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_0:.*]] = {{.*}} [3 x i8] c"%s\00",
4*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_1:.*]] = {{.*}} [2 x i8] c"C\00",
5*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_2:.*]] = {{.*}} [4 x i8] c" {\0A\00",
6*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_3:.*]] = {{.*}} [5 x i8] c"%s%s\00",
7*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_4:.*]] = {{.*}} [3 x i8] c"  \00",
8*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_5:.*]] = {{.*}} [2 x i8] c"A\00",
9*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_6:.*]] = {{.*}} [14 x i8] c"%s%s %s = %d\0A\00",
10*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_7:.*]] = {{.*}} [5 x i8] c"    \00",
11*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_8:.*]] = {{.*}} [4 x i8] c"int\00",
12*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_9:.*]] = {{.*}} [2 x i8] c"n\00",
13*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_10:.*]] = {{.*}} [5 x i8] c"%s}\0A\00",
14*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_11:.*]] = {{.*}} [2 x i8] c"B\00",
15*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_12:.*]] = {{.*}} [10 x i8] c"%s%s %s =\00",
16*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_13:.*]] = {{.*}} [2 x i8] c"a\00",
17*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_14:.*]] = {{.*}} [15 x i8] c"%s%s %s = *%p\0A\00",
18*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_15:.*]] = {{.*}} [2 x i8] c"X\00",
19*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_16:.*]] = {{.*}} [2 x i8] c"x\00",
20*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_17:.*]] = {{.*}} [2 x i8] c"f\00",
21*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_18:.*]] = {{.*}} [2 x i8] c"g\00",
22*c4f95ef8SRichard Smith // CHECK-DAG: @[[STR_19:.*]] = {{.*}} [3 x i8] c"}\0A\00",
23*c4f95ef8SRichard Smith 
24*c4f95ef8SRichard Smith struct A { int n; };
25*c4f95ef8SRichard Smith struct B { int n; };
26*c4f95ef8SRichard Smith class X { private: int n; };
27*c4f95ef8SRichard Smith struct C : A, B { A a; X x; int f, g; };
28*c4f95ef8SRichard Smith 
29*c4f95ef8SRichard Smith template<typename ...T> int format(int a, const char *str, T ...);
30*c4f95ef8SRichard Smith 
31*c4f95ef8SRichard Smith int f();
32*c4f95ef8SRichard Smith 
33*c4f95ef8SRichard Smith // CHECK-LABEL: define {{.*}} @_Z1gR1C(
g(C & c)34*c4f95ef8SRichard Smith void g(C &c) {
35*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
36*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_0]], ptr noundef @[[STR_1]])
37*c4f95ef8SRichard Smith 
38*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
39*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJEEiiPKcDpT_(i32 {{.*}}, ptr noundef @[[STR_2]])
40*c4f95ef8SRichard Smith 
41*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
42*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_EEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_3]], ptr noundef @[[STR_4]], ptr noundef @[[STR_5]])
43*c4f95ef8SRichard Smith 
44*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
45*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJEEiiPKcDpT_(i32 {{.*}}, ptr noundef @[[STR_2]])
46*c4f95ef8SRichard Smith 
47*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
48*c4f95ef8SRichard Smith   // CHECK: %[[VAL_n:.*]] = getelementptr inbounds %[[VAL_struct_A:.*]], ptr %[[VAL_0:.*]], i32 0, i32 0
49*c4f95ef8SRichard Smith   // CHECK: %[[VAL_1:.*]] = load i32, ptr %[[VAL_n]],
50*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_iEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_6]], ptr noundef @[[STR_7]], ptr noundef @[[STR_8]], ptr noundef @[[STR_9]], i32 noundef %[[VAL_1]])
51*c4f95ef8SRichard Smith 
52*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
53*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_10]], ptr noundef @[[STR_4]])
54*c4f95ef8SRichard Smith 
55*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
56*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_EEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_3]], ptr noundef @[[STR_4]], ptr noundef @[[STR_11]])
57*c4f95ef8SRichard Smith 
58*c4f95ef8SRichard Smith   // CHECK: %[[VAL_2:.*]] = icmp eq ptr %[[VAL_0]], null
59*c4f95ef8SRichard Smith   // CHECK: br i1 %[[VAL_2]],
60*c4f95ef8SRichard Smith 
61*c4f95ef8SRichard Smith   // CHECK: %[[VAL_add_ptr:.*]] = getelementptr inbounds i8, ptr %[[VAL_0]], i64 4
62*c4f95ef8SRichard Smith   // CHECK: br label
63*c4f95ef8SRichard Smith 
64*c4f95ef8SRichard Smith   // CHECK: %[[VAL_cast_result:.*]] = phi
65*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
66*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJEEiiPKcDpT_(i32 {{.*}}, ptr noundef @[[STR_2]])
67*c4f95ef8SRichard Smith 
68*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
69*c4f95ef8SRichard Smith   // CHECK: %[[VAL_n17:.*]] = getelementptr inbounds %[[VAL_struct_B:.*]], ptr %[[VAL_cast_result]], i32 0, i32 0
70*c4f95ef8SRichard Smith   // CHECK: %[[VAL_3:.*]] = load i32, ptr %[[VAL_n17]],
71*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_iEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_6]], ptr noundef @[[STR_7]], ptr noundef @[[STR_8]], ptr noundef @[[STR_9]], i32 noundef %[[VAL_3]])
72*c4f95ef8SRichard Smith 
73*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
74*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_10]], ptr noundef @[[STR_4]])
75*c4f95ef8SRichard Smith 
76*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
77*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_EEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_12]], ptr noundef @[[STR_4]], ptr noundef @[[STR_5]], ptr noundef @[[STR_13]])
78*c4f95ef8SRichard Smith 
79*c4f95ef8SRichard Smith   // CHECK: %[[VAL_a:.*]] = getelementptr inbounds %[[VAL_struct_C:.*]], ptr %[[VAL_0]], i32 0, i32 2
80*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
81*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJEEiiPKcDpT_(i32 {{.*}}, ptr noundef @[[STR_2]])
82*c4f95ef8SRichard Smith 
83*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
84*c4f95ef8SRichard Smith   // CHECK: %[[VAL_n26:.*]] = getelementptr inbounds %[[VAL_struct_A]], ptr %[[VAL_a]], i32 0, i32 0
85*c4f95ef8SRichard Smith   // CHECK: %[[VAL_4:.*]] = load i32, ptr %[[VAL_n26]],
86*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_iEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_6]], ptr noundef @[[STR_7]], ptr noundef @[[STR_8]], ptr noundef @[[STR_9]], i32 noundef %[[VAL_4]])
87*c4f95ef8SRichard Smith 
88*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
89*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_10]], ptr noundef @[[STR_4]])
90*c4f95ef8SRichard Smith 
91*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
92*c4f95ef8SRichard Smith   // CHECK: %[[VAL_x:.*]] = getelementptr inbounds %[[VAL_struct_C]], ptr %[[VAL_0]], i32 0, i32 3
93*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_P1XEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_14]], ptr noundef @[[STR_4]], ptr noundef @[[STR_15]], ptr noundef @[[STR_16]], ptr noundef %[[VAL_x]])
94*c4f95ef8SRichard Smith 
95*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
96*c4f95ef8SRichard Smith   // CHECK: %[[VAL_f:.*]] = getelementptr inbounds %[[VAL_struct_C]], ptr %[[VAL_0]], i32 0, i32 4
97*c4f95ef8SRichard Smith   // CHECK: %[[VAL_5:.*]] = load i32, ptr %[[VAL_f]],
98*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_iEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_6]], ptr noundef @[[STR_4]], ptr noundef @[[STR_8]], ptr noundef @[[STR_17]], i32 noundef %[[VAL_5]])
99*c4f95ef8SRichard Smith 
100*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
101*c4f95ef8SRichard Smith   // CHECK: %[[VAL_g:.*]] = getelementptr inbounds %[[VAL_struct_C]], ptr %[[VAL_0]], i32 0, i32 5
102*c4f95ef8SRichard Smith   // CHECK: %[[VAL_6:.*]] = load i32, ptr %[[VAL_g]],
103*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_iEEiiS1_DpT_(i32 {{.*}}, ptr noundef @[[STR_6]], ptr noundef @[[STR_4]], ptr noundef @[[STR_8]], ptr noundef @[[STR_18]], i32 noundef %[[VAL_6]])
104*c4f95ef8SRichard Smith 
105*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z1fv()
106*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJEEiiPKcDpT_(i32 {{.*}}, ptr noundef @[[STR_19]])
107*c4f95ef8SRichard Smith   __builtin_dump_struct(&c, format, f());
108*c4f95ef8SRichard Smith }
109*c4f95ef8SRichard Smith 
110*c4f95ef8SRichard Smith // CHECK-LABEL: define {{.*}} @_Z1hR1X(
h(X & x)111*c4f95ef8SRichard Smith void h(X &x) {
112*c4f95ef8SRichard Smith   // CHECK: %[[VAL_x_addr:.*]] = alloca ptr,
113*c4f95ef8SRichard Smith   // CHECK: store ptr %[[VAL_x]], ptr %[[VAL_x_addr]],
114*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcEEiiS1_DpT_(i32 noundef 0, ptr noundef @[[STR_0]], ptr noundef @[[STR_15]])
115*c4f95ef8SRichard Smith 
116*c4f95ef8SRichard Smith   // CHECK: %[[VAL_0:.*]] = load ptr, ptr %[[VAL_x_addr]],
117*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJEEiiPKcDpT_(i32 noundef 0, ptr noundef @[[STR_2]])
118*c4f95ef8SRichard Smith 
119*c4f95ef8SRichard Smith   // CHECK: %[[VAL_n:.*]] = getelementptr inbounds %[[VAL_class_X:.*]], ptr %[[VAL_0]], i32 0, i32 0
120*c4f95ef8SRichard Smith   // CHECK: %[[VAL_1:.*]] = load i32, ptr %[[VAL_n]],
121*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJPKcS1_S1_iEEiiS1_DpT_(i32 noundef 0, ptr noundef @[[STR_6]], ptr noundef @[[STR_4]], ptr noundef @[[STR_8]], ptr noundef @[[STR_9]], i32 noundef %[[VAL_1]])
122*c4f95ef8SRichard Smith 
123*c4f95ef8SRichard Smith   // CHECK: call {{.*}} @_Z6formatIJEEiiPKcDpT_(i32 noundef 0, ptr noundef @[[STR_19]])
124*c4f95ef8SRichard Smith   __builtin_dump_struct(&x, format, 0);
125*c4f95ef8SRichard Smith }
126