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 @@ -2633,10 +2637,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 @@ -1183,9 +1183,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 @@ -276,6 +276,8 @@ case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); CmdArgs.push_back("-lc++abi"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); 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 @@ -277,6 +277,8 @@ case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); CmdArgs.push_back("-lc++abi"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); break; case ToolChain::CST_Libstdcxx: CmdArgs.push_back("-lstdc++"); 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 @@ -5837,12 +5837,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 @@ -119,6 +119,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"); } Tool *CloudABI::buildLinker() const { 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 @@ -114,6 +114,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"); } std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, 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 @@ -333,6 +333,8 @@ CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++"); CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi"); CmdArgs.push_back(Profiling ? "-lpthread_p" : "-lpthread"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); } std::string OpenBSD::getCompilerRT(const ArgList &Args, StringRef Component, 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 @@ -147,6 +147,9 @@ CmdArgs.push_back("-lpthread"); // libunwind requires -ldl under glibc environment CmdArgs.push_back("-ldl"); + + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); } llvm::ExceptionHandling 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 @@ -445,6 +445,8 @@ case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); CmdArgs.push_back("-lc++abi"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); break; case ToolChain::CST_Libstdcxx: CmdArgs.push_back("-lstdc++"); 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,11 @@ +// 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();