美文网首页
LLVM __has_feature

LLVM __has_feature

作者: 可bing | 来源:发表于2021-10-29 17:42 被阅读0次

今天在项目中遇到了__has_feature(objc_arc)宏,通过查找文档发现该宏语句是用来判断clang(编译前端)是否支持某个功能特性,这里是判断是否支持objc_arc(自动引用计数)。

栗子:

#if ! __has_feature(objc_arc)
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
#endif

Clang文档中的定义:

__has_feature and __has_extension

These function-like macros take a single identifier argument that is the name of a feature. __has_feature evaluates to 1 if the feature is both supported by Clang and standardized in the current language standard or 0 if not (but see below), while __has_extension 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:

#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(cxx_rvalue_references)
// This code will only be compiled with the -std=c++11 and -std=gnu++11
// options, because rvalue references are only standardized in C++11.
#endif

#if __has_extension(cxx_rvalue_references)
// This code will be compiled with the -std=c++11, -std=gnu++11, -std=c++98
// and -std=gnu++98 options, because rvalue references are supported as a
// language extension in C++98.
#endif

For backward compatibility, __has_feature can also be used to test for support for non-standardized features, i.e. features not prefixed c_, cxx_ or objc_.

Another use of __has_feature is to check for compiler features not related to the language standard, such as e.g. AddressSanitizer.

If the -pedantic-errors option is given, __has_extension is equivalent to __has_feature.

The feature tag is described along with the language feature below.

The feature name or extension name can also be specified with a preceding and following __ (double underscore) to avoid interference from a macro with the same name. For instance, __cxx_rvalue_references__ can be used instead of cxx_rvalue_references.

clang API Documentation:

00855 /// HasFeature - Return true if we recognize and implement the feature
00856 /// specified by the identifier as a standard language feature.
00857 static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
00858   const LangOptions &LangOpts = PP.getLangOpts();
00859   StringRef Feature = II->getName();
00860 
00861   // Normalize the feature name, __foo__ becomes foo.
00862   if (Feature.startswith("__") && Feature.endswith("__") && Feature.size() >= 4)
00863     Feature = Feature.substr(2, Feature.size() - 4);
00864 
00865   return llvm::StringSwitch<bool>(Feature)
00866       .Case("address_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Address))
00867       .Case("attribute_analyzer_noreturn", true)
00868       .Case("attribute_availability", true)
00869       .Case("attribute_availability_with_message", true)
00870       .Case("attribute_cf_returns_not_retained", true)
00871       .Case("attribute_cf_returns_retained", true)
00872       .Case("attribute_deprecated_with_message", true)
00873       .Case("attribute_ext_vector_type", true)
00874       .Case("attribute_ns_returns_not_retained", true)
00875       .Case("attribute_ns_returns_retained", true)
00876       .Case("attribute_ns_consumes_self", true)
00877       .Case("attribute_ns_consumed", true)
00878       .Case("attribute_cf_consumed", true)
00879       .Case("attribute_objc_ivar_unused", true)
00880       .Case("attribute_objc_method_family", true)
00881       .Case("attribute_overloadable", true)
00882       .Case("attribute_unavailable_with_message", true)
00883       .Case("attribute_unused_on_fields", true)
00884       .Case("blocks", LangOpts.Blocks)
00885       .Case("c_thread_safety_attributes", true)
00886       .Case("cxx_exceptions", LangOpts.CXXExceptions)
00887       .Case("cxx_rtti", LangOpts.RTTI)
00888       .Case("enumerator_attributes", true)
00889       .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
00890       .Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread))
00891       .Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow))
00892       // Objective-C features
00893       .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
00894       .Case("objc_arc", LangOpts.ObjCAutoRefCount)
00895       .Case("objc_arc_weak", LangOpts.ObjCARCWeak)
00896       .Case("objc_default_synthesize_properties", LangOpts.ObjC2)
00897       .Case("objc_fixed_enum", LangOpts.ObjC2)
00898       .Case("objc_instancetype", LangOpts.ObjC2)
00899       .Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
00900       .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
00901       .Case("objc_property_explicit_atomic",
00902             true) // Does clang support explicit "atomic" keyword?
00903       .Case("objc_protocol_qualifier_mangling", true)
00904       .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
00905       .Case("ownership_holds", true)
00906       .Case("ownership_returns", true)
00907       .Case("ownership_takes", true)
00908       .Case("objc_bool", true)
00909       .Case("objc_subscripting", LangOpts.ObjCRuntime.isNonFragile())
00910       .Case("objc_array_literals", LangOpts.ObjC2)
00911       .Case("objc_dictionary_literals", LangOpts.ObjC2)
00912       .Case("objc_boxed_expressions", LangOpts.ObjC2)
00913       .Case("arc_cf_code_audited", true)
00914       // C11 features
00915       .Case("c_alignas", LangOpts.C11)
00916       .Case("c_atomic", LangOpts.C11)
00917       .Case("c_generic_selections", LangOpts.C11)
00918       .Case("c_static_assert", LangOpts.C11)
00919       .Case("c_thread_local",
00920             LangOpts.C11 && PP.getTargetInfo().isTLSSupported())
00921       // C++11 features
00922       .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
00923       .Case("cxx_alias_templates", LangOpts.CPlusPlus11)
00924       .Case("cxx_alignas", LangOpts.CPlusPlus11)
00925       .Case("cxx_atomic", LangOpts.CPlusPlus11)
00926       .Case("cxx_attributes", LangOpts.CPlusPlus11)
00927       .Case("cxx_auto_type", LangOpts.CPlusPlus11)
00928       .Case("cxx_constexpr", LangOpts.CPlusPlus11)
00929       .Case("cxx_decltype", LangOpts.CPlusPlus11)
00930       .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
00931       .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
00932       .Case("cxx_defaulted_functions", LangOpts.CPlusPlus11)
00933       .Case("cxx_delegating_constructors", LangOpts.CPlusPlus11)
00934       .Case("cxx_deleted_functions", LangOpts.CPlusPlus11)
00935       .Case("cxx_explicit_conversions", LangOpts.CPlusPlus11)
00936       .Case("cxx_generalized_initializers", LangOpts.CPlusPlus11)
00937       .Case("cxx_implicit_moves", LangOpts.CPlusPlus11)
00938       .Case("cxx_inheriting_constructors", LangOpts.CPlusPlus11)
00939       .Case("cxx_inline_namespaces", LangOpts.CPlusPlus11)
00940       .Case("cxx_lambdas", LangOpts.CPlusPlus11)
00941       .Case("cxx_local_type_template_args", LangOpts.CPlusPlus11)
00942       .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus11)
00943       .Case("cxx_noexcept", LangOpts.CPlusPlus11)
00944       .Case("cxx_nullptr", LangOpts.CPlusPlus11)
00945       .Case("cxx_override_control", LangOpts.CPlusPlus11)
00946       .Case("cxx_range_for", LangOpts.CPlusPlus11)
00947       .Case("cxx_raw_string_literals", LangOpts.CPlusPlus11)
00948       .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus11)
00949       .Case("cxx_rvalue_references", LangOpts.CPlusPlus11)
00950       .Case("cxx_strong_enums", LangOpts.CPlusPlus11)
00951       .Case("cxx_static_assert", LangOpts.CPlusPlus11)
00952       .Case("cxx_thread_local",
00953             LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported())
00954       .Case("cxx_trailing_return", LangOpts.CPlusPlus11)
00955       .Case("cxx_unicode_literals", LangOpts.CPlusPlus11)
00956       .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11)
00957       .Case("cxx_user_literals", LangOpts.CPlusPlus11)
00958       .Case("cxx_variadic_templates", LangOpts.CPlusPlus11)
00959       // C++1y features
00960       .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14)
00961       .Case("cxx_binary_literals", LangOpts.CPlusPlus14)
00962       .Case("cxx_contextual_conversions", LangOpts.CPlusPlus14)
00963       .Case("cxx_decltype_auto", LangOpts.CPlusPlus14)
00964       .Case("cxx_generic_lambdas", LangOpts.CPlusPlus14)
00965       .Case("cxx_init_captures", LangOpts.CPlusPlus14)
00966       .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14)
00967       .Case("cxx_return_type_deduction", LangOpts.CPlusPlus14)
00968       .Case("cxx_variable_templates", LangOpts.CPlusPlus14)
00969       // C++ TSes
00970       //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
00971       //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
00972       // FIXME: Should this be __has_feature or __has_extension?
00973       //.Case("raw_invocation_type", LangOpts.CPlusPlus)
00974       // Type traits
00975       .Case("has_nothrow_assign", LangOpts.CPlusPlus)
00976       .Case("has_nothrow_copy", LangOpts.CPlusPlus)
00977       .Case("has_nothrow_constructor", LangOpts.CPlusPlus)
00978       .Case("has_trivial_assign", LangOpts.CPlusPlus)
00979       .Case("has_trivial_copy", LangOpts.CPlusPlus)
00980       .Case("has_trivial_constructor", LangOpts.CPlusPlus)
00981       .Case("has_trivial_destructor", LangOpts.CPlusPlus)
00982       .Case("has_virtual_destructor", LangOpts.CPlusPlus)
00983       .Case("is_abstract", LangOpts.CPlusPlus)
00984       .Case("is_base_of", LangOpts.CPlusPlus)
00985       .Case("is_class", LangOpts.CPlusPlus)
00986       .Case("is_constructible", LangOpts.CPlusPlus)
00987       .Case("is_convertible_to", LangOpts.CPlusPlus)
00988       .Case("is_empty", LangOpts.CPlusPlus)
00989       .Case("is_enum", LangOpts.CPlusPlus)
00990       .Case("is_final", LangOpts.CPlusPlus)
00991       .Case("is_literal", LangOpts.CPlusPlus)
00992       .Case("is_standard_layout", LangOpts.CPlusPlus)
00993       .Case("is_pod", LangOpts.CPlusPlus)
00994       .Case("is_polymorphic", LangOpts.CPlusPlus)
00995       .Case("is_sealed", LangOpts.MicrosoftExt)
00996       .Case("is_trivial", LangOpts.CPlusPlus)
00997       .Case("is_trivially_assignable", LangOpts.CPlusPlus)
00998       .Case("is_trivially_constructible", LangOpts.CPlusPlus)
00999       .Case("is_trivially_copyable", LangOpts.CPlusPlus)
01000       .Case("is_union", LangOpts.CPlusPlus)
01001       .Case("modules", LangOpts.Modules)
01002       .Case("tls", PP.getTargetInfo().isTLSSupported())
01003       .Case("underlying_type", LangOpts.CPlusPlus)
01004       .Default(false);
01005 }

相关文章

  • LLVM __has_feature

    今天在项目中遇到了__has_feature(objc_arc)宏,通过查找文档发现该宏语句是用来判断clang(...

  • __has_feature详解

    在iOS开发中总能看见__has_feature宏,最常见的例如__has_feature(objc_arc),表...

  • iOS 单例宏

    #if __has_feature(objc_arc) #define SYNTHESIZE_SINGLETON_...

  • LLVM

    LLVM 什么是LLVM? 官网:https://llvm.org/ The LLVM Project is a ...

  • #if ! __has_feature(objc_arc)#warning This file must be c...

  • iOS_LLVM

    LLVM 官网:https://llvm.org/[https://llvm.org/] The LLVM Pro...

  • iOS 逆向 day 18 GCC LLVM Clang

    一、LLVM 1. 什么是 LLVM 官网:https://llvm.org/ The LLVM Project ...

  • __has_feature

    https://www.jianshu.com/p/79c98dd0fbca

  • 浅谈LLVM

    何为LLVM 在LLVM的官网(https://llvm.org/[https://llvm.org/])中写到T...

  • iOS逆向-day10:LLVM 编译器

    一、LLVM的简单介绍 1.1、什么是LLVM官网:https://llvm.org/LLVM官网解释:The L...

网友评论

      本文标题:LLVM __has_feature

      本文链接:https://www.haomeiwen.com/subject/jcoialtx.html