blob: 2b7b9e2a6effb9a39b25b2675302cd7448e6a677 [file] [log] [blame]
Erich Keane757d3172016-11-02 18:29:35 +00001// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN64 %s
2// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN32 %s
3// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -check-prefix=CHECK-WIN64 %s
4// RUN: %clang_cc1 -triple i386-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -check-prefix=CHECK-WIN32 %s
5
6int __regcall foo(int i);
7
8int main()
9{
10 int p = 0, _data;
11 auto lambda = [&](int parameter) -> int {
12 _data = foo(parameter);
13 return _data;
14 };
15 return lambda(p);
16}
17// CHECK-LIN: call x86_regcallcc {{.+}} @_Z15__regcall3__foo
18// CHECK-WIN64: call x86_regcallcc {{.+}} @"\01?foo@@YwHH@Z"
19// CHECK-WIN32: call x86_regcallcc {{.+}} @"\01?foo@@YwHH@Z"
20
21int __regcall foo (int i){
22 return i;
23}
24// CHECK-LIN: define x86_regcallcc {{.+}}@_Z15__regcall3__foo
25// CHECK-WIN64: define x86_regcallcc {{.+}}@"\01?foo@@YwHH@Z"
26// CHECK-WIN32: define x86_regcallcc {{.+}}@"\01?foo@@YwHH@Z"
27
28// used to give a body to test_class functions
29static int x = 0;
30class test_class {
31 int a;
32public:
33#ifndef WIN_TEST
34 __regcall
35#endif
36 test_class(){++x;}
37 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC1Ev
38 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC2Ev
39 // Windows ignores calling convention on constructor/destructors.
40 // CHECK-WIN64-DAG: define linkonce_odr %class.test_class* @"\01??0test_class@@QEAA@XZ"
41 // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc %class.test_class* @"\01??0test_class@@QAE@XZ"
42
43#ifndef WIN_TEST
44 __regcall
45#endif
46 ~test_class(){--x;}
47 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev
48 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev
49 // Windows ignores calling convention on constructor/destructors.
David Majnemerdc169752017-02-14 00:54:11 +000050 // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAAXXZ"
51 // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAEXXZ"
Erich Keane757d3172016-11-02 18:29:35 +000052
53 test_class& __regcall operator+=(const test_class&){
54 return *this;
55 }
56 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @_ZN10test_classpLERKS_
57 // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @"\01??Ytest_class@@QEAwAEAV0@AEBV0@@Z"
58 // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @"\01??Ytest_class@@QAwAAV0@ABV0@@Z"
59 void __regcall do_thing(){}
60 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__do_thingEv
61 // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01?do_thing@test_class@@QEAwXXZ"
62 // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01?do_thing@test_class@@QAwXXZ"
63
64 template<typename T>
65 void __regcall tempFunc(T i){}
66 // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__tempFuncIiEEvT_
67 // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
68 // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
69};
70
71bool __regcall operator ==(const test_class&, const test_class&){ --x; return false;}
72// CHECK-LIN-DAG: define x86_regcallcc zeroext i1 @_ZeqRK10test_classS1_
73// CHECK-WIN64-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NAEBVtest_class@@0@Z"
74// CHECK-WIN32-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NABVtest_class@@0@Z"
75
Erich Keanede1b2a92017-07-21 18:50:36 +000076test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};}
77// CHECK-LIN64-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* noalias sret %agg.result, i64)
Erich Keane757d3172016-11-02 18:29:35 +000078// CHECK-LIN32-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* inreg noalias sret %agg.result, i64)
79// CHECK-WIN64-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
80// CHECK-WIN32-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z"
81
82template<typename T>
83void __regcall freeTempFunc(T i){}
84// CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_Z24__regcall3__freeTempFuncIiEvT_
85// CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
86// CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z"
87
88// class to force generation of functions
89void force_gen() {
90 test_class t;
91 test_class t2 = 12_test_class;
92 t += t2;
93 auto t3 = 100_test_class;
94 t3.tempFunc(1);
95 freeTempFunc(1);
96 t3.do_thing();
97}
Erich Keanede1b2a92017-07-21 18:50:36 +000098
99long double _Complex __regcall foo(long double _Complex f) {
100 return f;
101}
102// CHECK-LIN64-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 16 %f)
103// CHECK-LIN32-DAG: define x86_regcallcc void @_Z15__regcall3__fooCe({ x86_fp80, x86_fp80 }* inreg noalias sret %agg.result, { x86_fp80, x86_fp80 }* byval align 4 %f)
104// CHECK-WIN64-DAG: define x86_regcallcc { double, double } @"\01?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)
105// CHECK-WIN32-DAG: define x86_regcallcc { double, double } @"\01?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double %f.0, double %f.1)