diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-02-03 21:57:35 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-02-03 21:57:35 +0000 |
commit | afdf137c50f7f96ef865cf007f660dd663a8731f (patch) | |
tree | 880d81a66bcc4dafedeaa9e8f03c8488f566dc7b | |
parent | 67410b34bc82af0d16e3a7b531d260e4ef72ce11 (diff) |
Add __has_feature() for each of the type traits
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124820 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/LanguageExtensions.html | 43 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 19 | ||||
-rw-r--r-- | test/Lexer/has_feature_type_traits.cpp | 91 |
3 files changed, 152 insertions, 1 deletions
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html index 30c85ffcbd..8b6b96f6f2 100644 --- a/docs/LanguageExtensions.html +++ b/docs/LanguageExtensions.html @@ -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> @@ -437,6 +438,46 @@ the alternate function declaration syntax with trailing return type is enabled.< 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> <!-- ======================================================================= --> diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 5fb55159de..4a719cac6c 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -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); } diff --git a/test/Lexer/has_feature_type_traits.cpp b/test/Lexer/has_feature_type_traits.cpp new file mode 100644 index 0000000000..3cfc602be6 --- /dev/null +++ b/test/Lexer/has_feature_type_traits.cpp @@ -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(); |