Erich Keane | 757d317 | 2016-11-02 18:29:35 +0000 | [diff] [blame] | 1 | // 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 | |
| 6 | int __regcall foo(int i); |
| 7 | |
| 8 | int 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 | |
| 21 | int __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 |
| 29 | static int x = 0; |
| 30 | class test_class { |
| 31 | int a; |
| 32 | public: |
| 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 Majnemer | dc16975 | 2017-02-14 00:54:11 +0000 | [diff] [blame] | 50 | // 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 Keane | 757d317 | 2016-11-02 18:29:35 +0000 | [diff] [blame] | 52 | |
| 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 | |
| 71 | bool __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 Keane | de1b2a9 | 2017-07-21 18:50:36 +0000 | [diff] [blame] | 76 | test_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 Keane | 757d317 | 2016-11-02 18:29:35 +0000 | [diff] [blame] | 78 | // 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 | |
| 82 | template<typename T> |
| 83 | void __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 |
| 89 | void 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 Keane | de1b2a9 | 2017-07-21 18:50:36 +0000 | [diff] [blame] | 98 | |
| 99 | long 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) |