Index: clang/lib/Driver/ToolChains/WebAssembly.cpp =================================================================== --- clang/lib/Driver/ToolChains/WebAssembly.cpp +++ clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -371,7 +371,11 @@ WebAssembly::GetCXXStdlibType(const ArgList &Args) const { if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) { StringRef Value = A->getValue(); - if (Value != "libc++") + if (Value == "libc++") + return ToolChain::CST_Libcxx; + else if (Value == "libstdc++") + return ToolChain::CST_Libstdcxx; + else getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); } @@ -417,17 +421,34 @@ void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - if (!DriverArgs.hasArg(options::OPT_nostdlibinc) && - !DriverArgs.hasArg(options::OPT_nostdincxx)) { - if (getTriple().getOS() != llvm::Triple::UnknownOS) { - const std::string MultiarchTriple = - getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot); + + if (DriverArgs.hasArg(options::OPT_nostdlibinc) || + DriverArgs.hasArg(options::OPT_nostdincxx)) + return; + + bool IsKnownOs = (getTriple().getOS() != llvm::Triple::UnknownOS); + const std::string MultiarchTriple = + getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot); + + switch (GetCXXStdlibType(DriverArgs)) { + case ToolChain::CST_Libcxx: + if (IsKnownOs) addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include/" + MultiarchTriple + "/c++/v1"); - } addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include/c++/v1"); + break; + case ToolChain::CST_Libstdcxx: + if (IsKnownOs) + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/include/" + MultiarchTriple + + "/c++/11"); + addSystemInclude(DriverArgs, CC1Args, + getDriver().SysRoot + "/include/c++/11"); + break; + default: + assert(false); } } @@ -440,6 +461,9 @@ CmdArgs.push_back("-lc++abi"); break; case ToolChain::CST_Libstdcxx: + CmdArgs.push_back("-lstdc++"); + break; + default: llvm_unreachable("invalid stdlib name"); } } Index: clang/test/Driver/wasm-toolchain.cpp =================================================================== --- clang/test/Driver/wasm-toolchain.cpp +++ clang/test/Driver/wasm-toolchain.cpp @@ -19,6 +19,11 @@ // LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo --stdlib=libstdc++ %s 2>&1 \ +// RUN: | FileCheck -check-prefix=LINK_STDCXX %s +// LINK_STDCXX: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" +// LINK_STDCXX: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" + // A basic C++ link command-line with optimization with unknown OS. // RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ 2>&1 \ @@ -26,6 +31,11 @@ // LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=libstdc++ 2>&1 \ +// RUN: | FileCheck -check-prefix=LINK_OPT_STDCXX %s +// LINK_OPT_STDCXX: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" +// LINK_OPT_STDCXX: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" + // A basic C++ link command-line with known OS. // RUN: %clangxx -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo --stdlib=c++ %s 2>&1 \ @@ -33,6 +43,11 @@ // LINK_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo --stdlib=libstdc++ %s 2>&1 \ +// RUN: | FileCheck -check-prefix=LINK_KNOWN_STDCXX %s +// LINK_KNOWN_STDCXX: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" +// LINK_KNOWN_STDCXX: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" + // A basic C++ link command-line with optimization with known OS. // RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo %s --stdlib=c++ 2>&1 \ @@ -40,6 +55,11 @@ // LINK_OPT_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" // LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo %s --stdlib=libstdc++ 2>&1 \ +// RUN: | FileCheck -check-prefix=LINK_OPT_KNOWN_STDCXX %s +// LINK_OPT_KNOWN_STDCXX: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" +// LINK_OPT_KNOWN_STDCXX: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lstdc++" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" + // A basic C++ compile command-line with known OS. // RUN: %clangxx -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo --stdlib=c++ %s 2>&1 \ @@ -52,3 +72,14 @@ // COMPILE: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" // COMPILE: "-internal-isystem" "/foo/include/wasm32-wasi" // COMPILE: "-internal-isystem" "/foo/include" + +// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo --stdlib=libstdc++ %s 2>&1 \ +// RUN: | FileCheck -check-prefix=COMPILE_STDCXX %s +// COMPILE_STDCXX: clang{{.*}}" "-cc1" +// COMPILE_STDCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]*]]" +// COMPILE_STDCXX: "-isysroot" "/foo" +// COMPILE_STDCXX: "-internal-isystem" "/foo/include/wasm32-wasi/c++/11" +// COMPILE_STDCXX: "-internal-isystem" "/foo/include/c++/11" +// COMPILE_STDCXX: "-internal-isystem" "[[RESOURCE_DIR]]{{(/|\\\\)}}include" +// COMPILE_STDCXX: "-internal-isystem" "/foo/include/wasm32-wasi" +// COMPILE_STDCXX: "-internal-isystem" "/foo/include"