diff options
Diffstat (limited to 'test/CodeGenCXX/regcall.cpp')
| -rw-r--r-- | test/CodeGenCXX/regcall.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/test/CodeGenCXX/regcall.cpp b/test/CodeGenCXX/regcall.cpp new file mode 100644 index 000000000000..0cc6ad009324 --- /dev/null +++ b/test/CodeGenCXX/regcall.cpp @@ -0,0 +1,97 @@ +// 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 +// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -std=c++11 %s -o - | FileCheck -check-prefix=CHECK-LIN -check-prefix=CHECK-LIN32 %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -check-prefix=CHECK-WIN64 %s +// RUN: %clang_cc1 -triple i386-windows-msvc -emit-llvm -std=c++11 %s -o - -DWIN_TEST | FileCheck -check-prefix=CHECK-WIN32 %s + +int __regcall foo(int i); + +int main() +{ + int p = 0, _data; + auto lambda = [&](int parameter) -> int { + _data = foo(parameter); + return _data; + }; + return lambda(p); +} +// CHECK-LIN: call x86_regcallcc {{.+}} @_Z15__regcall3__foo +// CHECK-WIN64: call x86_regcallcc {{.+}} @"\01?foo@@YwHH@Z" +// CHECK-WIN32: call x86_regcallcc {{.+}} @"\01?foo@@YwHH@Z" + +int __regcall foo (int i){ + return i; +} +// CHECK-LIN: define x86_regcallcc {{.+}}@_Z15__regcall3__foo +// CHECK-WIN64: define x86_regcallcc {{.+}}@"\01?foo@@YwHH@Z" +// CHECK-WIN32: define x86_regcallcc {{.+}}@"\01?foo@@YwHH@Z" + +// used to give a body to test_class functions +static int x = 0; +class test_class { + int a; +public: +#ifndef WIN_TEST + __regcall +#endif + test_class(){++x;} + // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC1Ev + // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classC2Ev + // Windows ignores calling convention on constructor/destructors. + // CHECK-WIN64-DAG: define linkonce_odr %class.test_class* @"\01??0test_class@@QEAA@XZ" + // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc %class.test_class* @"\01??0test_class@@QAE@XZ" + +#ifndef WIN_TEST + __regcall +#endif + ~test_class(){--x;} + // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev + // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev + // Windows ignores calling convention on constructor/destructors. + // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAA@XZ" + // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAE@XZ" + + test_class& __regcall operator+=(const test_class&){ + return *this; + } + // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @_ZN10test_classpLERKS_ + // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @"\01??Ytest_class@@QEAwAEAV0@AEBV0@@Z" + // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc dereferenceable(4) %class.test_class* @"\01??Ytest_class@@QAwAAV0@ABV0@@Z" + void __regcall do_thing(){} + // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__do_thingEv + // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01?do_thing@test_class@@QEAwXXZ" + // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01?do_thing@test_class@@QAwXXZ" + + template<typename T> + void __regcall tempFunc(T i){} + // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_class20__regcall3__tempFuncIiEEvT_ + // CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z" + // CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z" +}; + +bool __regcall operator ==(const test_class&, const test_class&){ --x; return false;} +// CHECK-LIN-DAG: define x86_regcallcc zeroext i1 @_ZeqRK10test_classS1_ +// CHECK-WIN64-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NAEBVtest_class@@0@Z" +// CHECK-WIN32-DAG: define x86_regcallcc zeroext i1 @"\01??8@Yw_NABVtest_class@@0@Z" + +test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};} +// CHECK-LIN64-DAG: define x86_regcallcc %class.test_class @_Zli11_test_classy(i64) +// CHECK-LIN32-DAG: define x86_regcallcc void @_Zli11_test_classy(%class.test_class* inreg noalias sret %agg.result, i64) +// CHECK-WIN64-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z" +// CHECK-WIN32-DAG: \01??__K_test_class@@Yw?AVtest_class@@_K@Z" + +template<typename T> +void __regcall freeTempFunc(T i){} +// CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_Z24__regcall3__freeTempFuncIiEvT_ +// CHECK-WIN64-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z" +// CHECK-WIN32-DAG: define linkonce_odr x86_regcallcc void @"\01??$freeTempFunc@H@@YwXH@Z" + +// class to force generation of functions +void force_gen() { + test_class t; + test_class t2 = 12_test_class; + t += t2; + auto t3 = 100_test_class; + t3.tempFunc(1); + freeTempFunc(1); + t3.do_thing(); +} |
