diff --git a/dmd/globals.d b/dmd/globals.d index 311a7172b6e..22b5845d94c 100644 --- a/dmd/globals.d +++ b/dmd/globals.d @@ -351,6 +351,7 @@ version (IN_LLVM) // target stuff const(void)* targetTriple; // const llvm::Triple* bool isUClibcEnvironment; + const(char)[] cppstdlib; // Cpp runtime library // Codegen cl options bool disableRedZone; diff --git a/dmd/globals.h b/dmd/globals.h index 5ef6df6873c..3ae98c28fdf 100644 --- a/dmd/globals.h +++ b/dmd/globals.h @@ -313,6 +313,7 @@ struct Param const llvm::Triple *targetTriple; bool isUClibcEnvironment; // not directly supported by LLVM + DString cppstdlib; // Cpp runtime library // Codegen cl options bool disableRedZone; diff --git a/dmd/mars.d b/dmd/mars.d index f971630ce9c..05c4847c961 100644 --- a/dmd/mars.d +++ b/dmd/mars.d @@ -83,6 +83,7 @@ version (IN_LLVM) const(char)* getPathToProducedBinary(); void deleteExeFile(); int runProgram(); + const (char)* getExplicitCppRuntimeName(); } else { @@ -431,6 +432,8 @@ else version (IN_LLVM) { + import dmd.root.string : toDString; + global.params.cppstdlib = toDString(getExplicitCppRuntimeName()); registerPredefinedVersions(); } else diff --git a/dmd/root/dcompat.h b/dmd/root/dcompat.h index 8c23056e746..a80675f097e 100644 --- a/dmd/root/dcompat.h +++ b/dmd/root/dcompat.h @@ -9,6 +9,8 @@ #pragma once +#include +#include #include "dsystem.h" /// Represents a D [ ] array @@ -33,6 +35,12 @@ struct DString : public DArray DString(size_t length, const char *ptr) : DArray(length, ptr) { } + + int compare (std::string str) + { + return this->length >= str.length() ? + strncmp(this->ptr, str.c_str(), this->length) : -1; + } }; /// Corresponding C++ type that maps to D size_t diff --git a/driver/linker.cpp b/driver/linker.cpp index 20ae660e7db..8cf800ad701 100644 --- a/driver/linker.cpp +++ b/driver/linker.cpp @@ -81,6 +81,12 @@ static llvm::cl::opt llvm::cl::value_desc("libcmt[d]|msvcrt[d]"), llvm::cl::cat(opts::linkingCategory)); +static llvm::cl::opt + cppstdlib("cppstdlib", llvm::cl::Optional , + llvm::cl::desc("C++ runtime library to link with"), + llvm::cl::value_desc("libstd++|libc++"), + llvm::cl::cat(opts::linkingCategory)); + ////////////////////////////////////////////////////////////////////////////// // linker-gcc.cpp @@ -335,3 +341,7 @@ int runProgram() { } return status; } + +////////////////////////////////////////////////////////////////////////////// + +const char * getExplicitCppRuntimeName() { return cppstdlib.c_str(); } diff --git a/driver/linker.h b/driver/linker.h index f962054efaf..f5a75285ec0 100644 --- a/driver/linker.h +++ b/driver/linker.h @@ -81,3 +81,8 @@ void deleteExeFile(); * @return the return status of the executable. */ int runProgram(); + +/** + * Returns the name of the C++ runtime library to link with. + */ +const char *getExplicitCppRuntimeName(); diff --git a/driver/main.cpp b/driver/main.cpp index 54d18b7572e..92e9d15cc66 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -784,7 +784,10 @@ void registerPredefinedTargetVersions() { VersionCondition::addPredefinedGlobalIdent("CRuntime_UClibc"); } else { VersionCondition::addPredefinedGlobalIdent("CRuntime_Glibc"); - VersionCondition::addPredefinedGlobalIdent("CppRuntime_Gcc"); + if (global.params.cppstdlib.compare("libc++") == 0) + VersionCondition::addPredefinedGlobalIdent("CppRuntime_Clang"); + else + VersionCondition::addPredefinedGlobalIdent("CppRuntime_Gcc"); } break; case llvm::Triple::Haiku: