xref: /llvm-project/clang/test/CodeGen/x64-microsoft-arguments.cpp (revision 3f37397c959a85f4cad91b655ea03a5d2450ab38)
1*3f37397cSMax Winkler // RUN: %clang_cc1 -triple x86_64-windows-msvc -ffreestanding -emit-llvm -O0 \
2*3f37397cSMax Winkler // RUN: -x c++ -o - %s | FileCheck %s
3*3f37397cSMax Winkler 
4*3f37397cSMax Winkler int global_i = 0;
5*3f37397cSMax Winkler 
6*3f37397cSMax Winkler // Pass and return object with a reference type (pass directly, return indirectly).
7*3f37397cSMax Winkler // CHECK: define dso_local void @"?f1@@YA?AUS1@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S1) align 8 {{.*}})
8*3f37397cSMax Winkler // CHECK: call void @"?func1@@YA?AUS1@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S1) align 8 {{.*}}, i64 {{.*}})
9*3f37397cSMax Winkler struct S1 {
10*3f37397cSMax Winkler   int& r;
11*3f37397cSMax Winkler };
12*3f37397cSMax Winkler 
13*3f37397cSMax Winkler S1 func1(S1 x);
f1()14*3f37397cSMax Winkler S1 f1() {
15*3f37397cSMax Winkler   S1 x{ global_i };
16*3f37397cSMax Winkler   return func1(x);
17*3f37397cSMax Winkler }
18*3f37397cSMax Winkler 
19*3f37397cSMax Winkler // Pass and return object with a reference type within an inner struct (pass directly, return indirectly).
20*3f37397cSMax Winkler // CHECK: define dso_local void @"?f2@@YA?AUS2@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S2) align 8 {{.*}})
21*3f37397cSMax Winkler // CHECK: call void @"?func2@@YA?AUS2@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S2) align 8 {{.*}}, i64 {{.*}})
22*3f37397cSMax Winkler struct Inner {
23*3f37397cSMax Winkler   int& r;
24*3f37397cSMax Winkler };
25*3f37397cSMax Winkler 
26*3f37397cSMax Winkler struct S2 {
27*3f37397cSMax Winkler   Inner i;
28*3f37397cSMax Winkler };
29*3f37397cSMax Winkler 
30*3f37397cSMax Winkler S2 func2(S2 x);
f2()31*3f37397cSMax Winkler S2 f2() {
32*3f37397cSMax Winkler   S2 x{ { global_i } };
33*3f37397cSMax Winkler   return func2(x);
34*3f37397cSMax Winkler }
35*3f37397cSMax Winkler 
36*3f37397cSMax Winkler // Pass and return object with a reference type (pass directly, return indirectly).
37*3f37397cSMax Winkler // CHECK: define dso_local void @"?f3@@YA?AUS3@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S3) align 8 {{.*}})
38*3f37397cSMax Winkler // CHECK: call void @"?func3@@YA?AUS3@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S3) align 8 {{.*}}, i64 {{.*}})
39*3f37397cSMax Winkler struct S3 {
40*3f37397cSMax Winkler   const int& r;
41*3f37397cSMax Winkler };
42*3f37397cSMax Winkler 
43*3f37397cSMax Winkler S3 func3(S3 x);
f3()44*3f37397cSMax Winkler S3 f3() {
45*3f37397cSMax Winkler   S3 x{ global_i };
46*3f37397cSMax Winkler   return func3(x);
47*3f37397cSMax Winkler }
48*3f37397cSMax Winkler 
49*3f37397cSMax Winkler // Pass and return object with a reference type within an inner struct (pass directly, return indirectly).
50*3f37397cSMax Winkler // CHECK: define dso_local void @"?f4@@YA?AUS4@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S4) align 8 {{.*}})
51*3f37397cSMax Winkler // CHECK: call void @"?func4@@YA?AUS4@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S4) align 8 {{.*}}, i64 {{.*}})
52*3f37397cSMax Winkler struct InnerConst {
53*3f37397cSMax Winkler   const int& r;
54*3f37397cSMax Winkler };
55*3f37397cSMax Winkler 
56*3f37397cSMax Winkler struct S4 {
57*3f37397cSMax Winkler   InnerConst i;
58*3f37397cSMax Winkler };
59*3f37397cSMax Winkler 
60*3f37397cSMax Winkler S4 func4(S4 x);
f4()61*3f37397cSMax Winkler S4 f4() {
62*3f37397cSMax Winkler   S4 x{ { global_i } };
63*3f37397cSMax Winkler   return func4(x);
64*3f37397cSMax Winkler }
65*3f37397cSMax Winkler 
66*3f37397cSMax Winkler // Pass and return an object with an explicitly deleted copy assignment operator (pass directly, return indirectly).
67*3f37397cSMax Winkler // CHECK: define dso_local void @"?f5@@YA?AUS5@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S5) align 4 {{.*}})
68*3f37397cSMax Winkler // CHECK: call void @"?func5@@YA?AUS5@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S5) align 4 {{.*}}, i32 {{.*}})
69*3f37397cSMax Winkler struct S5 {
70*3f37397cSMax Winkler   S5& operator=(const S5&) = delete;
71*3f37397cSMax Winkler   int i;
72*3f37397cSMax Winkler };
73*3f37397cSMax Winkler 
74*3f37397cSMax Winkler S5 func5(S5 x);
f5()75*3f37397cSMax Winkler S5 f5() {
76*3f37397cSMax Winkler   S5 x{ 1 };
77*3f37397cSMax Winkler   return func5(x);
78*3f37397cSMax Winkler }
79*3f37397cSMax Winkler 
80*3f37397cSMax Winkler // Pass and return an object with an explicitly defaulted copy assignment operator that is implicitly deleted (pass directly, return indirectly).
81*3f37397cSMax Winkler // CHECK: define dso_local void @"?f6@@YA?AUS6@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S6) align 8 {{.*}})
82*3f37397cSMax Winkler // CHECK: call void @"?func6@@YA?AUS6@@U1@@Z"(ptr dead_on_unwind writable sret(%struct.S6) align 8 {{.*}}, i64 {{.*}})
83*3f37397cSMax Winkler struct S6 {
84*3f37397cSMax Winkler   S6& operator=(const S6&) = default;
85*3f37397cSMax Winkler   int& i;
86*3f37397cSMax Winkler };
87*3f37397cSMax Winkler 
88*3f37397cSMax Winkler S6 func6(S6 x);
f6()89*3f37397cSMax Winkler S6 f6() {
90*3f37397cSMax Winkler   S6 x{ global_i };
91*3f37397cSMax Winkler   return func6(x);
92*3f37397cSMax Winkler }
93