diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -1761,6 +1761,10 @@ .. option:: -fexec-charset= +.. option:: -fexperimental-library, -fno-experimental-library + +Control whether unstable and experimental library features are enabled. This option enables various library features that are either experimental (also known as TSes), or have been but are not stable yet in the selected Standard Library implementation. It is not recommended to use this option in production code, since neither ABI nor API stability are guaranteed. This is intended to provide a preview of features that will ship in the future for experimentation purposes + .. option:: -fexperimental-new-constant-interpreter Enable the experimental new constant interpreter @@ -2637,10 +2641,6 @@ .. option:: -funsigned-char, -fno-unsigned-char, --unsigned-char -.. option:: -funstable, -fno-unstable - -Enable unstable and experimental features - .. option:: -funwind-tables, -fno-unwind-tables .. option:: -fuse-cxa-atexit, -fno-use-cxa-atexit diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -179,7 +179,6 @@ FEATURE(cxx_trailing_return, LangOpts.CPlusPlus11) FEATURE(cxx_unicode_literals, LangOpts.CPlusPlus11) FEATURE(cxx_unrestricted_unions, LangOpts.CPlusPlus11) -FEATURE(cxx_unstable, LangOpts.Unstable) FEATURE(cxx_user_literals, LangOpts.CPlusPlus11) FEATURE(cxx_variadic_templates, LangOpts.CPlusPlus11) // C++14 features @@ -235,6 +234,7 @@ LangOpts.Sanitize.has(SanitizerKind::ShadowCallStack)) FEATURE(tls, PP.getTargetInfo().isTLSSupported()) FEATURE(underlying_type, LangOpts.CPlusPlus) +FEATURE(experimental_library, LangOpts.ExperimentalLibrary) // C11 features supported by other languages as extensions. EXTENSION(c_alignas, true) diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -155,7 +155,7 @@ LANGOPT(Coroutines , 1, 0, "C++20 coroutines") LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods") LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments") -LANGOPT(Unstable , 1, 0, "Enable unstable and experimental features") +LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features") LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1189,9 +1189,13 @@ PosFlag, NegFlag>; -defm unstable : BoolFOption<"unstable", - LangOpts<"Unstable">, DefaultFalse, - PosFlag, +defm experimental_library : BoolFOption<"experimental-library", + LangOpts<"ExperimentalLibrary">, DefaultFalse, + PosFlag, NegFlag>; def fembed_offload_object_EQ : Joined<["-"], "fembed-offload-object=">, diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1013,6 +1013,8 @@ switch (Type) { case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -275,6 +275,8 @@ llvm::report_fatal_error("linking libstdc++ unimplemented on AIX"); case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); CmdArgs.push_back("-lc++abi"); return; } diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -276,6 +276,8 @@ switch (GetCXXStdlibType(Args)) { case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); CmdArgs.push_back("-lc++abi"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5858,12 +5858,7 @@ CmdArgs.push_back(A->getValue()); } - if (Args.hasArg(options::OPT_funstable)) { - CmdArgs.push_back("-funstable"); - if (!Args.hasArg(options::OPT_fno_coroutines_ts)) - CmdArgs.push_back("-fcoroutines-ts"); - CmdArgs.push_back("-fmodules-ts"); - } + Args.AddLastArg(CmdArgs, options::OPT_fexperimental_library); if (Args.hasArg(options::OPT_fexperimental_new_constant_interpreter)) CmdArgs.push_back("-fexperimental-new-constant-interpreter"); diff --git a/clang/lib/Driver/ToolChains/CloudABI.cpp b/clang/lib/Driver/ToolChains/CloudABI.cpp --- a/clang/lib/Driver/ToolChains/CloudABI.cpp +++ b/clang/lib/Driver/ToolChains/CloudABI.cpp @@ -117,6 +117,8 @@ void CloudABI::AddCXXStdlibLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); CmdArgs.push_back("-lc++abi"); CmdArgs.push_back("-lunwind"); } diff --git a/clang/lib/Driver/ToolChains/CrossWindows.cpp b/clang/lib/Driver/ToolChains/CrossWindows.cpp --- a/clang/lib/Driver/ToolChains/CrossWindows.cpp +++ b/clang/lib/Driver/ToolChains/CrossWindows.cpp @@ -273,8 +273,11 @@ void CrossWindowsToolChain:: AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const { - if (GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) + if (GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) { CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); + } } clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const { diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -2448,6 +2448,7 @@ break; } } + void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { CXXStdlibType Type = GetCXXStdlibType(Args); @@ -2455,6 +2456,8 @@ switch (Type) { case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -430,6 +430,8 @@ switch (Type) { case ToolChain::CST_Libcxx: CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -417,6 +417,8 @@ switch (GetCXXStdlibType(Args)) { case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -616,6 +616,8 @@ CmdArgs.push_back("-lc++"); CmdArgs.push_back("-lc++abi"); CmdArgs.push_back("-lunwind"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/lib/Driver/ToolChains/MipsLinux.cpp b/clang/lib/Driver/ToolChains/MipsLinux.cpp --- a/clang/lib/Driver/ToolChains/MipsLinux.cpp +++ b/clang/lib/Driver/ToolChains/MipsLinux.cpp @@ -112,6 +112,8 @@ "Only -lc++ (aka libxx) is supported in this toolchain."); CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); CmdArgs.push_back("-lc++abi"); CmdArgs.push_back("-lunwind"); } diff --git a/clang/lib/Driver/ToolChains/NaCl.cpp b/clang/lib/Driver/ToolChains/NaCl.cpp --- a/clang/lib/Driver/ToolChains/NaCl.cpp +++ b/clang/lib/Driver/ToolChains/NaCl.cpp @@ -308,6 +308,8 @@ // if the value is libc++, and emits an error for other values. GetCXXStdlibType(Args); CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); } void NaClToolChain::addLibCxxIncludePaths( diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp --- a/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -331,6 +331,8 @@ bool Profiling = Args.hasArg(options::OPT_pg); CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi"); CmdArgs.push_back(Profiling ? "-lpthread_p" : "-lpthread"); } diff --git a/clang/lib/Driver/ToolChains/VEToolchain.cpp b/clang/lib/Driver/ToolChains/VEToolchain.cpp --- a/clang/lib/Driver/ToolChains/VEToolchain.cpp +++ b/clang/lib/Driver/ToolChains/VEToolchain.cpp @@ -141,6 +141,8 @@ tools::addArchSpecificRPath(*this, Args, CmdArgs); CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); CmdArgs.push_back("-lc++abi"); CmdArgs.push_back("-lunwind"); // libc++ requires -lpthread under glibc environment diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -444,6 +444,8 @@ switch (GetCXXStdlibType(Args)) { case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); CmdArgs.push_back("-lc++abi"); break; case ToolChain::CST_Libstdcxx: diff --git a/clang/test/Driver/experimental-library-flag.cpp b/clang/test/Driver/experimental-library-flag.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/experimental-library-flag.cpp @@ -0,0 +1,15 @@ +// On Windows, -stdlib=libc++ is currently ignored, so -lc++experimental is not added. +// Once -stdlib=libc++ works on Windows, this XFAIL can be removed. +// XFAIL: windows + +// RUN: %clangxx -fexperimental-library -stdlib=libc++ -### %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-LIBCXX %s +// RUN: %clangxx -fexperimental-library -stdlib=libstdc++ -### %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-LIBSTDCXX %s +// RUN: %clangxx -fexperimental-library -stdlib=libc++ -nostdlib++ -### %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-NOSTDLIB %s + +// -fexperimental-library must be passed to CC1. +// CHECK: -fexperimental-library + +// Depending on the stdlib in use, we should (or not) pass -lc++experimental. +// CHECK-LIBCXX: -lc++experimental +// CHECK-LIBSTDCXX-NOT: -lc++experimental +// CHECK-NOSTDLIB-NOT: -lc++experimental diff --git a/clang/test/Driver/unstable-flag.cpp b/clang/test/Driver/unstable-flag.cpp deleted file mode 100644 --- a/clang/test/Driver/unstable-flag.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %clang -funstable -### %s 2>&1 | FileCheck %s - -// CHECK: -funstable -// CHECK: -fcoroutines-ts -// CHECK: -fmodules-ts diff --git a/clang/test/Lexer/has_feature_cxx_unstable.cpp b/clang/test/Lexer/has_feature_cxx_unstable.cpp deleted file mode 100644 --- a/clang/test/Lexer/has_feature_cxx_unstable.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -funstable -E %s -o - | FileCheck --check-prefix=CHECK-UNSTABLE %s -// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-UNSTABLE %s - -#if __has_feature(cxx_unstable) -int has_cxx_unstable(); -#else -int has_no_cxx_unstable(); -#endif -// CHECK-UNSTABLE: int has_cxx_unstable(); -// CHECK-NO-UNSTABLE: int has_no_cxx_unstable(); diff --git a/clang/test/Lexer/has_feature_experimental_library.cpp b/clang/test/Lexer/has_feature_experimental_library.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Lexer/has_feature_experimental_library.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -E -fexperimental-library %s -o - | FileCheck --check-prefix=CHECK-EXPERIMENTAL %s +// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-EXPERIMENTAL %s + +#if __has_feature(experimental_library) +int has_experimental_library(); +#else +int has_no_experimental_library(); +#endif +// CHECK-EXPERIMENTAL: int has_experimental_library(); +// CHECK-NO-EXPERIMENTAL: int has_no_experimental_library();