[clang] [clang] Support --sysroot= for ${arch}-windows-msvc targets (PR #96417)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 15 06:56:52 PDT 2026
https://github.com/trcrsired updated https://github.com/llvm/llvm-project/pull/96417
>From 4905cd086c32f9f1ec68bc64f2d17bfcfbbb03cf Mon Sep 17 00:00:00 2001
From: trcrsired <uwgghhbcad at gmail.com>
Date: Sat, 11 Oct 2025 09:01:53 +0800
Subject: [PATCH] [clang] Support --sysroot= for ${arch}-windows-msvc targets
I think it is possible to use the same rule for msvc targets with
--target= and --sysroot=
See Repository:
https://github.com/trcrsired/windows-msvc-sysroot
Add sysroot support for msvc
MSVC.cpp needs getDriver before using D
add stl in parser for -stdlib=
Add Vcruntime to runtime list and unwind list
MSVC add default runtime lib type and default unwind lib type
add a msvc sysroot test
use %S instead of /foo
Fix test for msvc-sysroot
Also add a pesudo implementation for WebAssembly and
maybe Microsoft STL could be ported to more targets in the future
Fix the toggle of wasm that prevents -stdlib=stl passed into
Avoid clang-formatting in MSVC.cpp
Add some comments to ToolChain
avoid indent the if block
Add back space before winsysroot line
use instead of arch in the comment
remove FIXME for libc++ since we have added the logic here
Remove MSVC.h formatting
Remove default cases in WebAssembly
add back the empty line before the Sysroot line
fix msvc-sysroot typo for libc++ loongarch
Fix : missing in CST_Stl case
Support --sysroot= for ${arch}-windows-msvc targets
I think it is possible to use the same rule for msvc targets with
--target= and --sysroot=
See Repository:
https://github.com/trcrsired/windows-msvc-sysroot
Add sysroot support for msvc
MSVC.cpp needs getDriver before using D
add stl in parser for -stdlib=
Add Vcruntime to runtime list and unwind list
MSVC add default runtime lib type and default unwind lib type
add a msvc sysroot test
use %S instead of /foo
Fix test for msvc-sysroot
Also add a pesudo implementation for WebAssembly and
maybe Microsoft STL could be ported to more targets in the future
Fix the toggle of wasm that prevents -stdlib=stl passed into
Avoid clang-formatting in MSVC.cpp
Add some comments to ToolChain
avoid indent the if block
Add back space before winsysroot line
use instead of arch in the comment
remove FIXME for libc++ since we have added the logic here
Remove MSVC.h formatting
Remove default cases in WebAssembly
add back the empty line before the Sysroot line
fix msvc-sysroot typo for libc++ loongarch
Fix : missing in CST_Stl case
[clang] update msvc-sysroot.cpp tep to test arm64ec and arm64x
[clang] Add arm64ec -windows-msvc support for msvc sysroot by finding libs in the aarch64-unknown-windows-msvc subdir
MSVC target needs to include Gnu.h to support libstdc++
[clang] fix formatting issues for MSVC sysroot PR
[clang] Support --sysroot= for ${arch}-windows-msvc targets
I think it is possible to use the same rule for msvc targets with
--target= and --sysroot=
See Repository:
https://github.com/trcrsired/windows-msvc-sysroot
Add sysroot support for msvc
MSVC.cpp needs getDriver before using D
add stl in parser for -stdlib=
Add Vcruntime to runtime list and unwind list
MSVC add default runtime lib type and default unwind lib type
add a msvc sysroot test
use %S instead of /foo
Fix test for msvc-sysroot
Also add a pesudo implementation for WebAssembly and
maybe Microsoft STL could be ported to more targets in the future
Fix the toggle of wasm that prevents -stdlib=stl passed into
Avoid clang-formatting in MSVC.cpp
Add some comments to ToolChain
avoid indent the if block
Add back space before winsysroot line
use instead of arch in the comment
remove FIXME for libc++ since we have added the logic here
Remove MSVC.h formatting
Remove default cases in WebAssembly
add back the empty line before the Sysroot line
fix msvc-sysroot typo for libc++ loongarch
Fix : missing in CST_Stl case
Support --sysroot= for ${arch}-windows-msvc targets
I think it is possible to use the same rule for msvc targets with
--target= and --sysroot=
See Repository:
https://github.com/trcrsired/windows-msvc-sysroot
Add sysroot support for msvc
MSVC.cpp needs getDriver before using D
add stl in parser for -stdlib=
Add Vcruntime to runtime list and unwind list
MSVC add default runtime lib type and default unwind lib type
add a msvc sysroot test
use %S instead of /foo
Fix test for msvc-sysroot
Also add a pesudo implementation for WebAssembly and
maybe Microsoft STL could be ported to more targets in the future
Fix the toggle of wasm that prevents -stdlib=stl passed into
Avoid clang-formatting in MSVC.cpp
Add some comments to ToolChain
avoid indent the if block
Add back space before winsysroot line
use instead of arch in the comment
remove FIXME for libc++ since we have added the logic here
Remove MSVC.h formatting
Remove default cases in WebAssembly
add back the empty line before the Sysroot line
fix msvc-sysroot typo for libc++ loongarch
Fix : missing in CST_Stl case
[clang] update msvc-sysroot.cpp tep to test arm64ec and arm64x
[clang] Add arm64ec -windows-msvc support for msvc sysroot by finding libs in the aarch64-unknown-windows-msvc subdir
MSVC target needs to include Gnu.h to support libstdc++
[clang] fix formatting issues for MSVC sysroot PR
[clang] Driver.cpp's formatting issue
[clang] Driver itself needs to be passed into CxxModulePathEvaluate
[clang] Fix Driver discards const qualifiers
[clang] Fix remaining unhandled msstl and also add msstl to mingw
We also always -lntdll since gcc with mcf alrady does that.
Even on windows 9x the linker would still discard -lntdll and
ntdll.dll does exist on windows 95
[clang] Darwin still did not handle msstl
---
clang/docs/UsersManual.rst | 73 +++++++
clang/include/clang/Driver/ToolChain.h | 16 +-
clang/lib/Driver/Driver.cpp | 102 +++++----
clang/lib/Driver/ToolChain.cpp | 10 +
clang/lib/Driver/ToolChains/AIX.cpp | 6 +-
clang/lib/Driver/ToolChains/BareMetal.cpp | 10 +-
clang/lib/Driver/ToolChains/CommonArgs.cpp | 4 +
clang/lib/Driver/ToolChains/Darwin.cpp | 24 ++-
clang/lib/Driver/ToolChains/Fuchsia.cpp | 2 +-
clang/lib/Driver/ToolChains/Gnu.cpp | 3 +
clang/lib/Driver/ToolChains/Hexagon.cpp | 3 +
clang/lib/Driver/ToolChains/MSVC.cpp | 222 ++++++++++++++++----
clang/lib/Driver/ToolChains/MSVC.h | 15 ++
clang/lib/Driver/ToolChains/MinGW.cpp | 30 ++-
clang/lib/Driver/ToolChains/OHOS.cpp | 4 +-
clang/lib/Driver/ToolChains/WebAssembly.cpp | 27 +++
clang/lib/Driver/ToolChains/WebAssembly.h | 2 +
clang/lib/Driver/ToolChains/ZOS.cpp | 6 +-
clang/test/Driver/msvc-sysroot.cpp | 90 ++++++++
clang/test/Driver/wasm-toolchain.cpp | 12 ++
20 files changed, 543 insertions(+), 118 deletions(-)
create mode 100644 clang/test/Driver/msvc-sysroot.cpp
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 5d7a124679d87..67a56d51fec3b 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -5607,3 +5607,76 @@ Restrictions and Limitations compared to Clang
Strict aliasing (TBAA) is always off by default in clang-cl whereas in clang,
strict aliasing is turned on by default for all optimization levels. For more
details, see :ref:`Strict aliasing <strict_aliasing>`.
+
+Using clang/clang++ with MSVC Targets
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+While ``clang-cl`` emulates the MSVC compiler interface, users may prefer to invoke ``clang`` or ``clang++`` directly for greater control and platform consistency. When targeting MSVC environments, Clang supports the use of ``--target=`` and ``--sysroot=`` following the same conventions as Unix-style cross-compilation.
+
+This approach avoids reliance on a Windows environment, Wine, or environmental variables, instead using a predictable and portable sysroot layout:
+
+Headers
+-------
+
+- Windows + CRT headers: ``include/``
+
+- C++ standard library headers (selected via ``-stdlib=``):
+
+ - ``-stdlib=msstl`` → ``include/c++/msstl``
+ Microsoft STL (MSVC's standard library implementation)
+
+ - ``-stdlib=libc++`` → ``include/c++/v1``
+ LLVM libc++ (Clang's standard library implementation)
+
+ - ``-stdlib=libstdc++`` → ``include/c++/<version>`` (e.g. ``16.0.0``)
+ GNU libstdc++ (GCC's standard library implementation)
+
+Library Naming Conventions
+--------------------------
+
+When targeting ``${cpu}-unknown-windows-msvc``, the naming of runtime libraries differs from GNU-style targets:
+
+- **LLVM libc++**:
+ - MSVC target: ``c++.dll``, ``c++.lib``
+ - GNU target: ``libc++.dll``, ``libc++.a``
+
+- **GNU libstdc++**:
+ - MSVC target: ``stdc++-6.dll``, ``stdc++.lib``
+ - GNU target: ``libstdc++-6.dll``, ``libstdc++.a``
+
+These naming conventions reflect platform-specific linker and runtime expectations. The MSVC target omits the ``lib`` prefix and uses `.lib` import libraries, while GNU targets retain the traditional Unix-style naming.
+
+Libraries
+---------
+
+The sysroot must contain libraries in the following fallback order:
+
+1. ``lib/${cpu}-unknown-windows-msvc``
+2. ``lib/``
+
+Example for ``x86_64-unknown-windows-msvc``:
+``lib/x86_64-unknown-windows-msvc`` → ``lib/``
+
+This structure allows toolchains to support both target-specific and shared libraries, enabling clean fallback behavior and simplifying multi-target packaging.
+
+Binaries
+--------
+
+The sysroot must also contain binaries in the following fallback order:
+
+1. ``bin/${cpu}-unknown-windows-msvc``
+2. ``bin/``
+
+Example for ``x86_64-unknown-windows-msvc``:
+``bin/x86_64-unknown-windows-msvc`` → ``bin/``
+
+This layout supports future scenarios such as universal binaries and ensures consistent tool resolution across architectures.
+
+Case Sensitivity
+----------------
+
+All header and library paths must use lowercase file names. This ensures compatibility across case-sensitive filesystems such as Linux and macOS, and matches the behavior of ``mingw-w64-crt``. Windows itself is case-insensitive, but relying on mixed-case paths can lead to portability issues.
+
+This layout is fully compatible with Clang’s standard sysroot resolution logic and requires no MSVC-specific flags. It enables clean cross-compilation workflows and portable toolchain packaging.
+
+For a reference implementation, see `windows-msvc-sysroot <https://github.com/trcrsired/windows-msvc-sysroot>`_.
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 5e111c43b717d..4e473fa8b0e5d 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -94,20 +94,14 @@ class ToolChain {
using path_list = SmallVector<std::string, 16>;
enum CXXStdlibType {
- CST_Libcxx,
- CST_Libstdcxx
+ CST_Libcxx, // LLVM libc++
+ CST_Libstdcxx, // GNU libstdc++
+ CST_Msstl, // MSVC STL
};
- enum RuntimeLibType {
- RLT_CompilerRT,
- RLT_Libgcc
- };
+ enum RuntimeLibType { RLT_CompilerRT, RLT_Libgcc, RLT_Vcruntime };
- enum UnwindLibType {
- UNW_None,
- UNW_CompilerRT,
- UNW_Libgcc
- };
+ enum UnwindLibType { UNW_None, UNW_CompilerRT, UNW_Libgcc, UNW_Vcruntime };
enum CStdlibType {
CST_Newlib,
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index b7f65b7b74401..4fe18fbdc7ae2 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2685,6 +2685,8 @@ bool Driver::HandleImmediateArgs(Compilation &C) {
case ToolChain::RLT_Libgcc:
llvm::outs() << GetFilePath("libgcc.a", TC) << "\n";
break;
+ default:
+ break;
}
return false;
}
@@ -6753,6 +6755,48 @@ std::string Driver::GetProgramPath(StringRef Name, const ToolChain &TC) const {
return std::string(Name);
}
+static std::optional<std::string>
+CxxModulePathEvaluate(const Driver &D, const ToolChain &TC,
+ ToolChain::CXXStdlibType cxxstdlib, const char *library) {
+ const char *modulejsonfilename = "modules.json";
+ switch (cxxstdlib) {
+ case ToolChain::CST_Libcxx: {
+ // Note when there are multiple flavours of libc++ the module json needs
+ // to look at the command-line arguments for the proper json. These
+ // flavours do not exist at the moment, but there are plans to provide a
+ // variant that is built with sanitizer instrumentation enabled.
+
+ // For example
+ // const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs());
+ // if (Sanitize.needsAsanRt())
+ // modulejsonfilename = "libc++.modules-asan.json";
+ // modulejsonfilename = "libc++.modules.json";
+ modulejsonfilename = "libc++.modules.json";
+ break;
+ }
+ case ToolChain::CST_Libstdcxx: {
+ modulejsonfilename = "libstdc++.modules.json";
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ if (library == nullptr) {
+ library = modulejsonfilename;
+ }
+ std::string lib = D.GetFilePath(library, TC);
+
+ SmallString<128> path(lib.begin(), lib.end());
+ llvm::sys::path::remove_filename(path);
+ llvm::sys::path::append(path, modulejsonfilename);
+ if (TC.getVFS().exists(path))
+ return static_cast<std::string>(path);
+
+ return {};
+}
+
std::string Driver::GetStdModuleManifestPath(const Compilation &C,
const ToolChain &TC) const {
std::string error = "<NOT PRESENT>";
@@ -6760,56 +6804,30 @@ std::string Driver::GetStdModuleManifestPath(const Compilation &C,
if (C.getArgs().hasArg(options::OPT_nostdlib))
return error;
- switch (TC.GetCXXStdlibType(C.getArgs())) {
+ auto cxxstdlib = TC.GetCXXStdlibType(C.getArgs());
+ switch (cxxstdlib) {
case ToolChain::CST_Libcxx: {
- auto evaluate = [&](const char *library) -> std::optional<std::string> {
- std::string lib = GetFilePath(library, TC);
-
- // Note when there are multiple flavours of libc++ the module json needs
- // to look at the command-line arguments for the proper json. These
- // flavours do not exist at the moment, but there are plans to provide a
- // variant that is built with sanitizer instrumentation enabled.
-
- // For example
- // StringRef modules = [&] {
- // const SanitizerArgs &Sanitize = TC.getSanitizerArgs(C.getArgs());
- // if (Sanitize.needsAsanRt())
- // return "libc++.modules-asan.json";
- // return "libc++.modules.json";
- // }();
-
- SmallString<128> path(lib.begin(), lib.end());
- llvm::sys::path::remove_filename(path);
- llvm::sys::path::append(path, "libc++.modules.json");
- if (TC.getVFS().exists(path))
- return static_cast<std::string>(path);
-
- return {};
- };
-
- if (std::optional<std::string> result = evaluate("libc++.so"); result)
+ if (std::optional<std::string> result =
+ CxxModulePathEvaluate(*this, TC, cxxstdlib, "libc++.so");
+ result)
return *result;
- return evaluate("libc++.a").value_or(error);
+ return CxxModulePathEvaluate(*this, TC, cxxstdlib, "libc++.a")
+ .value_or(error);
}
case ToolChain::CST_Libstdcxx: {
- auto evaluate = [&](const char *library) -> std::optional<std::string> {
- std::string lib = GetFilePath(library, TC);
-
- SmallString<128> path(lib.begin(), lib.end());
- llvm::sys::path::remove_filename(path);
- llvm::sys::path::append(path, "libstdc++.modules.json");
- if (TC.getVFS().exists(path))
- return static_cast<std::string>(path);
-
- return {};
- };
-
- if (std::optional<std::string> result = evaluate("libstdc++.so"); result)
+ if (std::optional<std::string> result =
+ CxxModulePathEvaluate(*this, TC, cxxstdlib, "libstdc++.so");
+ result)
return *result;
- return evaluate("libstdc++.a").value_or(error);
+ return CxxModulePathEvaluate(*this, TC, cxxstdlib, "libstdc++.a")
+ .value_or(error);
+ }
+
+ default: {
+ return CxxModulePathEvaluate(*this, TC, cxxstdlib, nullptr).value_or(error);
}
}
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 94913837f5339..e696024f63c52 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1339,6 +1339,8 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
runtimeLibType = ToolChain::RLT_CompilerRT;
else if (LibName == "libgcc")
runtimeLibType = ToolChain::RLT_Libgcc;
+ else if (LibName == "vcruntime")
+ runtimeLibType = ToolChain::RLT_Vcruntime;
else if (LibName == "platform")
runtimeLibType = GetDefaultRuntimeLibType();
else {
@@ -1377,6 +1379,8 @@ ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
unwindLibType = ToolChain::UNW_CompilerRT;
} else if (LibName == "libgcc")
unwindLibType = ToolChain::UNW_Libgcc;
+ else if (LibName == "vcruntime")
+ unwindLibType = ToolChain::UNW_Vcruntime;
else {
if (A)
getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
@@ -1400,6 +1404,8 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
cxxStdlibType = ToolChain::CST_Libcxx;
else if (LibName == "libstdc++")
cxxStdlibType = ToolChain::CST_Libstdcxx;
+ else if (LibName == "msstl")
+ cxxStdlibType = ToolChain::CST_Msstl;
else if (LibName == "platform")
cxxStdlibType = GetDefaultCXXStdlibType();
else {
@@ -1580,6 +1586,10 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
case ToolChain::CST_Libstdcxx:
CmdArgs.push_back("-lstdc++");
break;
+
+ case ToolChain::CST_Msstl:
+ // MSVC STL does not need to add -l
+ break;
}
}
diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp
index e7f4792ac5bba..65343e10563a5 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -448,6 +448,8 @@ void AIX::AddClangCXXStdlibIncludeArgs(
CC1Args.push_back("-D__LIBC_NO_CPP_MATH_OVERLOADS__");
return;
}
+ default:
+ break;
}
llvm_unreachable("Unexpected C++ library type; only libc++ is supported.");
@@ -477,9 +479,11 @@ void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
CmdArgs.push_back("-lc++experimental");
CmdArgs.push_back("-lc++abi");
return;
+ default:
+ break;
}
- llvm_unreachable("Unexpected C++ library type; only libc++ is supported.");
+ llvm_unreachable("Unexpected C++ library type");
}
// This function processes all the mtocdata options to build the final
diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp
index 5e974527774eb..73ae1fb2dd51b 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -485,10 +485,14 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
AddCXXIncludePath(P);
break;
}
- case ToolChain::CST_Libstdcxx:
+ case ToolChain::CST_Libstdcxx: {
addLibStdCxxIncludePaths(DriverArgs, CC1Args);
break;
}
+ default: {
+ break;
+ }
+ }
std::string SysRootDir(computeSysRoot());
if (SysRootDir.empty())
@@ -534,6 +538,8 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
}
break;
}
+ default:
+ break;
}
}
switch (GetCXXStdlibType(DriverArgs)) {
@@ -667,6 +673,8 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA,
TC.getCompilerRTArgString(Args, "crtend", ToolChain::FT_Object);
break;
}
+ default:
+ return;
}
CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath(CRTBegin)));
}
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 9a17fa2546e68..447635e799998 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2443,6 +2443,8 @@ static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
CmdArgs.push_back("-lunwind");
}
break;
+ default:
+ break;
}
if (AsNeeded)
@@ -2491,6 +2493,8 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
} else
AddLibgcc(TC, D, CmdArgs, Args);
break;
+ default:
+ break;
}
// On Android, the unwinder uses dl_iterate_phdr (or one of
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 7251f4a92d92d..acba3dedba8f2 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -26,6 +26,7 @@
#include "llvm/TargetParser/TargetParser.h"
#include "llvm/TargetParser/Triple.h"
#include <cstdlib> // ::getenv
+#include <string_view>
#ifdef CLANG_USE_XCSELECT
#include <xcselect.h> // ::xcselect_host_sdk_path
@@ -2892,8 +2893,11 @@ void AppleMachO::AddClangCXXStdlibIncludeArgs(
llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs);
- switch (GetCXXStdlibType(DriverArgs)) {
- case ToolChain::CST_Libcxx: {
+ auto cxxstdlib = GetCXXStdlibType(DriverArgs);
+ switch (cxxstdlib) {
+ case ToolChain::CST_Libcxx:
+ [[fallthrough]];
+ case ToolChain::CST_Msstl: {
// On Darwin, libc++ can be installed in one of the following places:
// 1. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
// 2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
@@ -2907,8 +2911,14 @@ void AppleMachO::AddClangCXXStdlibIncludeArgs(
// Get from '<install>/bin' to '<install>/include/c++/v1'.
// Note that InstallBin can be relative, so we use '..' instead of
// parent_path.
+ std::string_view cxxstrname;
+ if (cxxstdlib == CST_Msstl) {
+ cxxstrname = "msstl";
+ } else {
+ cxxstrname = "v1";
+ }
llvm::SmallString<128> InstallBin(getDriver().Dir); // <install>/bin
- llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
+ llvm::sys::path::append(InstallBin, "..", "include", "c++", cxxstrname);
if (getVFS().exists(InstallBin)) {
addSystemInclude(DriverArgs, CC1Args, InstallBin);
return;
@@ -2919,7 +2929,7 @@ void AppleMachO::AddClangCXXStdlibIncludeArgs(
// Otherwise, check for (2)
llvm::SmallString<128> SysrootUsr = Sysroot;
- llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
+ llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", cxxstrname);
if (getVFS().exists(SysrootUsr)) {
addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
return;
@@ -2932,10 +2942,11 @@ void AppleMachO::AddClangCXXStdlibIncludeArgs(
break;
}
- case ToolChain::CST_Libstdcxx:
+ case ToolChain::CST_Libstdcxx: {
AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);
break;
}
+ }
}
void AppleMachO::AddGnuCPlusPlusIncludePaths(
@@ -3029,6 +3040,9 @@ void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,
// Otherwise, let the linker search.
CmdArgs.push_back("-lstdc++");
break;
+
+ default:
+ break;
}
}
diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp
index 9edfc4de3d602..e3bf3026b73c2 100644
--- a/clang/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp
@@ -467,7 +467,7 @@ void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
CmdArgs.push_back("-lc++experimental");
break;
- case ToolChain::CST_Libstdcxx:
+ default:
llvm_unreachable("invalid stdlib name");
}
}
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index d8d537ec14b89..d5a58fcf4c67a 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -3243,6 +3243,9 @@ void Generic_GCC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
case ToolChain::CST_Libstdcxx:
addLibStdCxxIncludePaths(DriverArgs, CC1Args);
break;
+
+ default:
+ break;
}
}
diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp
index f3e5a0438a768..a31b467a87442 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -630,6 +630,9 @@ void HexagonToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
case ToolChain::CST_Libstdcxx:
CmdArgs.push_back("-lstdc++");
break;
+
+ default:
+ break;
}
}
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index f57440855fce4..8668e75033ec3 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -8,6 +8,7 @@
#include "MSVC.h"
#include "Darwin.h"
+#include "Gnu.h"
#include "clang/Config/config.h"
#include "clang/Driver/CommonArgs.h"
#include "clang/Driver/Compilation.h"
@@ -91,50 +92,70 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-defaultlib:oldnames");
}
- // If the VC environment hasn't been configured (perhaps because the user
- // did not run vcvarsall), try to build a consistent link environment. If
- // the environment variable is set however, assume the user knows what
- // they're doing. If the user passes /vctoolsdir or /winsdkdir, trust that
- // over env vars.
- if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
- options::OPT__SLASH_winsysroot)) {
- // cl.exe doesn't find the DIA SDK automatically, so this too requires
- // explicit flags and doesn't automatically look in "DIA SDK" relative
- // to the path we found for VCToolChainPath.
- llvm::SmallString<128> DIAPath(A->getValue());
- if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
- llvm::sys::path::append(DIAPath, "DIA SDK");
-
- // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
- llvm::sys::path::append(DIAPath, "lib",
- llvm::archToLegacyVCArch(TC.getArch()));
- CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + DIAPath));
- }
- if (!llvm::sys::Process::GetEnv("LIB") ||
- Args.hasArg(options::OPT__SLASH_vctoolsdir,
- options::OPT__SLASH_vctoolsversion,
- options::OPT__SLASH_winsysroot)) {
- CmdArgs.push_back(Args.MakeArgString(
- Twine("-libpath:") +
- TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
- CmdArgs.push_back(Args.MakeArgString(
- Twine("-libpath:") +
- TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib, "atlmfc")));
- }
- if (!llvm::sys::Process::GetEnv("LIB") ||
- Args.hasArg(options::OPT__SLASH_winsdkdir,
- options::OPT__SLASH_winsdkversion,
- options::OPT__SLASH_winsysroot)) {
- if (TC.useUniversalCRT()) {
- std::string UniversalCRTLibPath;
- if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
+ auto SysRoot = TC.getDriver().SysRoot;
+ if (!SysRoot.empty()) {
+ // If we have --sysroot, then we ignore all other setings
+ // libpath is $SYSROOT/lib and $SYSROOT/lib/${ARCH}-unknown-windows-msvc
+ // For ARM64EC, the ARCH is aarch64 instead
+ auto triple = TC.getTriple();
+ const std::string MultiarchTriple =
+ TC.getMultiarchTriple(TC.getDriver(), triple, SysRoot);
+ std::string SysRootLib = "-libpath:" + SysRoot + "/lib";
+ CmdArgs.push_back(Args.MakeArgString(SysRootLib + '/' + MultiarchTriple));
+ if (triple.isWindowsArm64EC()) {
+ triple.setArch(triple.getArch());
+ const std::string NoSubArchMultiarchTriple =
+ TC.getMultiarchTriple(TC.getDriver(), triple, SysRoot);
+ CmdArgs.push_back(
+ Args.MakeArgString(SysRootLib + '/' + NoSubArchMultiarchTriple));
+ }
+ CmdArgs.push_back(Args.MakeArgString(SysRootLib));
+ } else {
+ // If the VC environment hasn't been configured (perhaps because the user
+ // did not run vcvarsall), try to build a consistent link environment. If
+ // the environment variable is set however, assume the user knows what
+ // they're doing. If the user passes /vctoolsdir or /winsdkdir, trust that
+ // over env vars.
+ if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
+ options::OPT__SLASH_winsysroot)) {
+ // cl.exe doesn't find the DIA SDK automatically, so this too requires
+ // explicit flags and doesn't automatically look in "DIA SDK" relative
+ // to the path we found for VCToolChainPath.
+ llvm::SmallString<128> DIAPath(A->getValue());
+ if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
+ llvm::sys::path::append(DIAPath, "DIA SDK");
+
+ // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
+ llvm::sys::path::append(DIAPath, "lib",
+ llvm::archToLegacyVCArch(TC.getArch()));
+ CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + DIAPath));
+ }
+ if (!llvm::sys::Process::GetEnv("LIB") ||
+ Args.hasArg(options::OPT__SLASH_vctoolsdir,
+ options::OPT__SLASH_vctoolsversion,
+ options::OPT__SLASH_winsysroot)) {
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-libpath:") +
+ TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-libpath:") +
+ TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib, "atlmfc")));
+ }
+ if (!llvm::sys::Process::GetEnv("LIB") ||
+ Args.hasArg(options::OPT__SLASH_winsdkdir,
+ options::OPT__SLASH_winsdkversion,
+ options::OPT__SLASH_winsysroot)) {
+ if (TC.useUniversalCRT()) {
+ std::string UniversalCRTLibPath;
+ if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
+ }
+ std::string WindowsSdkLibPath;
+ if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
CmdArgs.push_back(
- Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
+ Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
}
- std::string WindowsSdkLibPath;
- if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
- CmdArgs.push_back(
- Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
}
if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
@@ -435,6 +456,12 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
RocmInstallation(D, Triple, Args), SYCLInstallation(D, Triple, Args) {
getProgramPaths().push_back(getDriver().Dir);
+ auto SysRoot = getDriver().SysRoot;
+ if (!SysRoot.empty()) {
+ // We have sysroot so we ignore all VCTools settings
+ return;
+ }
+
std::optional<llvm::StringRef> VCToolsDir, VCToolsVersion;
if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir))
VCToolsDir = A->getValue();
@@ -664,6 +691,17 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
"include");
}
+ auto SysRoot = getDriver().SysRoot;
+ if (!SysRoot.empty()) {
+ const Driver &D = getDriver();
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+ addSystemInclude(DriverArgs, CC1Args,
+ SysRoot + "/include/" + MultiarchTriple);
+ addSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
+ return;
+ }
+
// Add %INCLUDE%-like directories from the -imsvc flag.
for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
addSystemInclude(DriverArgs, CC1Args, Path);
@@ -795,7 +833,22 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
- // FIXME: There should probably be logic here to find libc++ on Windows.
+ if (DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc,
+ options::OPT_nostdincxx))
+ return;
+ if (getDriver().SysRoot.empty())
+ return;
+ switch (GetCXXStdlibType(DriverArgs)) {
+ case ToolChain::CST_Msstl:
+ addMsstlIncludePaths(DriverArgs, CC1Args);
+ break;
+ case ToolChain::CST_Libstdcxx:
+ addLibStdCXXIncludePaths(DriverArgs, CC1Args);
+ break;
+ case ToolChain::CST_Libcxx:
+ addLibCxxIncludePaths(DriverArgs, CC1Args);
+ break;
+ }
}
VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
@@ -1047,3 +1100,86 @@ void MSVCToolChain::addClangTargetOptions(
if (Arg *A = DriverArgs.getLastArgNoClaim(options::OPT_marm64x))
A->ignoreTargetSpecific();
}
+
+void MSVCToolChain::addMsstlIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+
+ std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/msstl";
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/msstl");
+}
+
+void MSVCToolChain::addLibCxxIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+
+ std::string Version = detectLibcxxVersion(LibPath);
+ if (Version.empty())
+ return;
+
+ std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/" + Version;
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/" + Version);
+}
+
+void MSVCToolChain::addLibStdCXXIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ // We cannot use GCCInstallationDetector here as the sysroot usually does
+ // not contain a full GCC installation.
+ // Instead, we search the given sysroot for /usr/include/xx, similar
+ // to how we do it for libc++.
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+
+ // This is similar to detectLibcxxVersion()
+ std::string Version;
+ {
+ std::error_code EC;
+ Generic_GCC::GCCVersion MaxVersion =
+ Generic_GCC::GCCVersion::Parse("0.0.0");
+ SmallString<128> Path(LibPath);
+ llvm::sys::path::append(Path, "c++");
+ for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(Path, EC), LE;
+ !EC && LI != LE; LI = LI.increment(EC)) {
+ StringRef VersionText = llvm::sys::path::filename(LI->path());
+ if (VersionText[0] != 'v') {
+ auto Version = Generic_GCC::GCCVersion::Parse(VersionText);
+ if (Version > MaxVersion)
+ MaxVersion = Version;
+ }
+ }
+ if (MaxVersion.Major > 0)
+ Version = MaxVersion.Text;
+ }
+
+ if (Version.empty())
+ return;
+
+ std::string TargetDir = LibPath + "/c++/" + Version + "/" + MultiarchTriple;
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/" + Version);
+ // Third the backward one.
+ addSystemInclude(DriverArgs, CC1Args,
+ LibPath + "/c++/" + Version + "/backward");
+}
diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h
index 80a6cbd9bc15b..4bed2146b3fe4 100644
--- a/clang/lib/Driver/ToolChains/MSVC.h
+++ b/clang/lib/Driver/ToolChains/MSVC.h
@@ -137,6 +137,21 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
Tool *buildLinker() const override;
Tool *buildAssembler() const override;
private:
+ CXXStdlibType GetDefaultCXXStdlibType() const override {
+ return ToolChain::CST_Msstl;
+ }
+ RuntimeLibType GetDefaultRuntimeLibType() const override {
+ return ToolChain::RLT_Vcruntime;
+ }
+ UnwindLibType GetDefaultUnwindLibType() const override {
+ return ToolChain::UNW_Vcruntime;
+ }
+ void addMsstlIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
+ void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
+ void addLibStdCXXIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
std::optional<llvm::StringRef> WinSdkDir, WinSdkVersion, WinSysRoot;
std::string VCToolChainPath;
llvm::ToolsetLayout VSLayout = llvm::ToolsetLayout::OlderVS;
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 2c9a174069f70..29c68804d179d 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -19,6 +19,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include <string_view>
#include <system_error>
using namespace clang::diag;
@@ -781,22 +782,30 @@ void toolchains::MinGW::AddClangCXXStdlibIncludeArgs(
StringRef Slash = llvm::sys::path::get_separator();
- switch (GetCXXStdlibType(DriverArgs)) {
- case ToolChain::CST_Libcxx: {
- std::string TargetDir = (Base + "include" + Slash + getTripleString() +
- Slash + "c++" + Slash + "v1")
- .str();
+ auto cxxstdlib = GetCXXStdlibType(DriverArgs);
+ switch (cxxstdlib) {
+ case ToolChain::CST_Libcxx:
+ [[fallthrough]];
+ case ToolChain::CST_Msstl: {
+ std::string cxxincludedir = (Slash + "c++" + Slash).str();
+ std::string_view cxxstrname;
+ if (cxxstdlib == CST_Msstl) {
+ cxxstrname = "msstl";
+ } else {
+ cxxstrname = "v1";
+ }
+ cxxincludedir.append(cxxstrname);
+ std::string TargetDir =
+ (Base + "include" + Slash + getTripleString() + cxxincludedir).str();
if (getDriver().getVFS().exists(TargetDir))
addSystemInclude(DriverArgs, CC1Args, TargetDir);
addSystemInclude(DriverArgs, CC1Args,
- Base + SubdirName + Slash + "include" + Slash + "c++" +
- Slash + "v1");
- addSystemInclude(DriverArgs, CC1Args,
- Base + "include" + Slash + "c++" + Slash + "v1");
+ Base + SubdirName + Slash + "include" + cxxincludedir);
+ addSystemInclude(DriverArgs, CC1Args, Base + "include" + cxxincludedir);
break;
}
- case ToolChain::CST_Libstdcxx:
+ case ToolChain::CST_Libstdcxx: {
llvm::SmallVector<llvm::SmallString<1024>, 7> CppIncludeBases;
CppIncludeBases.emplace_back(Base);
llvm::sys::path::append(CppIncludeBases[0], SubdirName, "include", "c++");
@@ -824,6 +833,7 @@ void toolchains::MinGW::AddClangCXXStdlibIncludeArgs(
}
break;
}
+ }
}
static bool testTriple(const Driver &D, const llvm::Triple &Triple,
diff --git a/clang/lib/Driver/ToolChains/OHOS.cpp b/clang/lib/Driver/ToolChains/OHOS.cpp
index 2a83ef9db59cc..359ede6c36c0c 100644
--- a/clang/lib/Driver/ToolChains/OHOS.cpp
+++ b/clang/lib/Driver/ToolChains/OHOS.cpp
@@ -266,8 +266,8 @@ void OHOS::AddCXXStdlibLibArgs(const ArgList &Args,
CmdArgs.push_back("-lunwind");
break;
- case ToolChain::CST_Libstdcxx:
- llvm_unreachable("invalid stdlib name");
+ default:
+ break;
}
}
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index e532ef0743cc2..a56537dffdd6a 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -483,6 +483,8 @@ WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
return ToolChain::CST_Libcxx;
else if (Value == "libstdc++")
return ToolChain::CST_Libstdcxx;
+ else if (Value == "msstl")
+ return ToolChain::CST_Msstl;
else
getDriver().Diag(diag::err_drv_invalid_stdlib_name)
<< A->getAsString(Args);
@@ -541,6 +543,9 @@ void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
case ToolChain::CST_Libstdcxx:
addLibStdCXXIncludePaths(DriverArgs, CC1Args);
break;
+ case ToolChain::CST_Msstl:
+ addMsstlIncludePaths(DriverArgs, CC1Args);
+ break;
}
}
@@ -557,6 +562,8 @@ void WebAssembly::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
case ToolChain::CST_Libstdcxx:
CmdArgs.push_back("-lstdc++");
break;
+ default:
+ break;
}
}
@@ -580,6 +587,26 @@ Tool *WebAssembly::buildLinker() const {
return new tools::wasm::Linker(*this);
}
+void WebAssembly::addMsstlIncludePaths(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+ std::string LibPath = SysRoot + "/include";
+ const std::string MultiarchTriple =
+ getMultiarchTriple(D, getTriple(), SysRoot);
+ bool IsKnownOs = (getTriple().getOS() != llvm::Triple::UnknownOS);
+
+ // First add the per-target include path if the OS is known.
+ if (IsKnownOs) {
+ std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/msstl";
+ addSystemInclude(DriverArgs, CC1Args, TargetDir);
+ }
+
+ // Second add the generic one.
+ addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/msstl");
+}
+
void WebAssembly::addLibCxxIncludePaths(
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.h b/clang/lib/Driver/ToolChains/WebAssembly.h
index 76e0ca39bd748..2978f15dae49d 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.h
+++ b/clang/lib/Driver/ToolChains/WebAssembly.h
@@ -79,6 +79,8 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly final : public ToolChain {
const llvm::Triple &TargetTriple,
StringRef SysRoot) const override;
+ void addMsstlIncludePaths(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
void addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
void addLibStdCXXIncludePaths(const llvm::opt::ArgList &DriverArgs,
diff --git a/clang/lib/Driver/ToolChains/ZOS.cpp b/clang/lib/Driver/ToolChains/ZOS.cpp
index c40f71c170538..7bc65474b184d 100644
--- a/clang/lib/Driver/ToolChains/ZOS.cpp
+++ b/clang/lib/Driver/ToolChains/ZOS.cpp
@@ -249,6 +249,8 @@ void ZOS::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
CmdArgs.push_back(
Args.MakeArgString("//'" + ClangHLQ + ".SCEELIB(CRTDQUNW)'"));
} break;
+ default:
+ break;
}
}
@@ -342,9 +344,9 @@ void ZOS::AddClangCXXStdlibIncludeArgs(
TryAddIncludeFromPath(InstallBin, DriverArgs, CC1Args);
break;
}
- case ToolChain::CST_Libstdcxx:
+ default:
llvm::report_fatal_error(
- "picking up libstdc++ headers is unimplemented on z/OS");
+ "picking up non libc++ headers is unimplemented on z/OS");
break;
}
}
diff --git a/clang/test/Driver/msvc-sysroot.cpp b/clang/test/Driver/msvc-sysroot.cpp
new file mode 100644
index 0000000000000..29e74033e6d35
--- /dev/null
+++ b/clang/test/Driver/msvc-sysroot.cpp
@@ -0,0 +1,90 @@
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -### \
+// RUN: --sysroot=%S -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_X86_64_MSSTL %s
+// COMPILE_X86_64_MSSTL: clang{{.*}}" "-cc1"
+// COMPILE_X86_64_MSSTL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc/c++/msstl"
+// COMPILE_X86_64_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/msstl"
+// COMPILE_X86_64_MSSTL: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -### \
+// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree/usr -stdlib=libc++ -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_X86_64_LIBCXX %s
+// COMPILE_X86_64_LIBCXX: clang{{.*}}" "-cc1"
+// COMPILE_X86_64_LIBCXX: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_LIBCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc/c++/v1"
+// COMPILE_X86_64_LIBCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/v1"
+// COMPILE_X86_64_LIBCXX: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx -### --target=x86_64-unknown-windows-msvc --stdlib=libstdc++ %s 2>&1 \
+// RUN: -fuse-ld=lld --sysroot=%S/Inputs/basic_linux_libstdcxx_libcxxv2_tree/usr \
+// RUN: | FileCheck -check-prefix=COMPILE_X86_64_LIBSTDCXX %s
+// COMPILE_X86_64_LIBSTDCXX: "-cc1"
+// COMPILE_X86_64_LIBSTDCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
+// COMPILE_X86_64_LIBSTDCXX: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/backward"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT:[^"]+]]/include"
+// COMPILE_X86_64_LIBSTDCXX: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=aarch64-unknown-windows-msvc -### \
+// RUN: --sysroot=%S -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_AARCH64_MSSTL %s
+// COMPILE_AARCH64_MSSTL: clang{{.*}}" "-cc1"
+// COMPILE_AARCH64_MSSTL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_AARCH64_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/aarch64-unknown-windows-msvc/c++/msstl"
+// COMPILE_AARCH64_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/msstl"
+// COMPILE_AARCH64_MSSTL: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/aarch64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=arm64ec-unknown-windows-msvc -### \
+// RUN: --sysroot=%S -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_ARM64EC_MSSTL %s
+// COMPILE_ARM64EC_MSSTL: clang{{.*}}" "-cc1"
+// COMPILE_ARM64EC_MSSTL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_ARM64EC_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/arm64ec-unknown-windows-msvc/c++/msstl"
+// COMPILE_ARM64EC_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/msstl"
+// COMPILE_ARM64EC_MSSTL: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/arm64ec-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib/aarch64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=loongarch64-unknown-windows-msvc -stdlib=msstl -### \
+// RUN: --sysroot=%S -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_LOONGARCH64_MSSTL %s
+// COMPILE_LOONGARCH64_MSSTL: clang{{.*}}" "-cc1"
+// COMPILE_LOONGARCH64_MSSTL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_LOONGARCH64_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/loongarch64-unknown-windows-msvc/c++/msstl"
+// COMPILE_LOONGARCH64_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/msstl"
+// COMPILE_LOONGARCH64_MSSTL: lld-link{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/loongarch64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -stdlib=msstl -### \
+// RUN: --sysroot=%S %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_X86_64_MSSTL_LINK %s
+// COMPILE_X86_64_MSSTL_LINK: clang{{.*}}" "-cc1"
+// COMPILE_X86_64_MSSTL_LINK: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_X86_64_MSSTL_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/x86_64-unknown-windows-msvc/c++/msstl"
+// COMPILE_X86_64_MSSTL_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/msstl"
+// COMPILE_X86_64_MSSTL_LINK: link.exe{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/x86_64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=loongarch64-unknown-windows-msvc -stdlib=libc++ -### \
+// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree/usr %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_LOONGARCH64_LIBCXX_LINK %s
+// COMPILE_LOONGARCH64_LIBCXX_LINK: clang{{.*}}" "-cc1"
+// COMPILE_LOONGARCH64_LIBCXX_LINK: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_LOONGARCH64_LIBCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/loongarch64-unknown-windows-msvc/c++/v1"
+// COMPILE_LOONGARCH64_LIBCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/v1"
+// COMPILE_LOONGARCH64_LIBCXX_LINK: link.exe{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/loongarch64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
+
+// RUN: %clangxx --target=riscv64-unknown-windows-msvc -### --stdlib=libstdc++ %s 2>&1 \
+// RUN: --sysroot=%S/Inputs/basic_linux_libstdcxx_libcxxv2_tree/usr \
+// RUN: | FileCheck -check-prefix=COMPILE_RISCV64_LIBSTDCXX_LINK %s
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-cc1"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/riscv64-unknown-windows-msvc"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/4.8/backward"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/riscv64-unknown-windows-msvc"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" "[[SYSROOT:[^"]+]]/include"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: link.exe{{.*}}" "-libpath:[[SYSROOT:[^"]+]]/lib/riscv64-unknown-windows-msvc" "-libpath:[[SYSROOT:[^"]+]]/lib"
diff --git a/clang/test/Driver/wasm-toolchain.cpp b/clang/test/Driver/wasm-toolchain.cpp
index 30a2f9397e3f4..06753dac11375 100644
--- a/clang/test/Driver/wasm-toolchain.cpp
+++ b/clang/test/Driver/wasm-toolchain.cpp
@@ -146,3 +146,15 @@
// RUN: %clangxx -### --target=wasm32-wasi -fwasm-exceptions --sysroot=/foo --stdlib=libc++ %s 2>&1 \
// RUN: | FileCheck -check-prefix=EH_ON_LINK %s
// EH_ON_LINK: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi/eh" "-L/foo/lib/wasm32-wasi"
+
+// RUN: %clangxx -### --target=wasm32-wasi --stdlib=msstl %s 2>&1 \
+// RUN: --sysroot=%S \
+// RUN: | FileCheck -check-prefix=COMPILE_MSSTL %s
+// COMPILE_MSSTL: "-cc1"
+// COMPILE_MSSTL: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]"
+// COMPILE_MSSTL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// COMPILE_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/wasm32-wasi/c++/msstl"
+// COMPILE_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/c++/msstl"
+// COMPILE_MSSTL: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include"
+// COMPILE_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include/wasm32-wasi"
+// COMPILE_MSSTL: "-internal-isystem" "[[SYSROOT:[^"]+]]/include"
More information about the cfe-commits
mailing list