forked from OSchip/llvm-project
Add __has_feature() for each of the type traits
llvm-svn: 124820
This commit is contained in:
parent
fb0bd049da
commit
7c60768590
|
@ -46,13 +46,14 @@ td {
|
|||
<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>
|
||||
</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="#builtins">Builtin Functions</a>
|
||||
<ul>
|
||||
<li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li>
|
||||
<li><a href="#__builtin_unreachable">__builtin_unreachable</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#targetspecific">Target-Specific Extensions</a>
|
||||
<ul>
|
||||
|
@ -436,6 +437,46 @@ the alternate function declaration syntax with trailing return type is enabled.<
|
|||
<p>Use <tt>__has_feature(cxx_strong_enums)</tt> to determine if support for
|
||||
strongly typed, scoped enumerations 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:
|
||||
<blockquote>
|
||||
<pre>
|
||||
#if __has_feature(is_convertible_to)
|
||||
template<typename From, typename To>
|
||||
struct is_convertible_to {
|
||||
static const bool value = __is_convertible_to(From, To);
|
||||
};
|
||||
#else
|
||||
// Emulate type trait
|
||||
#endif
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The following type traits are supported by Clang:</p>
|
||||
<ul>
|
||||
<li><code>__has_nothrow_assign</code> (GNU, Microsoft)</li>
|
||||
<li><code>__has_nothrow_copy</code> (GNU, Microsoft)</li>
|
||||
<li><code>__has_nothrow_constructor</code> (GNU, Microsoft)</li>
|
||||
<li><code>__has_trivial_assign</code> (GNU, Microsoft)</li>
|
||||
<li><code>__has_trivial_copy</code> (GNU, Microsoft)</li>
|
||||
<li><code>__has_trivial_constructor</code> (GNU, Microsoft)</li>
|
||||
<li><code>__has_trivial_destructor</code> (GNU, Microsoft)</li>
|
||||
<li><code>__has_virtual_destructor</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_abstract</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_base_of</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_class</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_convertible_to</code> (Microsoft)</li>
|
||||
<li><code>__is_empty</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_enum</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_pod</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_polymorphic</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_union</code> (GNU, Microsoft)</li>
|
||||
<li><code>__is_literal(type)</code>: Determines whether the given type is a literal type</li>
|
||||
</ul>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h2 id="blocks">Blocks</h2>
|
||||
<!-- ======================================================================= -->
|
||||
|
|
|
@ -565,6 +565,25 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
|
|||
.Case("cxx_static_assert", LangOpts.CPlusPlus0x)
|
||||
.Case("cxx_trailing_return", LangOpts.CPlusPlus0x)
|
||||
.Case("cxx_variadic_templates", LangOpts.CPlusPlus0x)
|
||||
// Type traits
|
||||
.Case("has_nothrow_assign", LangOpts.CPlusPlus)
|
||||
.Case("has_nothrow_copy", LangOpts.CPlusPlus)
|
||||
.Case("has_nothrow_constructor", LangOpts.CPlusPlus)
|
||||
.Case("has_trivial_assign", LangOpts.CPlusPlus)
|
||||
.Case("has_trivial_copy", LangOpts.CPlusPlus)
|
||||
.Case("has_trivial_constructor", LangOpts.CPlusPlus)
|
||||
.Case("has_trivial_destructor", LangOpts.CPlusPlus)
|
||||
.Case("has_virtual_destructor", LangOpts.CPlusPlus)
|
||||
.Case("is_abstract", LangOpts.CPlusPlus)
|
||||
.Case("is_base_of", LangOpts.CPlusPlus)
|
||||
.Case("is_class", LangOpts.CPlusPlus)
|
||||
.Case("is_convertible_to", LangOpts.CPlusPlus)
|
||||
.Case("is_empty", LangOpts.CPlusPlus)
|
||||
.Case("is_enum", LangOpts.CPlusPlus)
|
||||
.Case("is_pod", LangOpts.CPlusPlus)
|
||||
.Case("is_polymorphic", LangOpts.CPlusPlus)
|
||||
.Case("is_union", LangOpts.CPlusPlus)
|
||||
.Case("is_literal", LangOpts.CPlusPlus)
|
||||
.Case("tls", PP.getTargetInfo().isTLSSupported())
|
||||
.Default(false);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// RUN: %clang_cc1 -E %s -o - | FileCheck %s
|
||||
|
||||
#if __has_feature(has_nothrow_assign)
|
||||
int has_nothrow_assign();
|
||||
#endif
|
||||
// CHECK: int has_nothrow_assign();
|
||||
|
||||
#if __has_feature(has_nothrow_copy)
|
||||
int has_nothrow_copy();
|
||||
#endif
|
||||
// CHECK: int has_nothrow_copy();
|
||||
|
||||
#if __has_feature(has_nothrow_constructor)
|
||||
int has_nothrow_constructor();
|
||||
#endif
|
||||
// CHECK: int has_nothrow_constructor();
|
||||
|
||||
#if __has_feature(has_trivial_assign)
|
||||
int has_trivial_assign();
|
||||
#endif
|
||||
// CHECK: int has_trivial_assign();
|
||||
|
||||
#if __has_feature(has_trivial_copy)
|
||||
int has_trivial_copy();
|
||||
#endif
|
||||
// CHECK: int has_trivial_copy();
|
||||
|
||||
#if __has_feature(has_trivial_constructor)
|
||||
int has_trivial_constructor();
|
||||
#endif
|
||||
// CHECK: int has_trivial_constructor();
|
||||
|
||||
#if __has_feature(has_trivial_destructor)
|
||||
int has_trivial_destructor();
|
||||
#endif
|
||||
// CHECK: int has_trivial_destructor();
|
||||
|
||||
#if __has_feature(has_virtual_destructor)
|
||||
int has_virtual_destructor();
|
||||
#endif
|
||||
// CHECK: int has_virtual_destructor();
|
||||
|
||||
#if __has_feature(is_abstract)
|
||||
int is_abstract();
|
||||
#endif
|
||||
// CHECK: int is_abstract();
|
||||
|
||||
#if __has_feature(is_base_of)
|
||||
int is_base_of();
|
||||
#endif
|
||||
// CHECK: int is_base_of();
|
||||
|
||||
#if __has_feature(is_class)
|
||||
int is_class();
|
||||
#endif
|
||||
// CHECK: int is_class();
|
||||
|
||||
#if __has_feature(is_convertible_to)
|
||||
int is_convertible_to();
|
||||
#endif
|
||||
// CHECK: int is_convertible_to();
|
||||
|
||||
#if __has_feature(is_empty)
|
||||
int is_empty();
|
||||
#endif
|
||||
// CHECK: int is_empty();
|
||||
|
||||
#if __has_feature(is_enum)
|
||||
int is_enum();
|
||||
#endif
|
||||
// CHECK: int is_enum();
|
||||
|
||||
#if __has_feature(is_pod)
|
||||
int is_pod();
|
||||
#endif
|
||||
// CHECK: int is_pod();
|
||||
|
||||
#if __has_feature(is_polymorphic)
|
||||
int is_polymorphic();
|
||||
#endif
|
||||
// CHECK: int is_polymorphic();
|
||||
|
||||
#if __has_feature(is_union)
|
||||
int is_union();
|
||||
#endif
|
||||
// CHECK: int is_union();
|
||||
|
||||
#if __has_feature(is_literal)
|
||||
int is_literal();
|
||||
#endif
|
||||
// CHECK: int is_literal();
|
Loading…
Reference in New Issue