diff options
author | Hans Wennborg <hans@hanshq.net> | 2013-08-08 00:17:41 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2013-08-08 00:17:41 +0000 |
commit | 75958c41e220358b66a12c257f3f87abe4b372d5 (patch) | |
tree | 7fb948b065b519816df001efa9bf4691ffb0ea0c | |
parent | a5689e69afbd1b43c35958be453192a48c507d37 (diff) | |
download | bcm5719-llvm-75958c41e220358b66a12c257f3f87abe4b372d5.tar.gz bcm5719-llvm-75958c41e220358b66a12c257f3f87abe4b372d5.zip |
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
llvm-svn: 187945
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Driver/CLCompatOptions.td | 10 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CodeGenOptions.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/ModuleBuilder.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 45 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.h | 3 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | clang/test/CodeGen/dependent-lib.c | 15 | ||||
-rw-r--r-- | clang/test/Driver/cl-options.c | 2 | ||||
-rw-r--r-- | clang/test/Driver/cl-runtime-flags.c | 41 |
10 files changed, 121 insertions, 5 deletions
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index fdc073b5a2b..6ac40f5d208 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -210,6 +210,8 @@ def vectorize_slp : Flag<["-"], "vectorize-slp">, HelpText<"Run the SLP vectorization passes">; def vectorize_slp_aggressive : Flag<["-"], "vectorize-slp-aggressive">, HelpText<"Run the BB vectorization passes">; +def dependent_lib : Joined<["--"], "dependent-lib=">, + HelpText<"Add dependent library">; //===----------------------------------------------------------------------===// // Dependency Output Options diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td index b29fc8802db..e98d8e85164 100644 --- a/clang/include/clang/Driver/CLCompatOptions.td +++ b/clang/include/clang/Driver/CLCompatOptions.td @@ -86,6 +86,12 @@ def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, 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 DLL run-time">; +def _SLASH_MDd : CLFlag<"MDd">, + HelpText<"Use DLL debug run-time">; +def _SLASH_MT : CLFlag<"MT">, HelpText<"Use static run-time">; +def _SLASH_MTd : CLFlag<"MTd">, HelpText<"Use static 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 +125,6 @@ def _SLASH_GS : CLFlag<"GS">; 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">; diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index 6717791466a..45d2bda985b 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -128,6 +128,9 @@ public: /// A list of command-line options to forward to the LLVM backend. std::vector<std::string> BackendOptions; + /// A list of dependent libraries. + std::vector<std::string> DependentLibraries; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 7e0e3aac072..c6d40330e0c 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -60,6 +60,9 @@ namespace { 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/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 4a3ce42f0a1..e4acadbb510 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2516,6 +2516,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, 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/clang/lib/Driver/Tools.h b/clang/lib/Driver/Tools.h index 9138ddf88ba..8c1e695aa20 100644 --- a/clang/lib/Driver/Tools.h +++ b/clang/lib/Driver/Tools.h @@ -74,6 +74,9 @@ using llvm::opt::ArgStringList; 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/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 27ddd84d52f..a4c93fa5b50 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -502,6 +502,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } } + Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib); + return Success; } diff --git a/clang/test/CodeGen/dependent-lib.c b/clang/test/CodeGen/dependent-lib.c new file mode 100644 index 00000000000..df4aaf07306 --- /dev/null +++ b/clang/test/CodeGen/dependent-lib.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s + +// CHECK: !llvm.module.flags = !{!0} +// CHECK: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]} +// CHECK: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]]} +// CHECK: ![[msvcrt]] = metadata !{metadata !"/DEFAULTLIB:msvcrt.lib"} + +// LINUX: !llvm.module.flags = !{!0} +// LINUX: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]} +// LINUX: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]]} +// LINUX: ![[msvcrt]] = metadata !{metadata !"-lmsvcrt"} + +int f(); diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index ba1c1f30144..d37e88e456a 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -89,6 +89,6 @@ // Unsupported but parsed options. Check that we don't error on them. // (/Zs is for syntax-only) // RUN: %clang_cl /Zs /EHsc /Fdfoo /fp:precise /Gd /GL /GL- -- %s 2>&1 -// RUN: %clang_cl /Zs /Gm /Gm- /GS /Gy /Gy- /GZ /MD /MT /MDd /MTd /Oi -- %s 2>&1 +// RUN: %clang_cl /Zs /Gm /Gm- /GS /Gy /Gy- /GZ /Oi -- %s 2>&1 // RUN: %clang_cl /Zs /RTC1 /wfoo /Zc:wchar_t- -- %s 2>&1 // RUN: %clang_cl /Zs /ZI /Zi /showIncludes -- %s 2>&1 diff --git a/clang/test/Driver/cl-runtime-flags.c b/clang/test/Driver/cl-runtime-flags.c new file mode 100644 index 00000000000..520093c3023 --- /dev/null +++ b/clang/test/Driver/cl-runtime-flags.c @@ -0,0 +1,41 @@ +// 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: --dependent-lib
+
+// RUN: %clang_cl -### -- %s 2>&1 | FileCheck -check-prefix=CHECK-MT %s
+// 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"
+// CHECK-MT: "--dependent-lib=libcmt"
+// CHECK-MT: "--dependent-lib=oldnames"
+
+// 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"
+// CHECK-MTd: "--dependent-lib=libcmtd"
+// CHECK-MTd: "--dependent-lib=oldnames"
+
+// 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"
+// CHECK-MD: "--dependent-lib=msvcrt"
+// CHECK-MD: "--dependent-lib=oldnames"
+
+// 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"
+// CHECK-MDd: "--dependent-lib=msvcrtd"
+// CHECK-MDd: "--dependent-lib=oldnames"
|