LLVM __has_feature

今天在項(xiàng)目中遇到了__has_feature(objc_arc)宏,通過查找文檔發(fā)現(xiàn)該宏語句是用來判斷clang(編譯前端)是否支持某個功能特性,這里是判斷是否支持objc_arc(自動引用計(jì)數(shù))内颗。

栗子:

#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 }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盗冷,更是在濱河造成了極大的恐慌,老刑警劉巖同廉,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仪糖,死亡現(xiàn)場離奇詭異,居然都是意外死亡迫肖,警方通過查閱死者的電腦和手機(jī)锅劝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蟆湖,“玉大人故爵,你說我怎么就攤上這事∮缃颍” “怎么了诬垂?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伦仍。 經(jīng)常有香客問我结窘,道長,這世上最難降的妖魔是什么呢铆? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任晦鞋,我火速辦了婚禮,結(jié)果婚禮上棺克,老公的妹妹穿的比我還像新娘悠垛。我一直安慰自己,他們只是感情好娜谊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布确买。 她就那樣靜靜地躺著,像睡著了一般纱皆。 火紅的嫁衣襯著肌膚如雪湾趾。 梳的紋絲不亂的頭發(fā)上芭商,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音搀缠,去河邊找鬼铛楣。 笑死,一個胖子當(dāng)著我的面吹牛艺普,可吹牛的內(nèi)容都是我干的簸州。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼歧譬,長吁一口氣:“原來是場噩夢啊……” “哼岸浑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瑰步,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤矢洲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后缩焦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體读虏,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年袁滥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掘譬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡呻拌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出睦焕,到底是詐尸還是另有隱情藐握,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布垃喊,位于F島的核電站猾普,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏本谜。R本人自食惡果不足惜初家,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望乌助。 院中可真熱鬧溜在,春花似錦、人聲如沸他托。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赏参。三九已至志笼,卻和暖如春沿盅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纫溃。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工腰涧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人紊浩。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓窖铡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親郎楼。 傳聞我的和親對象是個殘疾皇子万伤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 在iOS開發(fā)中總能看見__has_feature宏,最常見的例如__has_feature(objc_arc)呜袁,表...
    Miridescent閱讀 3,344評論 0 3
  • 前言 通過閱讀別人的優(yōu)秀源碼敌买,你會發(fā)現(xiàn)別人的開源API設(shè)計(jì)中,有一些宏你是經(jīng)常忽略的阶界,或者你不知道的虹钮。通過這些宏,...
    gitKong閱讀 5,139評論 5 41
  • 參考鏈接今天看 MJRefresh 源碼有一段忽略獲的代碼膘融,借機(jī)整理下相關(guān)內(nèi)容 #pragma在本質(zhì)上是聲明芙粱,常用...
    wpf_register閱讀 6,779評論 0 2
  • C++ 開源庫列表https://en.cppreference.com/w/cpp/links/libs[htt...
    老陜西閱讀 2,051評論 0 0
  • This chapter discusses some of the design decisions that ...
    狂風(fēng)無跡閱讀 959評論 0 0