summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2013-09-10 20:18:04 +0000
committerHans Wennborg <hans@hanshq.net>2013-09-10 20:18:04 +0000
commitf1a7425bd95ecb233d7333a2e1b0d63dde5e803d (patch)
treed3dd8bdc0e73d8abc43fdec4573c6c4c6b9660f1 /clang/lib
parentd8110b6558ad111a1c1c1542c12122900791311e (diff)
downloadbcm5719-llvm-f1a7425bd95ecb233d7333a2e1b0d63dde5e803d.tar.gz
bcm5719-llvm-f1a7425bd95ecb233d7333a2e1b0d63dde5e803d.zip
clang-cl: Support building DLLs (PR17083)
This adds driver support for building DLLs (the /LD and /LDd flags). It basically does two things: runtime selection and passing -dll and -implib to the linker. llvm-svn: 190428
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/Driver.cpp20
-rw-r--r--clang/lib/Driver/Tools.cpp31
2 files changed, 42 insertions, 9 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 1f2915ae32f..9bbbaae33e2 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1585,9 +1585,11 @@ void Driver::BuildJobsForAction(Compilation &C,
static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
StringRef BaseName, types::ID FileType) {
SmallString<128> Filename = ArgValue;
- assert(!ArgValue.empty() && "Output filename argument must not be empty.");
- if (llvm::sys::path::is_separator(Filename.back())) {
+ if (ArgValue.empty()) {
+ // If the argument is empty, output to BaseName in the current dir.
+ Filename = BaseName;
+ } else if (llvm::sys::path::is_separator(Filename.back())) {
// If the argument is a directory, output to BaseName in that dir.
llvm::sys::path::append(Filename, BaseName);
}
@@ -1595,6 +1597,13 @@ static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
if (!llvm::sys::path::has_extension(ArgValue)) {
// If the argument didn't provide an extension, then set it.
const char *Extension = types::getTypeTempSuffix(FileType, true);
+
+ if (FileType == types::TY_Image &&
+ Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd)) {
+ // The output file is a dll.
+ Extension = "dll";
+ }
+
llvm::sys::path::replace_extension(Filename, Extension);
}
@@ -1656,12 +1665,11 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
StringRef Val = C.getArgs().getLastArg(options::OPT__SLASH_Fe)->getValue();
NamedOutput = MakeCLOutputFilename(C.getArgs(), Val, BaseName,
types::TY_Image);
- } else if (JA.getType() == types::TY_Image) {
+ } else if (JA.getType() == types::TY_Image) {
if (IsCLMode()) {
// clang-cl uses BaseName for the executable name.
- SmallString<128> Filename = BaseName;
- llvm::sys::path::replace_extension(Filename, "exe");
- NamedOutput = C.getArgs().MakeArgString(Filename.c_str());
+ NamedOutput = MakeCLOutputFilename(C.getArgs(), "", BaseName,
+ types::TY_Image);
} else if (MultipleArchs && BoundArch) {
SmallString<128> Output(DefaultImageName.c_str());
Output += "-";
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index d43758e3ad6..79cdb042a95 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3714,6 +3714,11 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
unsigned RTOptionID = options::OPT__SLASH_MT;
+ if (Args.hasArg(options::OPT__SLASH_LDd))
+ // The /LDd option implies /MTd. The dependent lib part can be overridden,
+ // but defining _DEBUG is sticky.
+ RTOptionID = options::OPT__SLASH_MTd;
+
if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD,
options::OPT__SLASH_MDd,
options::OPT__SLASH_MT,
@@ -3723,6 +3728,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
switch(RTOptionID) {
case options::OPT__SLASH_MD:
+ if (Args.hasArg(options::OPT__SLASH_LDd))
+ CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("-D_DLL");
CmdArgs.push_back("--dependent-lib=msvcrt");
@@ -3734,6 +3741,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
CmdArgs.push_back("--dependent-lib=msvcrtd");
break;
case options::OPT__SLASH_MT:
+ if (Args.hasArg(options::OPT__SLASH_LDd))
+ CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("--dependent-lib=libcmt");
break;
@@ -6584,13 +6593,29 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-nologo");
+ bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd);
+
+ if (DLL) {
+ CmdArgs.push_back(Args.MakeArgString("-dll"));
+
+ SmallString<128> ImplibName(Output.getFilename());
+ llvm::sys::path::replace_extension(ImplibName, "lib");
+ CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") +
+ ImplibName.str()));
+ }
+
if (getToolChain().getDriver().getOrParseSanitizerArgs(Args).needsAsanRt()) {
CmdArgs.push_back(Args.MakeArgString("-debug"));
CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir);
- // FIXME: Handle 64-bit. Use asan_dll_thunk.dll when building a DLL.
- llvm::sys::path::append(
- LibSanitizer, "lib", "windows", "clang_rt.asan-i386.lib");
+ llvm::sys::path::append(LibSanitizer, "lib", "windows");
+ if (DLL) {
+ // FIXME: Not sure what the final name of the thunk lib is.
+ llvm::sys::path::append(LibSanitizer, "clang_rt.asan-i386-dll_thunk.lib");
+ } else {
+ llvm::sys::path::append(LibSanitizer, "clang_rt.asan-i386.lib");
+ }
+ // FIXME: Handle 64-bit.
CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
}
OpenPOWER on IntegriCloud