From: Sean Hunt
Date: Wed, 13 Jan 2010 08:31:49 +0000 (+0000)
Subject: Add a bunch more feature-checking macros for C++0x features. Some of these are
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ef4c6b232121dd611fc4ff9711052aaace635a3;p=clang
Add a bunch more feature-checking macros for C++0x features. Some of these are
disabled with the intent that users can start with them now and not have to change
a thing to have them work when we implement the features.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93312 91177308-0d34-0410-b5e6-96231b3b80d8
---
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index 414d9c89e5..4648b271af 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -28,6 +28,19 @@ td {
C++ exceptions
C++ RTTI
+Checks for Upcoming Standard Language Features
+
Blocks
Function Overloading in C
Builtin Functions
@@ -215,6 +228,70 @@ example, compiling code with -fexceptions enables C++ exceptions.
Use __has_feature(cxx_rtti) to determine if C++ RTTI has been enabled. For example,
compiling code with -fno-rtti disables the use of RTTI.
+
+Checks for Upcoming Standard Language Features
+
+
+The __has_feature macro can be used to query if certain upcoming
+standard language features are enabled. Those features are listed here.
+
+Currently, all features listed here are slated for inclusion in the upcoming
+C++0x standard. As a result, all the features that clang supports are enabled
+with the -std=c++0x option when compiling C++ code. Features that are
+not yet implemented will be noted.
+
+C++0x decltype()
+
+Use __has_feature(cxx_decltype) to determine if support for the
+decltype() specifier is enabled.
+
+C++0x attributes
+
+Use __has_feature(cxx_attributes) to determine if support for
+attribute parsing with C++0x's square bracket notation is enabled.
+
+
C++0x deleted functions
+
+Use __has_feature(cxx_deleted_functions) to determine if support for
+deleted function definitions (with = delete) is enabled.
+
+
C++ TR concepts
+
+Use __has_feature(cxx_lambdas) to determine if support for
+concepts is enabled. clang does not currently implement this feature.
+
+
C++0x nullptr
+
+Use __has_feature(cxx_lambdas) to determine if support for
+lambdas is enabled. clang does not currently implement this feature.
+
+
C++0x nullptr
+
+Use __has_feature(cxx_nullptr) to determine if support for
+nullptr is enabled. clang does not yet fully implement this feature.
+
+
C++0x rvalue references
+
+Use __has_feature(cxx_rvalue_references) to determine if support for
+rvalue references is enabled. clang does not yet fully implement this feature.
+
+
C++0x static_assert()
+
+Use __has_feature(cxx_static_assert) to determine if support for
+compile-time assertions using static_assert is enabled.
+
+C++0x type inference
+
+Use __has_feature(cxx_auto_type) to determine C++0x type inference
+is supported using the auto specifier. If this is disabled,
+auto will instead be a storage class specifier, as in C or C++98.
+
+C++0x variadic templates
+
+Use __has_feature(cxx_variadic_templates) to determine if support
+for templates taking any number of arguments with the ellipsis notation is
+enabled. clang does not yet fully implement this feature.
+
Blocks
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index ba7be5c648..37927827a8 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -485,9 +485,19 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
return llvm::StringSwitch(II->getName())
.Case("blocks", LangOpts.Blocks)
.Case("cxx_rtti", LangOpts.RTTI)
+ //.Case("cxx_lambdas", false)
+ //.Case("cxx_nullptr", false)
+ //.Case("cxx_concepts", false)
+ .Case("cxx_decltype", LangOpts.CPlusPlus0x)
+ .Case("cxx_auto_type", LangOpts.CPlusPlus0x)
.Case("cxx_exceptions", LangOpts.Exceptions)
+ .Case("cxx_attributes", LangOpts.CPlusPlus0x)
+ .Case("cxx_static_assert", LangOpts.CPlusPlus0x)
.Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI)
+ .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x)
+ //.Case("cxx_rvalue_references", false)
.Case("attribute_overloadable", true)
+ //.Case("cxx_variadic_templates", false)
.Case("attribute_ext_vector_type", true)
.Case("attribute_analyzer_noreturn", true)
.Case("attribute_ns_returns_retained", true)
diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp
new file mode 100644
index 0000000000..e83a37bf43
--- /dev/null
+++ b/test/Lexer/has_feature_cxx0x.cpp
@@ -0,0 +1,101 @@
+// RUN: %clang -E -std=c++0x %s -o - | FileCheck --check-prefix=CHECK-0X %s
+// RUN: %clang -E %s -o - | FileCheck --check-prefix=CHECK-NO-0X %s
+
+#if __has_feature(cxx_lambdas)
+int lambdas();
+#else
+int no_lambdas();
+#endif
+
+// CHECK-0X: no_lambdas
+// CHECK-NO-0X: no_lambdas
+
+
+#if __has_feature(cxx_nullptr)
+int nullptr();
+#else
+int no_nullptr();
+#endif
+
+// CHECK-0X: no_nullptr
+// CHECK-NO-0X: no_nullptr
+
+
+#if __has_feature(cxx_concepts)
+int concepts();
+#else
+int no_concepts();
+#endif
+
+// CHECK-0X: no_concepts
+// CHECK-NO-0X: no_concepts
+
+
+#if __has_feature(cxx_decltype)
+int decltype();
+#else
+int no_decltype();
+#endif
+
+// CHECK-0X: decltype
+// CHECK-NO-0X: no_decltype
+
+
+#if __has_feature(cxx_auto_type)
+int auto_type();
+#else
+int no_auto_type();
+#endif
+
+// CHECK-0X: auto_type
+// CHECK-NO-0X: no_auto_type
+
+
+#if __has_feature(cxx_attributes)
+int attributes();
+#else
+int no_attributes();
+#endif
+
+// CHECK-0X: attributes
+// CHECK-NO-0X: no_attributes
+
+
+#if __has_feature(cxx_static_assert)
+int static_assert();
+#else
+int no_static_assert();
+#endif
+
+// CHECK-0X: static_assert
+// CHECK-NO-0X: no_static_assert
+
+
+#if __has_feature(cxx_deleted_functions)
+int deleted_functions();
+#else
+int no_deleted_functions();
+#endif
+
+// CHECK-0X: deleted_functions
+// CHECK-NO-0X: no_deleted_functions
+
+
+#if __has_feature(cxx_rvalue_references)
+int rvalue_references();
+#else
+int no_rvalue_references();
+#endif
+
+// CHECK-0X: no_rvalue_references
+// CHECK-NO-0X: no_rvalue_references
+
+
+#if __has_feature(cxx_variadic_templates)
+int variadic_templates();
+#else
+int no_variadic_templates();
+#endif
+
+// CHECK-0X: no_variadic_templates
+// CHECK-NO-0X: no_variadic_templates