summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp5
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp7
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp7
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
4 files changed, 22 insertions, 4 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 87d096dab00..8247d1a23ef 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -9281,6 +9281,11 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
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);
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c1c8813cc42..6ba5d048a48 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4972,7 +4972,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
// 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;
@@ -4993,6 +4994,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
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.
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2c0d99b4bef..692b20bd3ad 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2310,12 +2310,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// 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)
@@ -2326,7 +2326,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
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)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0c00ef7e26c..ab1a66ad8fb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9673,6 +9673,13 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
assert(T->isFunctionType() && "function decl is not of function type");
const FunctionType* FT = T->castAs<FunctionType>();
+ // Set default calling convention for main()
+ if (FT->getCallConv() != CC_C) {
+ FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(CC_C));
+ FD->setType(QualType(FT, 0));
+ T = Context.getCanonicalType(FD->getType());
+ }
+
if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
// In C with GNU extensions we allow main() to have non-integer return
// type, but we should warn about the extension, and we disable the
OpenPOWER on IntegriCloud