]> granicus.if.org Git - clang/commitdiff
Implement -mrtd which sets the StdCall calling convention to be the default
authorRoman Divacky <rdivacky@freebsd.org>
Tue, 1 Mar 2011 17:40:53 +0000 (17:40 +0000)
committerRoman Divacky <rdivacky@freebsd.org>
Tue, 1 Mar 2011 17:40:53 +0000 (17:40 +0000)
one.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126756 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/LangOptions.h
include/clang/Driver/CC1Options.td
include/clang/Driver/Options.td
lib/AST/ASTContext.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/CodeGen/mrtd.c [new file with mode: 0644]

index e4205d70903e32189fa99c0eabeb3093bd81ae10..83a6746d9209147cdf9a5cae9199fe4506951d29 100644 (file)
@@ -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; }
index 7c103baf279a27df2e50036511a316d6673bc2d5..0696f7d08e2d8b87d2a5483afe6acd44a761a812 100644 (file)
@@ -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">,
index 1b9d279f577b84719d70048362511a78cd0a363f..f5e92022c37a61f57faf3bdb5cf21243684b9c24 100644 (file)
@@ -492,6 +492,7 @@ def mno_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>;
 def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>;
 def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>;
 def mno_relax_all : Flag<"-mno-relax-all">, Group<m_Group>;
+def mno_rtd: Flag<"-mno-rtd">, Group<m_Group>;
 def mno_soft_float : Flag<"-mno-soft-float">, Group<m_Group>;
 def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>;
 def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>;
@@ -514,6 +515,7 @@ def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
 def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
 def mregparm_EQ : Joined<"-mregparm=">, Group<m_Group>;
 def mrelax_all : Flag<"-mrelax-all">, Group<m_Group>;
+def mrtd: Flag<"-mrtd">, Group<m_Group>;
 def msoft_float : Flag<"-msoft-float">, Group<m_Group>;
 def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>;
 def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>;
index 7768630749561b089ed7744e2ee7088d28643d80..5335a8b0c88edf52f918abffba576223923ca7fc 100644 (file)
@@ -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);
index bbee2c7aa216ce8714fd9d90760d6aa6bf8a480c..2e11d30d04285501d1a301b65ef4b329731581a6 100644 (file)
@@ -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))
index 21d0cac28252b546e1d8161813e653717f91cb02..bf4d6cd86ad25a75b7c2f7bc1442b54509381b61 100644 (file)
@@ -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);
index bc213a55ee7848046a520dcc76fa6bf40de1e082..c0b7d7248870e1f1e054335d6ce8f17041eb5b58 100644 (file)
@@ -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);
index aea3e37659d491a83200bc6b0f79ced2e7017f4e..7e0af0963d1e42cc2143e252ee8ee990e780bb98 100644 (file)
@@ -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 (file)
index 0000000..9453b6c
--- /dev/null
@@ -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)