clang-cl: Support the run-time selection options (/MD, /MT et al.)
These flags set some preprocessor macros and injects a dependency
on the runtime library into the object file, which later is picked up
by the linker.
This also adds a new CC1 flag for adding a dependent library.
Differential Revision: http://llvm-reviews.chandlerc.com/D1315
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187945 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 7e0e3aa..c6d4033 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -60,6 +60,9 @@
TD.reset(new llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription()));
Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD,
Diags));
+
+ for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i)
+ HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);
}
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 4a3ce42..e4acadb 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -2516,6 +2516,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");
@@ -3803,6 +3807,47 @@
return runtime;
}
+void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
+ unsigned RTOptionID = options::OPT__SLASH_MT;
+
+ if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD,
+ options::OPT__SLASH_MDd,
+ 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");
+ CmdArgs.push_back("--dependent-lib=msvcrt");
+ break;
+ case options::OPT__SLASH_MDd:
+ CmdArgs.push_back("-D_DEBUG");
+ CmdArgs.push_back("-D_MT");
+ CmdArgs.push_back("-D_DLL");
+ CmdArgs.push_back("--dependent-lib=msvcrtd");
+ break;
+ case options::OPT__SLASH_MT:
+ CmdArgs.push_back("-D_MT");
+ CmdArgs.push_back("--dependent-lib=libcmt");
+ break;
+ case options::OPT__SLASH_MTd:
+ CmdArgs.push_back("-D_DEBUG");
+ CmdArgs.push_back("-D_MT");
+ CmdArgs.push_back("--dependent-lib=libcmtd");
+ break;
+ default:
+ llvm_unreachable("Unexpected option ID.");
+ }
+
+ // 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.
+ CmdArgs.push_back("--dependent-lib=oldnames");
+}
+
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index 9138ddf..8c1e695 100644
--- a/lib/Driver/Tools.h
+++ b/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) {}
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 27ddd84..a4c93fa 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -502,6 +502,8 @@
}
}
+ Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib);
+
return Success;
}