diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 7 |
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 |