EricWF updated this revision to Diff 98087.
EricWF added a comment.
- Improve documentation
https://reviews.llvm.org/D32950
Files:
docs/LanguageExtensions.rst
lib/Lex/PPMacroExpansion.cpp
test/Lexer/has_extension_cxx.cpp
test/Lexer/has_feature_cxx0x.cpp
test/SemaCXX/cxx1z-extensions.cpp
Index: test/SemaCXX/cxx1z-extensions.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/cxx1z-extensions.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -std=c++11 -Wno-c++1z-extensions -Wno-c++14-extensions -verify %s
+
+// expected-no-diagnostics
+
+// Fold Expressions //
+static_assert(__has_extension(cxx_fold_expressions), "");
+template <class ...Bools>
+constexpr bool test_fold_expressions(Bools ...b) {
+ return (b && ...);
+}
+static_assert(test_fold_expressions(true, true, true), "");
+
+// If Constexpr //
+static_assert(__has_extension(cxx_if_constexpr), "");
+template <bool Pred>
+constexpr bool test_if_constexpr() {
+ if constexpr (Pred) {
+ static_assert(Pred, "");
+ return true;
+ } else {
+ static_assert(!Pred, "");
+ return false;
+ }
+}
+static_assert(test_if_constexpr<true>(), "");
+static_assert(!test_if_constexpr<false>(), "");
+
+// Inline Variables //
+static_assert(__has_extension(cxx_inline_variables), "");
+inline int test_inline_variables = 42;
+
+// Structured Bindings //
+static_assert(__has_extension(cxx_structured_bindings), "");
+struct Tuple {
+ int a, b, c;
+};
+constexpr bool test_bindings() {
+ auto [a, b, c] = Tuple{42, 101, -1};
+ return a == 42 && b == 101 && c == -1;
+}
+static_assert(test_bindings(), "");
+
+// Variadic Using //
+static_assert(__has_extension(cxx_variadic_using), "");
+struct A { constexpr bool operator()() const { return true; } };
+struct B { constexpr bool operator()(int) const { return false; } };
+template <class ...Args> struct TestVariadicUsing : Args... {
+ using Args::operator()...;
+};
+static_assert(TestVariadicUsing<A, B>{}(), "");
+static_assert(!TestVariadicUsing<A, B>{}(42), "");
Index: test/Lexer/has_feature_cxx0x.cpp
===================================================================
--- test/Lexer/has_feature_cxx0x.cpp
+++ test/Lexer/has_feature_cxx0x.cpp
@@ -479,3 +479,57 @@
// CHECK-14: has_generic_lambdas
// CHECK-11: no_generic_lambdas
// CHECK-NO-11: no_generic_lambdas
+
+#if __has_feature(cxx_fold_expressions)
+int has_fold_expressions();
+#else
+int no_fold_expressions();
+#endif
+// CHECK-1Z: has_fold_expressions
+// CHECK-14: no_fold_expressions
+// CHECK-11: no_fold_expressions
+// CHECK-NO-11: no_fold_expressions
+
+
+#if __has_feature(cxx_if_constexpr)
+int has_if_constexpr();
+#else
+int no_if_constexpr();
+#endif
+// CHECK-1Z: has_if_constexpr
+// CHECK-14: no_if_constexpr
+// CHECK-11: no_if_constexpr
+// CHECK-NO-11: no_if_constexpr
+
+
+#if __has_feature(cxx_inline_variables)
+int has_inline_variables();
+#else
+int no_inline_variables();
+#endif
+// CHECK-1Z: has_inline_variables
+// CHECK-14: no_inline_variables
+// CHECK-11: no_inline_variables
+// CHECK-NO-11: no_inline_variables
+
+
+#if __has_feature(cxx_structured_bindings)
+int has_structured_bindings();
+#else
+int no_structured_bindings();
+#endif
+// CHECK-1Z: has_structured_bindings
+// CHECK-14: no_structured_bindings
+// CHECK-11: no_structured_bindings
+// CHECK-NO-11: no_structured_bindings
+
+
+#if __has_feature(cxx_variadic_using)
+int has_variadic_using();
+#else
+int no_variadic_using();
+#endif
+// CHECK-1Z: has_variadic_using
+// CHECK-14: no_variadic_using
+// CHECK-11: no_variadic_using
+// CHECK-NO-11: no_variadic_using
Index: test/Lexer/has_extension_cxx.cpp
===================================================================
--- test/Lexer/has_extension_cxx.cpp
+++ test/Lexer/has_extension_cxx.cpp
@@ -66,3 +66,33 @@
#if __has_extension(cxx_init_captures)
int has_init_captures();
#endif
+
+// CHECK-NOT: has_fold_expressions
+// CHECK11: has_fold_expressions
+#if __has_extension(cxx_fold_expressions)
+int has_fold_expressions();
+#endif
+
+// CHECK-NOT: has_if_constexpr
+// CHECK11: has_if_constexpr
+#if __has_extension(cxx_if_constexpr)
+int has_if_constexpr();
+#endif
+
+// CHECK-NOT: has_inline_variables
+// CHECK11: has_inline_variables
+#if __has_extension(cxx_inline_variables)
+int has_inline_variables();
+#endif
+
+// CHECK-NOT: has_structured_bindings
+// CHECK11: has_structured_bindings
+#if __has_extension(cxx_structured_bindings)
+int has_structured_bindings();
+#endif
+
+// CHECK-NOT: has_variadic_using
+// CHECK11: has_variadic_using
+#if __has_extension(cxx_variadic_using)
+int has_variadic_using();
+#endif
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -1224,8 +1224,15 @@
.Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14)
.Case("cxx_return_type_deduction", LangOpts.CPlusPlus14)
.Case("cxx_variable_templates", LangOpts.CPlusPlus14)
+ // C++17 features
+ .Case("cxx_fold_expressions", LangOpts.CPlusPlus1z)
+ .Case("cxx_if_constexpr", LangOpts.CPlusPlus1z)
+ .Case("cxx_inline_variables", LangOpts.CPlusPlus1z)
+ .Case("cxx_structured_bindings", LangOpts.CPlusPlus1z)
+ .Case("cxx_variadic_using", LangOpts.CPlusPlus1z)
// NOTE: For features covered by SD-6, it is preferable to provide *only*
- // the SD-6 macro and not a __has_feature check.
+ // the SD-6 macro and not a __has_feature check unless the feature is
+ // also provided as an extension in older dialects.
// C++ TSes
//.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
@@ -1314,6 +1321,12 @@
.Case("cxx_binary_literals", true)
.Case("cxx_init_captures", LangOpts.CPlusPlus11)
.Case("cxx_variable_templates", LangOpts.CPlusPlus)
+ // C++17 features supported by other languages as extensions.
+ .Case("cxx_fold_expressions", LangOpts.CPlusPlus11)
+ .Case("cxx_if_constexpr", LangOpts.CPlusPlus11)
+ .Case("cxx_inline_variables", LangOpts.CPlusPlus11)
+ .Case("cxx_structured_bindings", LangOpts.CPlusPlus11)
+ .Case("cxx_variadic_using", LangOpts.CPlusPlus11)
.Default(false);
}
Index: docs/LanguageExtensions.rst
===================================================================
--- docs/LanguageExtensions.rst
+++ docs/LanguageExtensions.rst
@@ -873,6 +873,57 @@
``__has_extension(cxx_variable_templates)`` to determine if support for
templated variable declarations is enabled.
+C++1z
+-----
+
+C++1z fold expressions
+^^^^^^^^^^^^^^^^^^^^^^
+
+Use ``__has_feature(cxx_fold_expressions)`` or
+``__has_extension(cxx_fold_expressions)`` to determine if support for
+fold expressions is enabled. For instance:
+
+.. code-block:: c++
+
+ template <class ...Bools>
+ bool variadic_and(Bools... b) { return (b && ...); }
+
+C++1z if constexpr
+^^^^^^^^^^^^^^^^^^
+
+Use ``__has_feature(cxx_if_constexpr)`` or
+``__has_extension(cxx_if_constexpr)`` to determine if support for
+``if constexpr`` is enabled.
+
+C++1z inline variables
+^^^^^^^^^^^^^^^^^^^^^^
+
+Use ``__has_feature(cxx_inline_variables)`` or
+``__has_extension(cxx_inline_variables)`` to determine if support for
+inline variables is enabled. (For instance, ``inline int x = 42;``)
+
+C++1z structured bindings
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Use ``__has_feature(cxx_structured_bindings)`` or
+``__has_extension(cxx_structured_bindings)`` to determine if support for
+structured bindings is enabled. (For instance,
+``auto [a, b, c] = std::make_tuple(1, 2, 3);``)
+
+C++1z variadic using
+^^^^^^^^^^^^^^^^^^^^
+
+Use ``__has_feature(cxx_variadic_using)`` or
+``__has_extension(cxx_variadic_using)`` to determine if support for
+pack expansions of using-declarations is enabled. For instance:
+
+.. code-block:: c++
+
+ template <class ...Bases> struct T : Bases... {
+ using Bases::operator()...;
+ }
+
+
C11
---
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits