eandrews created this revision.
Added support for regcall as default calling convention. Also added code to
exclude main when applying default calling conventions.
https://reviews.llvm.org/D39210
Files:
include/clang/AST/ASTContext.h
include/clang/Basic/LangOptions.h
include/clang/Driver/CC1Options.td
include/clang/Driver/CLCompatOptions.td
lib/AST/ASTContext.cpp
lib/Driver/ToolChains/Clang.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Sema/SemaType.cpp
test/CodeGenCXX/default_calling_conv.cpp
test/Driver/cl-cc-flags.c
Index: test/Driver/cl-cc-flags.c
===================================================================
--- test/Driver/cl-cc-flags.c
+++ test/Driver/cl-cc-flags.c
@@ -13,6 +13,9 @@
// RUN: %clang_cl --target=i686-windows-msvc /Gv -### -- %s 2>&1 | FileCheck --check-prefix=VECTORCALL %s
// VECTORCALL: -fdefault-calling-conv=vectorcall
+// RUN: %clang_cl --target=i686-windows-msvc /Gregcall -### -- %s 2>&1 | FileCheck --check-prefix=REGCALL %s
+// REGCALL: -fdefault-calling-conv=regcall
+
// Last one should win:
// RUN: %clang_cl --target=i686-windows-msvc /Gd /Gv -### -- %s 2>&1 | FileCheck --check-prefix=LASTWINS_VECTOR %s
Index: test/CodeGenCXX/default_calling_conv.cpp
===================================================================
--- test/CodeGenCXX/default_calling_conv.cpp
+++ test/CodeGenCXX/default_calling_conv.cpp
@@ -3,11 +3,13 @@
// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
// RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL
// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL
+// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL
// CDECL: define void @_Z5test1v
// FASTCALL: define x86_fastcallcc void @_Z5test1v
// STDCALL: define x86_stdcallcc void @_Z5test1v
// VECTORCALL: define x86_vectorcallcc void @_Z5test1v
+// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v
void test1() {}
// ALL: define void @_Z5test2v
@@ -22,6 +24,9 @@
// ALL: define x86_vectorcallcc void @_Z5test5v
void __attribute__((vectorcall)) test5() {}
+// ALL: define x86_regcallcc void @_Z17__regcall3__test6v
+void __attribute__((regcall)) test6() {}
+
// ALL: define linkonce_odr void @_ZN1A11test_memberEv
class A {
public:
@@ -32,3 +37,8 @@
A a;
a.test_member();
}
+
+// ALL: define i32 @main
+int main() {
+ return 1;
+}
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -3266,8 +3266,14 @@
}
}
- CallingConv CC = S.Context.getDefaultCallingConvention(FTI.isVariadic,
- IsCXXInstanceMethod);
+ bool IsMain = false;
+ if (D.getIdentifier() && D.getIdentifier()->isStr("main") &&
+ S.CurContext->getRedeclContext()->isTranslationUnit() &&
+ !S.getLangOpts().Freestanding)
+ IsMain = true;
+
+ CallingConv CC = S.Context.getDefaultCallingConvention(
+ FTI.isVariadic, IsCXXInstanceMethod, IsMain);
// Attribute AT_OpenCLKernel affects the calling convention for SPIR
// and AMDGPU targets, hence it cannot be treated as a calling
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2299,12 +2299,12 @@
// Check for MS default calling conventions being specified.
if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
LangOptions::DefaultCallingConvention DefaultCC =
- llvm::StringSwitch<LangOptions::DefaultCallingConvention>(
- A->getValue())
+ llvm::StringSwitch<LangOptions::DefaultCallingConvention>(A->getValue())
.Case("cdecl", LangOptions::DCC_CDecl)
.Case("fastcall", LangOptions::DCC_FastCall)
.Case("stdcall", LangOptions::DCC_StdCall)
.Case("vectorcall", LangOptions::DCC_VectorCall)
+ .Case("regcall", LangOptions::DCC_RegCall)
.Default(LangOptions::DCC_None);
if (DefaultCC == LangOptions::DCC_None)
Diags.Report(diag::err_drv_invalid_value)
@@ -2315,7 +2315,8 @@
bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
DefaultCC == LangOptions::DCC_StdCall) &&
Arch != llvm::Triple::x86;
- emitError |= DefaultCC == LangOptions::DCC_VectorCall &&
+ emitError |= (DefaultCC == LangOptions::DCC_VectorCall ||
+ DefaultCC == LangOptions::DCC_RegCall) &&
!(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64);
if (emitError)
Diags.Report(diag::err_drv_argument_not_allowed_with)
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -4958,7 +4958,8 @@
// Parse the default calling convention options.
if (Arg *CCArg =
Args.getLastArg(options::OPT__SLASH_Gd, options::OPT__SLASH_Gr,
- options::OPT__SLASH_Gz, options::OPT__SLASH_Gv)) {
+ options::OPT__SLASH_Gz, options::OPT__SLASH_Gv,
+ options::OPT__SLASH_Gregcall)) {
unsigned DCCOptId = CCArg->getOption().getID();
const char *DCCFlag = nullptr;
bool ArchSupported = true;
@@ -4979,6 +4980,10 @@
ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64;
DCCFlag = "-fdefault-calling-conv=vectorcall";
break;
+ case options::OPT__SLASH_Gregcall:
+ ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64;
+ DCCFlag = "-fdefault-calling-conv=regcall";
+ break;
}
// MSVC doesn't warn if /Gr or /Gz is used on x64, so we don't either.
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -9257,11 +9257,15 @@
}
CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
- bool IsCXXMethod) const {
+ bool IsCXXMethod,
+ bool IsMain) const {
// Pass through to the C++ ABI object
if (IsCXXMethod)
return ABI->getDefaultMethodCallConv(IsVariadic);
+ if (IsMain)
+ return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown);
+
switch (LangOpts.getDefaultCallingConv()) {
case LangOptions::DCC_None:
break;
@@ -9280,6 +9284,11 @@
if (!IsVariadic)
return CC_X86VectorCall;
break;
+ case LangOptions::DCC_RegCall:
+ // __regcall cannot be applied to variadic functions.
+ if (!IsVariadic)
+ return CC_X86RegCall;
+ break;
}
return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown);
}
Index: include/clang/Driver/CLCompatOptions.td
===================================================================
--- include/clang/Driver/CLCompatOptions.td
+++ include/clang/Driver/CLCompatOptions.td
@@ -302,6 +302,8 @@
HelpText<"Set __stdcall as a default calling convention">;
def _SLASH_Gv : CLFlag<"Gv">,
HelpText<"Set __vectorcall as a default calling convention">;
+def _SLASH_Gregcall : CLFlag<"Gregcall">,
+ HelpText<"Set __regcall as a default calling convention">;
// Ignored:
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -704,7 +704,7 @@
def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
HelpText<"Allow function arguments and returns of type half">;
def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
- HelpText<"Set default MS calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall">;
+ HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">;
def finclude_default_header : Flag<["-"], "finclude-default-header">,
HelpText<"Include the default header file for OpenCL">;
def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">,
Index: include/clang/Basic/LangOptions.h
===================================================================
--- include/clang/Basic/LangOptions.h
+++ include/clang/Basic/LangOptions.h
@@ -77,7 +77,8 @@
DCC_CDecl,
DCC_FastCall,
DCC_StdCall,
- DCC_VectorCall
+ DCC_VectorCall,
+ DCC_RegCall
};
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -2229,8 +2229,8 @@
getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
/// \brief Retrieves the default calling convention for the current target.
- CallingConv getDefaultCallingConvention(bool isVariadic,
- bool IsCXXMethod) const;
+ CallingConv getDefaultCallingConvention(bool isVariadic, bool IsCXXMethod,
+ bool IsMain = false) const;
/// \brief Retrieves the "canonical" template name that refers to a
/// given template.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits