[cfe-commits] r131308 - in /cfe/trunk: docs/LanguageExtensions.html include/clang/Basic/Diagnostic.h include/clang/Lex/Preprocessor.h lib/Lex/PPMacroExpansion.cpp test/Lexer/has_extension.c test/Lexer/has_extension_cxx.cpp test/Lexer/has_feature_c1x.c
Peter Collingbourne
peter at pcc.me.uk
Fri May 13 13:54:45 PDT 2011
Author: pcc
Date: Fri May 13 15:54:45 2011
New Revision: 131308
URL: http://llvm.org/viewvc/llvm-project?rev=131308&view=rev
Log:
Introduce __has_extension macro
__has_extension is a function-like macro which takes the same set
of feature identifiers as __has_feature. It evaluates to 1 if the
feature is supported by Clang in the current language (either as a
language extension or a standard language feature) or 0 if not.
At the same time, add support for the C1X feature identifiers
c_generic_selections (renamed from generic_selections) and
c_static_assert, and document them.
Patch by myself and Jean-Daniel Dupas.
Added:
cfe/trunk/test/Lexer/has_extension.c
cfe/trunk/test/Lexer/has_extension_cxx.cpp
cfe/trunk/test/Lexer/has_feature_c1x.c
Modified:
cfe/trunk/docs/LanguageExtensions.html
cfe/trunk/include/clang/Basic/Diagnostic.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
Modified: cfe/trunk/docs/LanguageExtensions.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.html?rev=131308&r1=131307&r2=131308&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.html (original)
+++ cfe/trunk/docs/LanguageExtensions.html Fri May 13 15:54:45 2011
@@ -32,30 +32,37 @@
</ul>
<li><a href="#checking_upcoming_features">Checks for Upcoming Standard Language Features</a></li>
<ul>
- <li><a href="#cxx_access_control_sfinae">C++0x SFINAE includes access control</a></li>
- <li><a href="#cxx_alias_templates">C++0x alias templates</a></li>
- <li><a href="#cxx_attributes">C++0x attributes</a></li>
- <li><a href="#cxx_decltype">C++0x <tt>decltype()</tt></a></li>
- <li><a href="#cxx_default_function_template_args">C++0x default template arguments in function templates</a></li>
- <li><a href="#cxx_deleted_functions">C++0x deleted functions</a></li>
- <li><a href="#cxx_lambdas">C++0x lambdas</a></li>
- <li><a href="#cxx_nullptr">C++0x nullptr</a></li>
- <li><a href="#cxx_override_control">C++0x override control</a></li>
- <li><a href="#cxx_range_for">C++0x range-based for loop</a></li>
- <li><a href="#cxx_rvalue_references">C++0x rvalue references</a></li>
- <li><a href="#cxx_reference_qualified_functions">C++0x reference-qualified functions</a></li>
- <li><a href="#cxx_static_assert">C++0x <tt>static_assert()</tt></a></li>
- <li><a href="#cxx_auto_type">C++0x type inference</a></li>
- <li><a href="#cxx_variadic_templates">C++0x variadic templates</a></li>
- <li><a href="#cxx_inline_namespaces">C++0x inline namespaces</a></li>
- <li><a href="#cxx_strong_enums">C++0x strongly-typed enumerations</a></li>
- <li><a href="#cxx_trailing_return">C++0x trailing return type</a></li>
- <li><a href="#cxx_noexcept">C++0x noexcept specification</a></li>
+ <li><a href="#cxx0x">C++0x</a>
+ <ul>
+ <li><a href="#cxx_decltype">C++0x <tt>decltype()</tt></a></li>
+ <li><a href="#cxx_access_control_sfinae">C++0x SFINAE includes access control</a></li>
+ <li><a href="#cxx_alias_templates">C++0x alias templates</a></li>
+ <li><a href="#cxx_attributes">C++0x attributes</a></li>
+ <li><a href="#cxx_default_function_template_args">C++0x default template arguments in function templates</a></li>
+ <li><a href="#cxx_deleted_functions">C++0x deleted functions</a></li>
+ <li><a href="#cxx_lambdas">C++0x lambdas</a></li>
+ <li><a href="#cxx_nullptr">C++0x nullptr</a></li>
+ <li><a href="#cxx_override_control">C++0x override control</a></li>
+ <li><a href="#cxx_range_for">C++0x range-based for loop</a></li>
+ <li><a href="#cxx_rvalue_references">C++0x rvalue references</a></li>
+ <li><a href="#cxx_reference_qualified_functions">C++0x reference-qualified functions</a></li>
+ <li><a href="#cxx_static_assert">C++0x <tt>static_assert()</tt></a></li>
+ <li><a href="#cxx_auto_type">C++0x type inference</a></li>
+ <li><a href="#cxx_variadic_templates">C++0x variadic templates</a></li>
+ <li><a href="#cxx_inline_namespaces">C++0x inline namespaces</a></li>
+ <li><a href="#cxx_strong_enums">C++0x strongly-typed enumerations</a></li>
+ <li><a href="#cxx_trailing_return">C++0x trailing return type</a></li>
+ <li><a href="#cxx_noexcept">C++0x noexcept specification</a></li>
+ </ul>
+ <li><a href="#c1x">C1X</a>
+ <ul>
+ <li><a href="#c_generic_selections">C1X generic selections</a></li>
+ <li><a href="#c_static_assert">C1X <tt>_Static_assert()</tt></a></li>
+ </ul>
</ul>
<li><a href="#checking_type_traits">Checks for Type Traits</a></li>
<li><a href="#blocks">Blocks</a></li>
<li><a href="#overloading-in-c">Function Overloading in C</a></li>
-<li><a href="#generic-selections">Generic Selections</a></li>
<li><a href="#builtins">Builtin Functions</a>
<ul>
<li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li>
@@ -117,28 +124,48 @@
<!-- ======================================================================= -->
-<h3 id="__has_feature">__has_feature</h3>
+<h3 id="__has_feature_extension">__has_feature and __has_extension</h3>
<!-- ======================================================================= -->
-<p>This function-like macro takes a single identifier argument that is the name
-of a feature. It evaluates to 1 if the feature is supported or 0 if not. It
-can be used like this:</p>
+<p>These function-like macros take a single identifier argument that is the
+name of a feature. <code>__has_feature</code> evaluates to 1 if the feature
+is both supported by Clang and standardized in the current language standard
+or 0 if not (but see <a href="#has_feature_back_compat">below</a>), while
+<code>__has_extension</code> evaluates to 1 if the feature is supported by
+Clang in the current language (either as a language extension or a standard
+language feature) or 0 if not. They can be used like this:</p>
<blockquote>
<pre>
#ifndef __has_feature // Optional of course.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
+#ifndef __has_extension
+ #define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
+#endif
...
-#if __has_feature(attribute_overloadable) || \
- __has_feature(blocks)
-...
+#if __has_feature(cxx_rvalue_references)
+// This code will only be compiled with the -std=c++0x and -std=gnu++0x
+// options, because rvalue references are only standardized in C++0x.
+#endif
+
+#if __has_extension(cxx_rvalue_references)
+// This code will be compiled with the -std=c++0x, -std=gnu++0x, -std=c++98
+// and -std=gnu++98 options, because rvalue references are supported as a
+// language extension in C++98.
#endif
-...
</pre>
</blockquote>
+<p id="has_feature_back_compat">For backwards compatibility reasons,
+<code>__has_feature</code> can also be used to test for support for
+non-standardized features, i.e. features not prefixed <code>c_</code>,
+<code>cxx_</code> or <code>objc_</code>.</p>
+
+<p>If the <code>-pedantic-errors</code> option is given,
+<code>__has_extension</code> is equivalent to <code>__has_feature</code>.</p>
+
<p>The feature tag is described along with the language feature below.</p>
<!-- ======================================================================= -->
@@ -295,7 +322,7 @@
</pre>
</blockquote>
-<p>Query for this feature with __has_feature(attribute_ext_vector_type).</p>
+<p>Query for this feature with __has_extension(attribute_ext_vector_type).</p>
<p>See also <a href="#__builtin_shufflevector">__builtin_shufflevector</a>.</p>
@@ -320,8 +347,8 @@
</blockquote>
<p>Query for this feature
-with <tt>__has_feature(attribute_deprecated_with_message)</tt>
-and <tt>__has_feature(attribute_unavailable_with_message)</tt>.</p>
+with <tt>__has_extension(attribute_deprecated_with_message)</tt>
+and <tt>__has_extension(attribute_unavailable_with_message)</tt>.</p>
<!-- ======================================================================= -->
<h2 id="attributes-on-enumerators">Attributes on Enumerators</h2>
@@ -344,7 +371,7 @@
<p>Attributes on the <tt>enum</tt> declaration do not apply to
individual enumerators.</p>
-<p>Query for this feature with <tt>__has_feature(enumerator_attributes)</tt>.</p>
+<p>Query for this feature with <tt>__has_extension(enumerator_attributes)</tt>.</p>
<!-- ======================================================================= -->
<h2 id="checking_language_features">Checks for Standard Language Features</h2>
@@ -367,115 +394,166 @@
<h2 id="checking_upcoming_features">Checks for Upcoming Standard Language Features</h2>
<!-- ======================================================================= -->
-<p>The <tt>__has_feature</tt> macro can be used to query if certain upcoming
-standard language features are enabled. Those features are listed here.</p>
+<p>The <tt>__has_feature</tt> or <tt>__has_extension</tt> macros can be used
+to query if certain upcoming standard language features are enabled. Those
+features are listed here. Features that are not yet implemented will be
+noted.</p>
+
+<h3 id="cxx0x">C++0x</h3>
-<p>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 <tt>-std=c++0x</tt> option when compiling C++ code. Features that are
-not yet implemented will be noted.</p>
+<p>The features listed below are slated for inclusion in the upcoming
+C++0x standard. As a result, all these features are enabled
+with the <tt>-std=c++0x</tt> option when compiling C++ code.</p>
-<h3 id="cxx_decltype">C++0x <tt>decltype()</tt></h3>
+<h4 id="cxx_decltype">C++0x <tt>decltype()</tt></h3>
-<p>Use <tt>__has_feature(cxx_decltype)</tt> to determine if support for the
+<p>Use <tt>__has_feature(cxx_decltype)</tt> or
+<tt>__has_extension(cxx_decltype)</tt> to determine if support for the
<tt>decltype()</tt> specifier is enabled.</p>
-<h3 id="cxx_access_control_sfinae">C++0x SFINAE includes access control</h3>
+<h4 id="cxx_access_control_sfinae">C++0x SFINAE includes access control</h3>
-<p>Use <tt>__has_feature(cxx_access_control_sfinae)</tt> to determine whether access-control errors (e.g., calling a private constructor) are considered to be template argument deduction errors (aka SFINAE errors), per <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1170">C++ DR1170</a>.</p>
+<p>Use <tt>__has_feature(cxx_access_control_sfinae)</tt> or <tt>__has_extension(cxx_access_control_sfinae)</tt> to determine whether access-control errors (e.g., calling a private constructor) are considered to be template argument deduction errors (aka SFINAE errors), per <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1170">C++ DR1170</a>.</p>
-<h3 id="cxx_alias_templates">C++0x alias templates</h3>
+<h4 id="cxx_alias_templates">C++0x alias templates</h3>
-<p>Use <tt>__has_feature(cxx_alias_templates)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_alias_templates)</tt> or
+<tt>__has_extension(cxx_alias_templates)</tt> to determine if support for
C++0x's alias declarations and alias templates is enabled.</p>
-<h3 id="cxx_attributes">C++0x attributes</h3>
+<h4 id="cxx_attributes">C++0x attributes</h3>
-<p>Use <tt>__has_feature(cxx_attributes)</tt> to determine if support for
-attribute parsing with C++0x's square bracket notation is enabled.</p>
+<p>Use <tt>__has_feature(cxx_attributes)</tt> or
+<tt>__has_extension(cxx_attributes)</tt> to determine if support for attribute
+parsing with C++0x's square bracket notation is enabled.</p>
-<h3 id="cxx_default_function_template_args">C++0x default template arguments in function templates</h3>
+<h4 id="cxx_default_function_template_args">C++0x default template arguments in function templates</h3>
-<p>Use <tt>__has_feature(cxx_default_function_template_args)</tt> to determine if support for default template arguments in function templates is enabled.</p>
+<p>Use <tt>__has_feature(cxx_default_function_template_args)</tt> or
+<tt>__has_extension(cxx_default_function_template_args)</tt> to determine
+if support for default template arguments in function templates is enabled.</p>
-<h3 id="cxx_deleted_functions">C++0x deleted functions</tt></h3>
+<h4 id="cxx_deleted_functions">C++0x deleted functions</tt></h3>
-<p>Use <tt>__has_feature(cxx_deleted_functions)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_deleted_functions)</tt> or
+<tt>__has_extension(cxx_deleted_functions)</tt> to determine if support for
deleted function definitions (with <tt>= delete</tt>) is enabled.</p>
-<h3 id="cxx_lambdas">C++0x lambdas</h3>
+<h4 id="cxx_lambdas">C++0x lambdas</h3>
-<p>Use <tt>__has_feature(cxx_lambdas)</tt> to determine if support for
-lambdas is enabled. clang does not currently implement this feature.</p>
+<p>Use <tt>__has_feature(cxx_lambdas)</tt> or
+<tt>__has_extension(cxx_lambdas)</tt> to determine if support for lambdas
+is enabled. clang does not currently implement this feature.</p>
-<h3 id="cxx_nullptr">C++0x <tt>nullptr</tt></h3>
+<h4 id="cxx_nullptr">C++0x <tt>nullptr</tt></h3>
-<p>Use <tt>__has_feature(cxx_nullptr)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_nullptr)</tt> or
+<tt>__has_extension(cxx_nullptr)</tt> to determine if support for
<tt>nullptr</tt> is enabled. clang does not yet fully implement this
feature.</p>
-<h3 id="cxx_override_control">C++0x <tt>override control</tt></h3>
+<h4 id="cxx_override_control">C++0x <tt>override control</tt></h3>
-<p>Use <tt>__has_feature(cxx_override_control)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_override_control)</tt> or
+<tt>__has_extension(cxx_override_control)</tt> to determine if support for
the override control keywords is enabled.</p>
-<h3 id="cxx_reference_qualified_functions">C++0x reference-qualified functions</h3>
-<p>Use <tt>__has_feature(cxx_reference_qualified_functions)</tt> to determine if support for reference-qualified functions (e.g., member functions with <code>&</code> or <code>&&</code> applied to <code>*this</code>) is enabled.</p>
-
-<h3 id="cxx_range_for">C++0x range-based for loop</tt></h3>
-
-<p>Use <tt>__has_feature(cxx_range_for)</tt> to determine if support for
-the range-based for loop is enabled. </p>
+<h4 id="cxx_reference_qualified_functions">C++0x reference-qualified functions</h3>
+<p>Use <tt>__has_feature(cxx_reference_qualified_functions)</tt> or
+<tt>__has_extension(cxx_reference_qualified_functions)</tt> to determine
+if support for reference-qualified functions (e.g., member functions with
+<code>&</code> or <code>&&</code> applied to <code>*this</code>)
+is enabled.</p>
+
+<h4 id="cxx_range_for">C++0x range-based for loop</tt></h3>
+
+<p>Use <tt>__has_feature(cxx_range_for)</tt> or
+<tt>__has_extension(cxx_range_for)</tt> to determine if support for the
+range-based for loop is enabled. </p>
-<h3 id="cxx_rvalue_references">C++0x rvalue references</tt></h3>
+<h4 id="cxx_rvalue_references">C++0x rvalue references</tt></h3>
-<p>Use <tt>__has_feature(cxx_rvalue_references)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_rvalue_references)</tt> or
+<tt>__has_extension(cxx_rvalue_references)</tt> to determine if support for
rvalue references is enabled. </p>
-<h3 id="cxx_static_assert">C++0x <tt>static_assert()</tt></h3>
+<h4 id="cxx_static_assert">C++0x <tt>static_assert()</tt></h3>
-<p>Use <tt>__has_feature(cxx_static_assert)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_static_assert)</tt> or
+<tt>__has_extension(cxx_static_assert)</tt> to determine if support for
compile-time assertions using <tt>static_assert</tt> is enabled.</p>
-<h3 id="cxx_auto_type">C++0x type inference</h3>
+<h4 id="cxx_auto_type">C++0x type inference</h3>
-<p>Use <tt>__has_feature(cxx_auto_type)</tt> to determine C++0x type inference
-is supported using the <tt>auto</tt> specifier. If this is disabled,
-<tt>auto</tt> will instead be a storage class specifier, as in C or C++98.</p>
+<p>Use <tt>__has_feature(cxx_auto_type)</tt> or
+<tt>__has_extension(cxx_auto_type)</tt> to determine C++0x type inference is
+supported using the <tt>auto</tt> specifier. If this is disabled, <tt>auto</tt>
+will instead be a storage class specifier, as in C or C++98.</p>
-<h3 id="cxx_variadic_templates">C++0x variadic templates</h3>
+<h4 id="cxx_variadic_templates">C++0x variadic templates</h3>
-<p>Use <tt>__has_feature(cxx_variadic_templates)</tt> to determine if support
+<p>Use <tt>__has_feature(cxx_variadic_templates)</tt> or
+<tt>__has_extension(cxx_variadic_templates)</tt> to determine if support
for variadic templates is enabled.</p>
-<h3 id="cxx_inline_namespaces">C++0x inline namespaces</h3>
+<h4 id="cxx_inline_namespaces">C++0x inline namespaces</h3>
-<p>Use <tt>__has_feature(cxx_inline_namespaces)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_inline_namespaces)</tt> or
+<tt>__has_extension(cxx_inline_namespaces)</tt> to determine if support for
inline namespaces is enabled.</p>
-<h3 id="cxx_trailing_return">C++0x trailing return type</h3>
+<h4 id="cxx_trailing_return">C++0x trailing return type</h3>
-<p>Use <tt>__has_feature(cxx_trailing_return)</tt> to determine if support for
-the alternate function declaration syntax with trailing return type is enabled.</p>
+<p>Use <tt>__has_feature(cxx_trailing_return)</tt> or
+<tt>__has_extension(cxx_trailing_return)</tt> to determine if support for the
+alternate function declaration syntax with trailing return type is enabled.</p>
-<h3 id="cxx_noexcept">C++0x noexcept</h3>
+<h4 id="cxx_noexcept">C++0x noexcept</h3>
-<p>Use <tt>__has_feature(cxx_noexcept)</tt> to determine if support for
-noexcept exception specifications is enabled.</p>
+<p>Use <tt>__has_feature(cxx_noexcept)</tt> or
+<tt>__has_extension(cxx_noexcept)</tt> to determine if support for noexcept
+exception specifications is enabled.</p>
-<h3 id="cxx_strong_enums">C++0x strongly typed enumerations</h3>
+<h4 id="cxx_strong_enums">C++0x strongly typed enumerations</h3>
-<p>Use <tt>__has_feature(cxx_strong_enums)</tt> to determine if support for
+<p>Use <tt>__has_feature(cxx_strong_enums)</tt> or
+<tt>__has_extension(cxx_strong_enums)</tt> to determine if support for
strongly typed, scoped enumerations is enabled.</p>
+<h3 id="c1x">C1X</h3>
+
+<p>The features listed below are slated for inclusion in the upcoming
+C1X standard. As a result, all these features are enabled
+with the <tt>-std=c1x</tt> option when compiling C code.</p>
+
+<h4 id="c_generic_selections">C1X generic selections</h2>
+
+<p>Use <tt>__has_feature(c_generic_selections)</tt> or
+<tt>__has_extension(c_generic_selections)</tt> to determine if support for
+generic selections is enabled.</p>
+
+<p>As an extension, the C1X generic selection expression is available in all
+languages supported by Clang. The syntax is the same as that given in the
+C1X draft standard.</p>
+
+<p>In C, type compatibility is decided according to the rules given in the
+appropriate standard, but in C++, which lacks the type compatibility rules
+used in C, types are considered compatible only if they are equivalent.</p>
+
+<h4 id="c_static_assert">C1X <tt>_Static_assert()</tt></h3>
+
+<p>Use <tt>__has_feature(c_static_assert)</tt> or
+<tt>__has_extension(c_static_assert)</tt> to determine if support for
+compile-time assertions using <tt>_Static_assert</tt> is enabled.</p>
+
<!-- ======================================================================= -->
<h2 id="checking_type_traits">Checks for Type Traits</h2>
<!-- ======================================================================= -->
-<p>Clang supports the <a hef="http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html">GNU C++ type traits</a> and a subset of the <a href="http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx">Microsoft Visual C++ Type traits</a>. For each supported type trait <code>__X</code>, <code>__has_feature(X)</code> indicates the presence of the type trait. For example:
+<p>Clang supports the <a hef="http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html">GNU C++ type traits</a> and a subset of the <a href="http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx">Microsoft Visual C++ Type traits</a>. For each supported type trait <code>__X</code>, <code>__has_extension(X)</code> indicates the presence of the type trait. For example:
<blockquote>
<pre>
-#if __has_feature(is_convertible_to)
+#if __has_extension(is_convertible_to)
template<typename From, typename To>
struct is_convertible_to {
static const bool value = __is_convertible_to(From, To);
@@ -518,7 +596,7 @@
href="Block-ABI-Apple.txt">Block-ABI-Apple.txt</a>.</p>
-<p>Query for this feature with __has_feature(blocks).</p>
+<p>Query for this feature with __has_extension(blocks).</p>
<!-- ======================================================================= -->
<h2 id="overloading-in-c">Function Overloading in C</h2>
@@ -618,22 +696,8 @@
C.</li>
</ul>
-<p>Query for this feature with __has_feature(attribute_overloadable).</p>
-
-
-<!-- ======================================================================= -->
-<h2 id="generic-selections">Generic Selections</h2>
-<!-- ======================================================================= -->
-
-<p>The C1X generic selection expression is available in all languages
-supported by Clang. The syntax is the same as that given in the C1X draft
-standard.</p>
-
-<p>In C, type compatibility is decided according to the rules given in the
-appropriate standard, but in C++, which lacks the type compatibility rules
-used in C, types are considered compatible only if they are equivalent.</p>
+<p>Query for this feature with __has_extension(attribute_overloadable).</p>
-<p>Query for this feature with __has_feature(generic_selections).</p>
<!-- ======================================================================= -->
<h2 id="builtins">Builtin Functions</h2>
Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=131308&r1=131307&r2=131308&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Fri May 13 15:54:45 2011
@@ -401,6 +401,7 @@
void setExtensionHandlingBehavior(ExtensionHandling H) {
ExtBehavior = H;
}
+ ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; }
/// AllExtensionsSilenced - This is a counter bumped when an __extension__
/// block is encountered. When non-zero, all extension diagnostics are
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=131308&r1=131307&r2=131308&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri May 13 15:54:45 2011
@@ -84,6 +84,7 @@
IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma
IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
IdentifierInfo *Ident__has_feature; // __has_feature
+ IdentifierInfo *Ident__has_extension; // __has_extension
IdentifierInfo *Ident__has_builtin; // __has_builtin
IdentifierInfo *Ident__has_attribute; // __has_attribute
IdentifierInfo *Ident__has_include; // __has_include
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=131308&r1=131307&r2=131308&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri May 13 15:54:45 2011
@@ -85,6 +85,7 @@
// Clang Extensions.
Ident__has_feature = RegisterBuiltinMacro(*this, "__has_feature");
+ Ident__has_extension = RegisterBuiltinMacro(*this, "__has_extension");
Ident__has_builtin = RegisterBuiltinMacro(*this, "__has_builtin");
Ident__has_attribute = RegisterBuiltinMacro(*this, "__has_attribute");
Ident__has_include = RegisterBuiltinMacro(*this, "__has_include");
@@ -525,8 +526,8 @@
}
-/// HasFeature - Return true if we recognize and implement the specified feature
-/// specified by the identifier.
+/// HasFeature - Return true if we recognize and implement the feature
+/// specified by the identifier as a standard language feature.
static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
const LangOptions &LangOpts = PP.getLangOptions();
@@ -550,12 +551,14 @@
.Case("cxx_exceptions", LangOpts.Exceptions)
.Case("cxx_rtti", LangOpts.RTTI)
.Case("enumerator_attributes", true)
- .Case("generic_selections", true)
.Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI)
.Case("objc_weak_class", LangOpts.ObjCNonFragileABI)
.Case("ownership_holds", true)
.Case("ownership_returns", true)
.Case("ownership_takes", true)
+ // C1X features
+ .Case("c_generic_selections", LangOpts.C1X)
+ .Case("c_static_assert", LangOpts.C1X)
// C++0x features
.Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x)
.Case("cxx_alias_templates", LangOpts.CPlusPlus0x)
@@ -603,6 +606,35 @@
.Default(false);
}
+/// HasExtension - Return true if we recognize and implement the feature
+/// specified by the identifier, either as an extension or a standard language
+/// feature.
+static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
+ if (HasFeature(PP, II))
+ return true;
+
+ // If the use of an extension results in an error diagnostic, extensions are
+ // effectively unavailable, so just return false here.
+ if (PP.getDiagnostics().getExtensionHandlingBehavior()==Diagnostic::Ext_Error)
+ return false;
+
+ const LangOptions &LangOpts = PP.getLangOptions();
+
+ // Because we inherit the feature list from HasFeature, this string switch
+ // must be less restrictive than HasFeature's.
+ return llvm::StringSwitch<bool>(II->getName())
+ // C1X features supported by other languages as extensions.
+ .Case("c_generic_selections", true)
+ .Case("c_static_assert", true)
+ // C++0x features supported by other languages as extensions.
+ .Case("cxx_deleted_functions", LangOpts.CPlusPlus)
+ .Case("cxx_inline_namespaces", LangOpts.CPlusPlus)
+ .Case("cxx_override_control", LangOpts.CPlusPlus)
+ .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus)
+ .Case("cxx_rvalue_references", LangOpts.CPlusPlus)
+ .Default(false);
+}
+
/// HasAttribute - Return true if we recognize and implement the attribute
/// specified by the given identifier.
static bool HasAttribute(const IdentifierInfo *II) {
@@ -851,10 +883,11 @@
// __COUNTER__ expands to a simple numeric value.
OS << CounterValue++;
Tok.setKind(tok::numeric_constant);
- } else if (II == Ident__has_feature ||
- II == Ident__has_builtin ||
+ } else if (II == Ident__has_feature ||
+ II == Ident__has_extension ||
+ II == Ident__has_builtin ||
II == Ident__has_attribute) {
- // The argument to these two builtins should be a parenthesized identifier.
+ // The argument to these builtins should be a parenthesized identifier.
SourceLocation StartLoc = Tok.getLocation();
bool IsValid = false;
@@ -883,6 +916,8 @@
Value = FeatureII->getBuiltinID() != 0;
} else if (II == Ident__has_attribute)
Value = HasAttribute(FeatureII);
+ else if (II == Ident__has_extension)
+ Value = HasExtension(*this, FeatureII);
else {
assert(II == Ident__has_feature && "Must be feature check");
Value = HasFeature(*this, FeatureII);
Added: cfe/trunk/test/Lexer/has_extension.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/has_extension.c?rev=131308&view=auto
==============================================================================
--- cfe/trunk/test/Lexer/has_extension.c (added)
+++ cfe/trunk/test/Lexer/has_extension.c Fri May 13 15:54:45 2011
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-PED-NONE %s
+// RUN: %clang_cc1 -pedantic-errors -E %s -o - | FileCheck --check-prefix=CHECK-PED-ERR %s
+
+// CHECK-PED-NONE: no_dummy_extension
+#if !__has_extension(dummy_extension)
+int no_dummy_extension();
+#endif
+
+// Arbitrary feature to test that has_extension is a superset of has_feature
+// CHECK-PED-NONE: attribute_overloadable
+#if __has_extension(attribute_overloadable)
+int attribute_overloadable();
+#endif
+
+// CHECK-PED-NONE: has_c_static_assert
+// CHECK-PED-ERR: no_c_static_assert
+#if __has_extension(c_static_assert)
+int has_c_static_assert();
+#else
+int no_c_static_assert();
+#endif
+
+// CHECK-PED-NONE: has_c_generic_selections
+// CHECK-PED-ERR: no_c_generic_selections
+#if __has_extension(c_generic_selections)
+int has_c_generic_selections();
+#else
+int no_c_generic_selections();
+#endif
+
Added: cfe/trunk/test/Lexer/has_extension_cxx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/has_extension_cxx.cpp?rev=131308&view=auto
==============================================================================
--- cfe/trunk/test/Lexer/has_extension_cxx.cpp (added)
+++ cfe/trunk/test/Lexer/has_extension_cxx.cpp Fri May 13 15:54:45 2011
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -E %s -o - | FileCheck %s
+
+// CHECK: c_static_assert
+#if __has_extension(c_static_assert)
+int c_static_assert();
+#endif
+
+// CHECK: c_generic_selections
+#if __has_extension(c_generic_selections)
+int c_generic_selections();
+#endif
+
+// CHECK: has_deleted_functions
+#if __has_extension(cxx_deleted_functions)
+int has_deleted_functions();
+#endif
+
+// CHECK: has_inline_namespaces
+#if __has_extension(cxx_inline_namespaces)
+int has_inline_namespaces();
+#endif
+
+// CHECK: has_override_control
+#if __has_extension(cxx_override_control)
+int has_override_control();
+#endif
+
+// CHECK: has_reference_qualified_functions
+#if __has_extension(cxx_reference_qualified_functions)
+int has_reference_qualified_functions();
+#endif
+
+// CHECK: has_rvalue_references
+#if __has_extension(cxx_rvalue_references)
+int has_rvalue_references();
+#endif
Added: cfe/trunk/test/Lexer/has_feature_c1x.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/has_feature_c1x.c?rev=131308&view=auto
==============================================================================
--- cfe/trunk/test/Lexer/has_feature_c1x.c (added)
+++ cfe/trunk/test/Lexer/has_feature_c1x.c Fri May 13 15:54:45 2011
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -E -std=c1x %s -o - | FileCheck --check-prefix=CHECK-1X %s
+// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-1X %s
+
+#if __has_feature(c_static_assert)
+int has_static_assert();
+#else
+int no_static_assert();
+#endif
+
+// CHECK-1X: has_static_assert
+// CHECK-NO-1X: no_static_assert
+
+#if __has_feature(c_generic_selections)
+int has_generic_selections();
+#else
+int no_generic_selections();
+#endif
+
+// CHECK-1X: has_generic_selections
+// CHECK-NO-1X: no_generic_selections
More information about the cfe-commits
mailing list