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