Hi rnk,

These options set some preprocessor defines and injects library names into the 
object files. This is based on the approach from Reid's original patch.

Please take a look!

http://llvm-reviews.chandlerc.com/D1315

Files:
  include/clang/Driver/CLCompatOptions.td
  lib/Driver/Tools.cpp
  lib/Driver/Tools.h
  lib/Headers/msvcrt_picker.h
  test/Driver/cl-runtime-flags.c
Index: include/clang/Driver/CLCompatOptions.td
===================================================================
--- include/clang/Driver/CLCompatOptions.td
+++ include/clang/Driver/CLCompatOptions.td
@@ -86,6 +86,15 @@
 def _SLASH_Fo : CLJoined<"Fo">,
   HelpText<"Set output object file, or directory (ends in / or \\)">,
   MetaVarName<"<file or directory>">;
+def _SLASH_MD : CLFlag<"MD">,
+  HelpText<"Use multi-threaded DLL-specific run-time">;
+def _SLASH_MDd : CLFlag<"MDd">,
+  HelpText<"Use multi-threaded DLL-specific debug run-time">;
+def _SLASH_ML : CLFlag<"ML">,
+  HelpText<"Use single-threaded run-time (default)">;
+def _SLASH_MLd : CLFlag<"MLd">, HelpText<"Use single-threaded debug run-time">;
+def _SLASH_MT : CLFlag<"MT">, HelpText<"Use multi-threaded run-time">;
+def _SLASH_MTd : CLFlag<"MTd">, HelpText<"Use multi-threaded debug run-time">;
 def _SLASH_Tc : CLJoinedOrSeparate<"Tc">, HelpText<"Specify a C source file">,
   MetaVarName<"<filename>">;
 def _SLASH_TC : CLFlag<"TC">, HelpText<"Treat all source files as C">;
@@ -119,10 +128,6 @@
 def _SLASH_Gy : CLFlag<"Gy">;
 def _SLASH_Gy_ : CLFlag<"Gy-">;
 def _SLASH_GZ : CLFlag<"GZ">;
-def _SLASH_MD : CLFlag<"MD">;
-def _SLASH_MT : CLFlag<"MT">;
-def _SLASH_MDd : CLFlag<"MDd">;
-def _SLASH_MTd : CLFlag<"MTd">;
 def _SLASH_Oi : CLFlag<"Oi">;
 def _SLASH_RTC : CLJoined<"RTC">;
 def _SLASH_showIncludes : CLJoined<"showIncludes">;
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -2510,6 +2510,10 @@
     break;
   }
 
+  // Add clang-cl arguments.
+  if (getToolChain().getDriver().IsCLMode())
+    AddClangCLArgs(Args, CmdArgs);
+
   // Pass the linker version in use.
   if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
     CmdArgs.push_back("-target-linker-version");
@@ -3797,6 +3801,49 @@
   return runtime;
 }
 
+void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
+  unsigned RTOptionID = options::OPT__SLASH_ML;
+
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD,
+                               options::OPT__SLASH_MDd,
+                               options::OPT__SLASH_ML,
+                               options::OPT__SLASH_MLd,
+                               options::OPT__SLASH_MT,
+                               options::OPT__SLASH_MTd)) {
+    RTOptionID = A->getOption().getID();
+  }
+
+  switch(RTOptionID) {
+    case options::OPT__SLASH_MD:
+      CmdArgs.push_back("-D_MT");
+      CmdArgs.push_back("-D_DLL");
+      break;
+    case options::OPT__SLASH_MDd:
+      CmdArgs.push_back("-D_DEBUG");
+      CmdArgs.push_back("-D_MT");
+      CmdArgs.push_back("-D_DLL");
+      break;
+    case options::OPT__SLASH_ML:
+      break;
+    case options::OPT__SLASH_MLd:
+      CmdArgs.push_back("-D_DEBUG");
+      break;
+    case options::OPT__SLASH_MT:
+      CmdArgs.push_back("-D_MT");
+      break;
+    case options::OPT__SLASH_MTd:
+      CmdArgs.push_back("-D_DEBUG");
+      CmdArgs.push_back("-D_MT");
+      break;
+    default:
+      llvm_unreachable("Unexpected option ID.");
+  }
+
+  CmdArgs.push_back("-include");
+  CmdArgs.push_back(Args.MakeArgString(
+        getToolChain().GetFilePath("include/msvcrt_picker.h")));
+}
+
 void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
                            const InputInfo &Output,
                            const InputInfoList &Inputs,
Index: lib/Driver/Tools.h
===================================================================
--- lib/Driver/Tools.h
+++ lib/Driver/Tools.h
@@ -74,6 +74,9 @@
                                    llvm::opt::ArgStringList &cmdArgs,
                                    RewriteKind rewrite) const;
 
+    void AddClangCLArgs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const;
+
   public:
     Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {}
 
Index: lib/Headers/msvcrt_picker.h
===================================================================
--- /dev/null
+++ lib/Headers/msvcrt_picker.h
@@ -0,0 +1,55 @@
+/*===---- msvcrt_picker.h - C runtime picker -------------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __MSVCRT_PICKER_H
+#define __MSVCRT_PICKER_H
+
+#ifdef _MT
+# ifdef _DLL
+#  ifdef _DEBUG
+#   pragma comment(lib, "msvcrtd")
+#  else
+#   pragma comment(lib, "msvcrt")
+#  endif
+# else
+#  ifdef _DEBUG
+#   pragma comment(lib, "libcmtd")
+#  else
+#   pragma comment(lib, "libcmt")
+#  endif
+# endif
+#else
+# ifdef _DEBUG
+#  pragma comment(lib, "libcd")
+# else
+#  pragma comment(lib, "libc")
+# endif
+#endif
+
+/* This provides POSIX compatibility (maps 'open' to '_open'), which most users
+ * want.  MSVC has a switch to turn off this autolinking, but it's not
+ * implemented in clang yet.
+ */
+#pragma comment(lib, "oldnames")
+
+#endif /* __MSVCRT_PICKER_H */
Index: test/Driver/cl-runtime-flags.c
===================================================================
--- /dev/null
+++ test/Driver/cl-runtime-flags.c
@@ -0,0 +1,68 @@
+// Don't attempt slash switches on msys bash.
+// REQUIRES: shell-preserves-root
+
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+// First check that regular clang doesn't do any of this stuff.
+// RUN: %clang -### %s 2>&1 | FileCheck -check-prefix=CHECK-CLANG %s
+// CHECK-CLANG-NOT: "-D_DEBUG"
+// CHECK-CLANG-NOT: "-D_MT"
+// CHECK-CLANG-NOT: "-D_DLL"
+// CHECK-CLANG-NOT: msvcrt_picker.h
+
+
+// RUN: %clang_cl -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-DEFAULT %s
+// RUN: %clang_cl -### /ML -- %s 2>&1 | FileCheck -check-prefix=CHECK-DEFAULT %s
+// CHECK-DEFAULT-NOT: "-D_DEBUG"
+// CHECK-DEFAULT-NOT: "-D_MT"
+// CHECK-DEFAULT-NOT: "-D_DLL"
+// RUN: %clang_cl /P -- %s 2>&1 | FileCheck -check-prefix=CHECK-DEFAULT-LIB %s
+// CHECK-DEFAULT-LIB: #pragma comment(lib, "libc")
+// CHECK-DEFAULT-LIB: #pragma comment(lib, "oldnames")
+// CHECK-DEFAULT-LIB-NOT: #pragma comment
+
+// RUN: %clang_cl -### /MLd -- %s 2>&1 | FileCheck -check-prefix=CHECK-MLd %s
+// CHECK-MLd: "-D_DEBUG"
+// CHECK-MLd-NOT: "-D_MT"
+// CHECK-MLd-NOT: "-D_DLL"
+// RUN: %clang_cl /P /MLd -- %s 2>&1 | FileCheck -check-prefix=CHECK-MLd-LIB %s
+// CHECK-MLd-LIB: #pragma comment(lib, "libcd")
+// CHECK-MLd-LIB: #pragma comment(lib, "oldnames")
+// CHECK-MLd-LIB-NOT: #pragma comment
+
+// RUN: %clang_cl -### /MT -- %s 2>&1 | FileCheck -check-prefix=CHECK-MT %s
+// CHECK-MT-NOT: "-D_DEBUG"
+// CHECK-MT: "-D_MT"
+// CHECK-MT-NOT: "-D_DLL"
+// RUN: %clang_cl /P /MT -- %s 2>&1 | FileCheck -check-prefix=CHECK-MT-LIB %s
+// CHECK-MT-LIB: #pragma comment(lib, "libcmt")
+// CHECK-MT-LIB: #pragma comment(lib, "oldnames")
+// CHECK-MT-LIB-NOT: #pragma comment
+
+// RUN: %clang_cl -### /MTd -- %s 2>&1 | FileCheck -check-prefix=CHECK-MTd %s
+// CHECK-MTd: "-D_DEBUG"
+// CHECK-MTd: "-D_MT"
+// CHECK-MTd-NOT: "-D_DLL"
+// RUN: %clang_cl /P /MTd -- %s 2>&1 | FileCheck -check-prefix=CHECK-MTd-LIB %s
+// CHECK-MTd-LIB: #pragma comment(lib, "libcmtd")
+// CHECK-MTd-LIB: #pragma comment(lib, "oldnames")
+// CHECK-MTd-LIB-NOT: #pragma comment
+
+// RUN: %clang_cl -### /MD -- %s 2>&1 | FileCheck -check-prefix=CHECK-MD %s
+// CHECK-MD-NOT: "-D_DEBUG"
+// CHECK-MD: "-D_MT"
+// CHECK-MD: "-D_DLL"
+// RUN: %clang_cl /P /MD -- %s 2>&1 | FileCheck -check-prefix=CHECK-MD-LIB %s
+// CHECK-MD-LIB: #pragma comment(lib, "msvcrt")
+// CHECK-MD-LIB: #pragma comment(lib, "oldnames")
+// CHECK-MD-LIB-NOT: #pragma comment
+
+// RUN: %clang_cl -### /MDd -- %s 2>&1 | FileCheck -check-prefix=CHECK-MDd %s
+// CHECK-MDd: "-D_DEBUG"
+// CHECK-MDd: "-D_MT"
+// CHECK-MDd: "-D_DLL"
+// RUN: %clang_cl /P /MDd -- %s 2>&1 | FileCheck -check-prefix=CHECK-MDd-LIB %s
+// CHECK-MDd-LIB: #pragma comment(lib, "msvcrtd")
+// CHECK-MDd-LIB: #pragma comment(lib, "oldnames")
+// CHECK-MDd-LIB-NOT: #pragma comment
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to