From cfe9af250f466e7e38becea4428990448ae07737 Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Tue, 1 Mar 2011 17:40:53 +0000 Subject: [PATCH] Implement -mrtd which sets the StdCall calling convention to be the default one. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126756 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/LangOptions.h | 3 +++ include/clang/Driver/CC1Options.td | 2 ++ include/clang/Driver/Options.td | 2 ++ lib/AST/ASTContext.cpp | 15 +++++++++++---- lib/Driver/Tools.cpp | 3 +++ lib/Frontend/CompilerInvocation.cpp | 1 + lib/Serialization/ASTReader.cpp | 1 + lib/Serialization/ASTWriter.cpp | 1 + test/CodeGen/mrtd.c | 15 +++++++++++++++ 9 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/mrtd.c diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index e4205d7090..83a6746d92 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -124,6 +124,8 @@ public: // FIXME: This is just a temporary option, for testing purposes. unsigned NoBitFieldTypeAlign : 1; + unsigned MRTD : 1; // -mrtd calling convention + private: // We declare multibit enums as unsigned because MSVC insists on making enums // signed. Set/Query these values using accessors. @@ -216,6 +218,7 @@ public: FastRelaxedMath = 0; DefaultFPContract = 0; NoBitFieldTypeAlign = 0; + MRTD = 0; } GCMode getGCMode() const { return (GCMode) GC; } diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 7c103baf27..0696f7d08e 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -157,6 +157,8 @@ def mregparm : Separate<"-mregparm">, HelpText<"Limit the number of registers available for integer arguments">; def mrelax_all : Flag<"-mrelax-all">, HelpText<"Relax all machine instructions">; +def mrtd: Flag<"-mrtd">, + HelpText<"Make StdCall calling convention the default">; def mrelocation_model : Separate<"-mrelocation-model">, HelpText<"The relocation model to use">; def munwind_tables : Flag<"-munwind-tables">, diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 1b9d279f57..f5e92022c3 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -492,6 +492,7 @@ def mno_mmx : Flag<"-mno-mmx">, Group; def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group; def mno_red_zone : Flag<"-mno-red-zone">, Group; def mno_relax_all : Flag<"-mno-relax-all">, Group; +def mno_rtd: Flag<"-mno-rtd">, Group; def mno_soft_float : Flag<"-mno-soft-float">, Group; def mno_sse2 : Flag<"-mno-sse2">, Group; def mno_sse3 : Flag<"-mno-sse3">, Group; @@ -514,6 +515,7 @@ def mpascal_strings : Flag<"-mpascal-strings">, Group; def mred_zone : Flag<"-mred-zone">, Group; def mregparm_EQ : Joined<"-mregparm=">, Group; def mrelax_all : Flag<"-mrelax-all">, Group; +def mrtd: Flag<"-mrtd">, Group; def msoft_float : Flag<"-msoft-float">, Group; def msse2 : Flag<"-msse2">, Group; def msse3 : Flag<"-msse3">, Group; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 7768630749..5335a8b0c8 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1862,7 +1862,9 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType, QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const { - const CallingConv CallConv = Info.getCC(); + const CallingConv DefaultCC = Info.getCC(); + const CallingConv CallConv = (LangOpts.MRTD && DefaultCC == CC_Default) ? + CC_X86StdCall : DefaultCC; // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; @@ -1886,8 +1888,9 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy, assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; } + FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv); FunctionNoProtoType *New = new (*this, TypeAlignment) - FunctionNoProtoType(ResultTy, Canonical, Info); + FunctionNoProtoType(ResultTy, Canonical, newInfo); Types.push_back(New); FunctionNoProtoTypes.InsertNode(New, InsertPos); return QualType(New, 0); @@ -1915,7 +1918,9 @@ ASTContext::getFunctionType(QualType ResultTy, if (!ArgArray[i].isCanonicalAsParam()) isCanonical = false; - const CallingConv CallConv = EPI.ExtInfo.getCC(); + const CallingConv DefaultCC = EPI.ExtInfo.getCC(); + const CallingConv CallConv = (LangOpts.MRTD && DefaultCC == CC_Default) ? + CC_X86StdCall : DefaultCC; // If this type isn't canonical, get the canonical version of it. // The exception spec is not part of the canonical type. @@ -1952,7 +1957,9 @@ ASTContext::getFunctionType(QualType ResultTy, NumArgs * sizeof(QualType) + EPI.NumExceptions * sizeof(QualType); FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment); - new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, Canonical, EPI); + FunctionProtoType::ExtProtoInfo newEPI = EPI; + newEPI.ExtInfo = EPI.ExtInfo.withCallingConv(CallConv); + new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, Canonical, newEPI); Types.push_back(FTP); FunctionProtoTypes.InsertNode(FTP, InsertPos); return QualType(FTP, 0); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index bbee2c7aa2..2e11d30d04 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1081,6 +1081,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(Args)); } + if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false)) + CmdArgs.push_back("-mrtd"); + // FIXME: Set --enable-unsafe-fp-math. if (Args.hasFlag(options::OPT_fno_omit_frame_pointer, options::OPT_fomit_frame_pointer)) diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 21d0cac282..bf4d6cd86a 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1475,6 +1475,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.SinglePrecisionConstants = Args.hasArg(OPT_cl_single_precision_constant); Opts.FastRelaxedMath = Args.hasArg(OPT_cl_fast_relaxed_math); Opts.OptimizeSize = 0; + Opts.MRTD = Args.hasArg(OPT_mrtd); // FIXME: Eliminate this dependency. unsigned Opt = getOptimizationLevel(Args, IK, Diags); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index bc213a55ee..c0b7d72488 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2839,6 +2839,7 @@ bool ASTReader::ParseLanguageOptions( PARSE_LANGOPT(DefaultFPContract); PARSE_LANGOPT(ElideConstructors); PARSE_LANGOPT(SpellChecking); + PARSE_LANGOPT(MRTD); #undef PARSE_LANGOPT return Listener->ReadLanguageOptions(LangOpts); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index aea3e37659..7e0af0963d 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1072,6 +1072,7 @@ void ASTWriter::WriteLanguageOptions(const LangOptions &LangOpts) { Record.push_back(LangOpts.DefaultFPContract); Record.push_back(LangOpts.ElideConstructors); Record.push_back(LangOpts.SpellChecking); + Record.push_back(LangOpts.MRTD); Stream.EmitRecord(LANGUAGE_OPTIONS, Record); } diff --git a/test/CodeGen/mrtd.c b/test/CodeGen/mrtd.c new file mode 100644 index 0000000000..9453b6cd68 --- /dev/null +++ b/test/CodeGen/mrtd.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -mrtd -triple i386-unknown-freebsd9.0 -emit-llvm -o - %s | FileCheck %s + +void baz(int arg); + +// CHECK: define x86_stdcallcc void @foo(i32 %arg) nounwind +void foo(int arg) { +// CHECK: %call = call x86_stdcallcc i32 (...)* @bar(i32 %tmp) + bar(arg); +// CHECK: call x86_stdcallcc void @baz(i32 %tmp1) + baz(arg); +} + +// CHECK: declare x86_stdcallcc i32 @bar(...) + +// CHECK: declare x86_stdcallcc void @baz(i32) -- 2.40.0