https://github.com/trcrsired updated 
https://github.com/llvm/llvm-project/pull/96417

>From 35f03003c071a8d727f108975800cae1acc3d8c3 Mon Sep 17 00:00:00 2001
From: trcrsired <[email protected]>
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] msvc-sysroot.cpp test has been completely broken
since last commit
Fix it

[clang] change BareMetal to default to prevent msstl
warning
---
 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   |  12 +-
 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        | 317 +++++++++++++++++---
 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          | 128 ++++++++
 clang/test/Driver/wasm-toolchain.cpp        |  12 +
 20 files changed, 678 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 3bc8622b13d90..508905e170963 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -6266,3 +6266,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 863ba1084cb1a..6f2717aadf44e 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -98,20 +98,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 1a91b353a27e4..5f2db6ec0cf82 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2745,6 +2745,8 @@ bool Driver::HandleImmediateArgs(Compilation &C) {
     case ToolChain::RLT_Libgcc:
       llvm::outs() << GetFilePath("libgcc.a", TC) << "\n";
       break;
+    default:
+      break;
     }
     return false;
   }
@@ -6859,6 +6861,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>";
@@ -6866,56 +6910,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 21d2fbef59fc6..4bef998387b95 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1544,6 +1544,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 {
@@ -1583,6 +1585,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)
@@ -1606,6 +1610,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 {
@@ -1786,6 +1792,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 586bc08067eff..7b0bfe29968f9 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -446,6 +446,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.");
@@ -475,9 +477,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 ba454acbf755c..6a185e92782c9 100644
--- a/clang/lib/Driver/ToolChains/BareMetal.cpp
+++ b/clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -405,10 +405,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())
@@ -454,6 +458,8 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList 
&DriverArgs,
       }
       break;
     }
+    default:
+      break;
     }
   }
   switch (GetCXXStdlibType(DriverArgs)) {
@@ -464,7 +470,7 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList 
&DriverArgs,
       addSystemInclude(DriverArgs, CC1Args, Dir.str());
     break;
   }
-  case ToolChain::CST_Libstdcxx:
+  default:
     break;
   }
 }
@@ -587,6 +593,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 dfd13fbe8a4eb..9bd4a7aa301c6 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2488,6 +2488,8 @@ static void AddUnwindLibrary(const ToolChain &TC, const 
Driver &D,
       CmdArgs.push_back("-lunwind");
     }
     break;
+  default:
+    break;
   }
 
   if (AsNeeded)
@@ -2536,6 +2538,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 64bc96a900f30..910afc0aaafbd 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
@@ -2982,8 +2983,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
@@ -2997,8 +3001,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;
@@ -3009,7 +3019,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;
@@ -3022,10 +3032,11 @@ void AppleMachO::AddClangCXXStdlibIncludeArgs(
     break;
   }
 
-  case ToolChain::CST_Libstdcxx:
+  case ToolChain::CST_Libstdcxx: {
     AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args);
     break;
   }
+  }
 }
 
 void AppleMachO::AddGnuCPlusPlusIncludePaths(
@@ -3119,6 +3130,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 abde9fa10482d..885a587cee548 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 b58c10145e7f3..02aaf0b998d4b 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -3244,6 +3244,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 fd2ec694abb2f..7d084fb16a506 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.cpp
+++ b/clang/lib/Driver/ToolChains/Hexagon.cpp
@@ -758,6 +758,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 eb81f1b4e142c..dec2a20e6158a 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"
@@ -60,6 +61,30 @@ static std::string FindVisualStudioExecutable(const 
ToolChain &TC,
   return std::string(canExecute(TC.getVFS(), FilePath) ? FilePath.str() : Exe);
 }
 
+// Finds the highest versioned directory (lexically) in a given path.
+// If IsWinSDK is true, it filters for directories starting with "10.".
+static std::string getHighestVersion(llvm::vfs::FileSystem &VFS,
+                                     StringRef BasePath) {
+  std::string HighestVersion;
+  llvm::VersionTuple MaxVersion;
+  std::error_code EC;
+
+  for (llvm::vfs::directory_iterator LI = VFS.dir_begin(BasePath, EC), LE;
+       !EC && LI != LE; LI = LI.increment(EC)) {
+    StringRef VerText = llvm::sys::path::filename(LI->path());
+
+    llvm::VersionTuple CurrentVersion;
+    if (CurrentVersion.tryParse(VerText))
+      continue;
+
+    if (CurrentVersion > MaxVersion) {
+      MaxVersion = CurrentVersion;
+      HighestVersion = VerText.str();
+    }
+  }
+  return HighestVersion;
+}
+
 void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                         const InputInfo &Output,
                                         const InputInfoList &Inputs,
@@ -138,50 +163,110 @@ void visualstudio::Linker::ConstructJob(Compilation &C, 
const JobAction &JA,
     }
   }
 
-  // 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");
+  auto SysRoot = TC.getDriver().SysRoot;
+  if (!SysRoot.empty()) {
+
+    // --- 1. GNU-STYLE DETECTION
+    // 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));
+
+    // --- 2. MSVC-STYLE DETECTION (Only if Windows Kits exists) ---
+    auto &VFS = TC.getVFS();
+    std::string WinKitsBase = SysRoot + "/Windows Kits";
+
+    if (VFS.exists(WinKitsBase)) {
+      const char *Arch = llvm::archToWindowsSDKArch(TC.getArch());
+
+      // Windows SDK Discovery
+      std::string SDKRootVer = getHighestVersion(VFS, WinKitsBase);
+      if (!SDKRootVer.empty()) {
+        std::string SDKLibBase = WinKitsBase + "/" + SDKRootVer + "/Lib";
+
+        std::string SDKBuildVer = getHighestVersion(VFS, SDKLibBase);
+        if (!SDKBuildVer.empty()) {
+          std::string SDKLib = SDKLibBase + "/" + SDKBuildVer;
+          CmdArgs.push_back(
+              Args.MakeArgString("-libpath:" + SDKLib + "/ucrt/" + Arch));
+          CmdArgs.push_back(
+              Args.MakeArgString("-libpath:" + SDKLib + "/um/" + Arch));
+        }
+      }
 
-    // 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))
+      // MSVC Libs
+      std::string VCToolsBase = SysRoot + "/VC/Tools/MSVC";
+      std::string VCVer = getHighestVersion(VFS, VCToolsBase);
+      if (!VCVer.empty()) {
+        std::string VCLib = VCToolsBase + "/" + VCVer + "/lib/" + Arch;
+        CmdArgs.push_back(Args.MakeArgString("-libpath:" + VCLib));
+        CmdArgs.push_back(Args.MakeArgString("-libpath:" + VCLib + "/atlmfc"));
+      }
+
+      // DIA SDK
+      std::string DIALib =
+          SysRoot + "/DIA SDK/lib/" + llvm::archToLegacyVCArch(TC.getArch());
+      if (VFS.exists(DIALib))
+        CmdArgs.push_back(Args.MakeArgString("-libpath:" + DIALib));
+    }
+  } 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))
@@ -504,6 +589,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();
@@ -748,6 +839,50 @@ 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);
+
+    // --- 1. GNU-style Headers ---
+    addSystemInclude(DriverArgs, CC1Args,
+                     SysRoot + "/include/" + MultiarchTriple);
+    addSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
+
+    // 2. MSVC-style (Only if Windows Kits exists)
+    auto &VFS = getVFS();
+    std::string WinKitsBase = SysRoot + "/Windows Kits";
+
+    if (VFS.exists(WinKitsBase)) {
+      // Find SDK Root (e.g., "10" or "11")
+      std::string SDKRootVer = getHighestVersion(VFS, WinKitsBase);
+
+      if (!SDKRootVer.empty()) {
+        std::string SDKIncBase = WinKitsBase + "/" + SDKRootVer + "/Include";
+
+        // Find Specific SDK Build Version (e.g., "10.0.19041.0")
+        std::string SDKBuildVer = getHighestVersion(VFS, SDKIncBase);
+        if (!SDKBuildVer.empty()) {
+          std::string SDKPath = SDKIncBase + "/" + SDKBuildVer;
+          addSystemInclude(DriverArgs, CC1Args, SDKPath + "/ucrt");
+          addSystemInclude(DriverArgs, CC1Args, SDKPath + "/um");
+          addSystemInclude(DriverArgs, CC1Args, SDKPath + "/shared");
+        }
+      }
+
+      // VC Tools Discovery
+      std::string VCToolsBase = SysRoot + "/VC/Tools/MSVC";
+      std::string VCVer = getHighestVersion(VFS, VCToolsBase);
+      if (!VCVer.empty()) {
+        std::string VCInc = VCToolsBase + "/" + VCVer + "/include";
+        addSystemInclude(DriverArgs, CC1Args, VCInc);
+        addSystemInclude(DriverArgs, CC1Args, VCInc + "/atlmfc");
+      }
+    }
+    return;
+  }
+
   // Add %INCLUDE%-like directories from the -imsvc flag.
   for (const auto &Path : 
DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
     addSystemInclude(DriverArgs, CC1Args, Path);
@@ -891,7 +1026,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,
@@ -1144,3 +1294,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 0ec73fb59b921..e61e62c7cee99 100644
--- a/clang/lib/Driver/ToolChains/MSVC.h
+++ b/clang/lib/Driver/ToolChains/MSVC.h
@@ -140,6 +140,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 4237a6906be3b..91a50a5e18178 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;
@@ -803,22 +804,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++");
@@ -846,6 +855,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 dda00c9250a5f..55c3709c60662 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 7dabefbee7f79..ff298d2dec926 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -507,6 +507,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);
@@ -565,6 +567,9 @@ void WebAssembly::AddClangCXXStdlibIncludeArgs(const 
ArgList &DriverArgs,
   case ToolChain::CST_Libstdcxx:
     addLibStdCXXIncludePaths(DriverArgs, CC1Args);
     break;
+  case ToolChain::CST_Msstl:
+    addMsstlIncludePaths(DriverArgs, CC1Args);
+    break;
   }
 }
 
@@ -581,6 +586,8 @@ void WebAssembly::AddCXXStdlibLibArgs(const 
llvm::opt::ArgList &Args,
   case ToolChain::CST_Libstdcxx:
     CmdArgs.push_back("-lstdc++");
     break;
+  default:
+    break;
   }
 }
 
@@ -605,6 +612,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 f91987ba3883a..682c9b306a8cd 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.h
+++ b/clang/lib/Driver/ToolChains/WebAssembly.h
@@ -81,6 +81,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 da4aaa28cd1da..31591bc498ca9 100644
--- a/clang/lib/Driver/ToolChains/ZOS.cpp
+++ b/clang/lib/Driver/ToolChains/ZOS.cpp
@@ -261,6 +261,8 @@ void ZOS::AddCXXStdlibLibArgs(const llvm::opt::ArgList 
&Args,
     CmdArgs.push_back(
         Args.MakeArgString("//'" + ClangHLQ + ".SCEELIB(CRTDQUNW)'"));
   } break;
+  default:
+    break;
   }
 }
 
@@ -354,9 +356,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..7fc287fbcf716
--- /dev/null
+++ b/clang/test/Driver/msvc-sysroot.cpp
@@ -0,0 +1,128 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: split-file %s %t
+
+// --- X86_64 MSSTL ---
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -### \
+// RUN: --sysroot=%t/msvc_tree -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: "-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: "-internal-isystem" "[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Include{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt"
+// COMPILE_X86_64_MSSTL: "-internal-isystem" 
"[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}include"
+// COMPILE_X86_64_MSSTL: lld-link{{.*}}" 
"-libpath:[[SYSROOT]]/lib/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_MSSTL: "-libpath:[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Lib{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt{{/|\\\\}}x64"
+// COMPILE_X86_64_MSSTL: 
"-libpath:[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}lib{{/|\\\\}}x64"
+
+// --- X86_64 LIBCXX ---
+// RUN: %clangxx --target=x86_64-unknown-windows-msvc -stdlib=libc++ -### \
+// RUN: --sysroot=%t/msvc_tree -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: "-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: "-internal-isystem" "[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Include{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt"
+// COMPILE_X86_64_LIBCXX: "-internal-isystem" 
"[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}include"
+// COMPILE_X86_64_LIBCXX: lld-link{{.*}}" 
"-libpath:[[SYSROOT]]/lib/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_LIBCXX: "-libpath:[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Lib{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt{{/|\\\\}}x64"
+// COMPILE_X86_64_LIBCXX: 
"-libpath:[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}lib{{/|\\\\}}x64"
+
+// --- X86_64 LIBSTDCXX ---
+// RUN: %clangxx -### --target=x86_64-unknown-windows-msvc --stdlib=libstdc++ 
%s 2>&1 \
+// RUN:  -fuse-ld=lld  --sysroot=%t/msvc_tree \
+// RUN:   | FileCheck -check-prefix=COMPILE_X86_64_LIBSTDCXX %s
+// COMPILE_X86_64_LIBSTDCXX: "-cc1"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" 
"[[SYSROOT:[^"]+]]/include/c++/17.0.1/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" 
"[[SYSROOT]]/include/c++/17.0.1"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" "[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Include{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt"
+// COMPILE_X86_64_LIBSTDCXX: "-internal-isystem" 
"[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}include"
+// COMPILE_X86_64_LIBSTDCXX: lld-link{{.*}}" 
"-libpath:[[SYSROOT]]/lib/x86_64-unknown-windows-msvc"
+// COMPILE_X86_64_LIBSTDCXX: "-libpath:[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Lib{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt{{/|\\\\}}x64"
+
+// --- AARCH64 MSSTL ---
+// RUN: %clangxx --target=aarch64-unknown-windows-msvc -### \
+// RUN: --sysroot=%t/msvc_tree -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_AARCH64_MSSTL %s
+// COMPILE_AARCH64_MSSTL: clang{{.*}}" "-cc1"
+// 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: "-internal-isystem" "[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Include{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt"
+// COMPILE_AARCH64_MSSTL: "-internal-isystem" 
"[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}include"
+// COMPILE_AARCH64_MSSTL: lld-link{{.*}}" 
"-libpath:[[SYSROOT]]/lib/aarch64-unknown-windows-msvc"
+// COMPILE_AARCH64_MSSTL: "-libpath:[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Lib{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt{{/|\\\\}}arm64"
+// COMPILE_AARCH64_MSSTL: 
"-libpath:[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}lib{{/|\\\\}}arm64"
+
+// --- ARM64EC MSSTL ---
+// RUN: %clangxx --target=arm64ec-unknown-windows-msvc -### \
+// RUN: --sysroot=%t/msvc_tree -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_ARM64EC_MSSTL %s
+// COMPILE_ARM64EC_MSSTL: clang{{.*}}" "-cc1"
+// 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: "-internal-isystem" "[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Include{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt"
+// COMPILE_ARM64EC_MSSTL: "-internal-isystem" 
"[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}include"
+// COMPILE_ARM64EC_MSSTL: lld-link{{.*}}" 
"-libpath:[[SYSROOT]]/lib/arm64ec-unknown-windows-msvc" 
"-libpath:[[SYSROOT]]/lib/aarch64-unknown-windows-msvc"
+// COMPILE_ARM64EC_MSSTL: "-libpath:[[SYSROOT]]{{/|\\\\}}Windows 
Kits{{/|\\\\}}10{{/|\\\\}}Lib{{/|\\\\}}10.0.19041.0{{/|\\\\}}ucrt{{/|\\\\}}arm64"
+// COMPILE_ARM64EC_MSSTL: 
"-libpath:[[SYSROOT]]{{/|\\\\}}VC{{/|\\\\}}Tools{{/|\\\\}}MSVC{{/|\\\\}}14.29.30133{{/|\\\\}}lib{{/|\\\\}}arm64"
+
+// --- LOONGARCH64 MSSTL ---
+// RUN: %clangxx --target=loongarch64-unknown-windows-msvc -stdlib=msstl -### \
+// RUN: --sysroot=%t/msvc_tree -fuse-ld=lld %s 2>&1 \
+// RUN: | FileCheck --check-prefix=COMPILE_LOONGARCH64_MSSTL %s
+// COMPILE_LOONGARCH64_MSSTL: clang{{.*}}" "-cc1"
+// 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: "-internal-isystem" 
"[[SYSROOT]]/include/loongarch64-unknown-windows-msvc"
+// COMPILE_LOONGARCH64_MSSTL: lld-link{{.*}}" 
"-libpath:[[SYSROOT]]/lib/loongarch64-unknown-windows-msvc" 
"-libpath:[[SYSROOT]]/lib"
+
+// --- RISCV64 LIBSTDCXX ---
+// RUN: %clangxx --target=riscv64-unknown-windows-msvc -### --stdlib=libstdc++ 
%s 2>&1 \
+// RUN:  --sysroot=%t/msvc_tree -fuse-ld=link \
+// RUN:   | FileCheck -check-prefix=COMPILE_RISCV64_LIBSTDCXX_LINK %s
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-cc1"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" 
"[[SYSROOT:[^"]+]]/include/c++/17.0.1/riscv64-unknown-windows-msvc"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" 
"[[SYSROOT:[^"]+]]/include/c++/17.0.1"
+// COMPILE_RISCV64_LIBSTDCXX_LINK: "-internal-isystem" 
"[[SYSROOT:[^"]+]]/include/c++/17.0.1/backward"
+// 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"
+
+// --- Mock Directory Structure ---
+#--- msvc_tree/VC/Tools/MSVC/14.29.30133/include/string
+#--- msvc_tree/VC/Tools/MSVC/14.29.30133/lib/x64/msvcrt.lib
+#--- msvc_tree/VC/Tools/MSVC/14.29.30133/lib/arm64/msvcrt.lib
+
+#--- msvc_tree/Windows Kits/10/Include/10.0.19041.0/ucrt/assert.h
+#--- msvc_tree/Windows Kits/10/Lib/10.0.19041.0/ucrt/x64/ucrt.lib
+#--- msvc_tree/Windows Kits/10/Lib/10.0.19041.0/ucrt/arm64/ucrt.lib
+
+
+#--- msvc_tree/include/c++/msstl/string
+#--- msvc_tree/include/c++/v1/string
+#--- msvc_tree/include/c++/17.0.1/string
+#--- msvc_tree/include/x86_64-unknown-windows-msvc/c++/msstl/string
+#--- msvc_tree/include/aarch64-unknown-windows-msvc/c++/msstl/string
+#--- msvc_tree/include/loongarch64-unknown-windows-msvc/c++/msstl/string
+#--- msvc_tree/include/riscv64-unknown-windows-msvc/c++/msstl/string
+#--- msvc_tree/include/x86_64-unknown-windows-msvc/c++/v1/string
+#--- msvc_tree/include/aarch64-unknown-windows-msvc/c++/v1/string
+#--- msvc_tree/include/loongarch64-unknown-windows-msvc/c++/v1/string
+#--- msvc_tree/include/riscv64-unknown-windows-msvc/c++/v1/string
+#--- msvc_tree/include/x86_64-unknown-windows-msvc/c++/17.0.1/string
+#--- msvc_tree/include/aarch64-unknown-windows-msvc/c++/17.0.1/string
+#--- msvc_tree/include/loongarch64-unknown-windows-msvc/c++/17.0.1/string
+#--- msvc_tree/include/riscv64-unknown-windows-msvc/c++/17.0.1/string
+#--- msvc_tree/include/c++/17.0.1/x86_64-unknown-windows-msvc/string
+#--- msvc_tree/include/c++/17.0.1/aarch64-unknown-windows-msvc/string
+#--- msvc_tree/include/c++/17.0.1/loongarch64-unknown-windows-msvc/string
+#--- msvc_tree/include/c++/17.0.1/riscv64-unknown-windows-msvc/string
+
+#--- msvc_tree/include/riscv64-unknown-windows-msvc/empty
+#--- msvc_tree/lib/x86_64-unknown-windows-msvc/empty
+#--- msvc_tree/lib/aarch64-unknown-windows-msvc/empty
+#--- msvc_tree/lib/loongarch64-unknown-windows-msvc/empty
+#--- msvc_tree/lib/riscv64-unknown-windows-msvc/empty
+#--- msvc_tree/lib/empty
+
+#--- foo.cpp
+int main() { return 0; }
\ No newline at end of file
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"

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to