diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2205,6 +2205,8 @@ HelpText<"Dot-separated value representing the Microsoft compiler " "version number to report in _MSC_VER (0 = don't define it " "(default))">; +def fms_runtime_lib_EQ : Joined<["-"], "fms-runtime-lib=">, Group, + Flags<[NoXarchOption, CoreOption]>, HelpText<"Select Windows run-time library">; defm delayed_template_parsing : BoolFOption<"delayed-template-parsing", LangOpts<"DelayedTemplateParsing">, DefaultFalse, PosFlag, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6477,6 +6477,35 @@ if (IsMSVCCompat) CmdArgs.push_back("-fms-compatibility"); + // Process Windows runtime flags (equivalent to cl flags /MD, /MDd, /MT, /MTd) + if (Triple.isOSWindows()) { + if (Arg *A = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { + StringRef Val = A->getValue(); + if (Val == "dll") { + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("-D_DLL"); + CmdArgs.push_back("--dependent-lib=msvcrt"); + } else if (Val == "dll_dbg") { + CmdArgs.push_back("-D_DEBUG"); + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("-D_DLL"); + CmdArgs.push_back("--dependent-lib=msvcrtd"); + } else if (Val == "static") { + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("-flto-visibility-public-std"); + CmdArgs.push_back("--dependent-lib=libcmt"); + } else if (Val == "static_dbg") { + CmdArgs.push_back("-D_DEBUG"); + CmdArgs.push_back("-D_MT"); + CmdArgs.push_back("-flto-visibility-public-std"); + CmdArgs.push_back("--dependent-lib=libcmtd"); + } else { + D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << Val; + } + CmdArgs.push_back("--dependent-lib=oldnames"); + } + } + // Handle -fgcc-version, if present. VersionTuple GNUCVer; if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) { diff --git a/clang/test/Driver/cl-runtime-flags.c b/clang/test/Driver/cl-runtime-flags.c --- a/clang/test/Driver/cl-runtime-flags.c +++ b/clang/test/Driver/cl-runtime-flags.c @@ -95,3 +95,39 @@ // CHECK-MTZl-SAME: "-D_VC_NODEFAULTLIB" // CHECK-MTZl-NOT: "--dependent-lib=libcmt" // CHECK-MTZl-NOT: "--dependent-lib=oldnames" + +// Check for clang versions of the /MD and /MT flags. + +// RUN: %clang -### --target=x86_64-windows-msvc -fms-runtime-lib=static -- %s \ +// RUN: 2>&1 | FileCheck -check-prefix=CHECK-CLANG-STATIC %s +// CHECK-CLANG-STATIC-NOT: "-D_DEBUG" +// CHECK-CLANG-STATIC: "-D_MT" +// CHECK-CLANG-STATIC-NOT: "-D_DLL" +// CHECK-CLANG-STATIC: "-flto-visibility-public-std" +// CHECK-CLANG-STATIC: "--dependent-lib=libcmt" +// CHECK-CLANG-STATIC: "--dependent-lib=oldnames" + +// RUN: %clang -### --target=x86_64-windows-msvc -fms-runtime-lib=static_dbg \ +// RUN: -- %s 2>&1 | FileCheck -check-prefix=CHECK-CLANG-STATIC-DBG %s +// CHECK-CLANG-STATIC-DBG: "-D_DEBUG" +// CHECK-CLANG-STATIC-DBG: "-D_MT" +// CHECK-CLANG-STATIC-DBG-NOT: "-D_DLL" +// CHECK-CLANG-STATIC-DBG: "-flto-visibility-public-std" +// CHECK-CLANG-STATIC-DBG: "--dependent-lib=libcmtd" +// CHECK-CLANG-STATIC-DBG: "--dependent-lib=oldnames" + +// RUN: %clang -### --target=x86_64-windows-msvc -fms-runtime-lib=dll -- %s \ +// RUN: 2>&1 | FileCheck -check-prefix=CHECK-CLANG-DLL %s +// CHECK-CLANG-DLL-NOT: "-D_DEBUG" +// CHECK-CLANG-DLL: "-D_MT" +// CHECK-CLANG-DLL: "-D_DLL" +// CHECK-CLANG-DLL: "--dependent-lib=msvcrt" +// CHECK-CLANG-DLL: "--dependent-lib=oldnames" + +// RUN: %clang -### --target=x86_64-windows-msvc -fms-runtime-lib=dll_dbg -- \ +// RUN: %s 2>&1 | FileCheck -check-prefix=CHECK-CLANG-DLL-DBG %s +// CHECK-CLANG-DLL-DBG: "-D_DEBUG" +// CHECK-CLANG-DLL-DBG: "-D_MT" +// CHECK-CLANG-DLL-DBG: "-D_DLL" +// CHECK-CLANG-DLL-DBG: "--dependent-lib=msvcrtd" +// CHECK-CLANG-DLL-DBG: "--dependent-lib=oldnames"