aboutsummaryrefslogtreecommitdiff
path: root/gcc/objc
diff options
context:
space:
mode:
authorAlex Coplan <alex.coplan@arm.com>2023-03-17 16:30:51 +0000
committerAlex Coplan <alex.coplan@arm.com>2023-11-27 10:42:55 +0000
commit06280a906cb3dc80cf5e07cf3335b758848d488d (patch)
tree292a91ef3a9c33fd3761b3cff321303b5d03d656 /gcc/objc
parentd9abaa8d58f5729925b1db735d4723a9ea825eaa (diff)
downloadgcc-06280a906cb3dc80cf5e07cf3335b758848d488d.zip
gcc-06280a906cb3dc80cf5e07cf3335b758848d488d.tar.gz
gcc-06280a906cb3dc80cf5e07cf3335b758848d488d.tar.bz2
c-family: Implement __has_feature and __has_extension [PR60512]
This patch implements clang's __has_feature and __has_extension in GCC. Currently the patch aims to implement all documented features (and some undocumented ones) following the documentation at https://clang.llvm.org/docs/LanguageExtensions.html with the exception of the legacy features for C++ type traits. These are omitted, since as the clang documentation notes, __has_builtin is the correct "modern" way to query for these (which GCC already implements). gcc/c-family/ChangeLog: PR c++/60512 * c-common.cc (struct hf_feature_info): New. (c_common_register_feature): New. (init_has_feature): New. (has_feature_p): New. * c-common.h (c_common_has_feature): New. (c_family_register_lang_features): New. (c_common_register_feature): New. (has_feature_p): New. * c-lex.cc (init_c_lex): Plumb through has_feature callback. (c_common_has_builtin): Generalize and move common part ... (c_common_lex_availability_macro): ... here. (c_common_has_feature): New. * c-ppoutput.cc (init_pp_output): Plumb through has_feature. gcc/c/ChangeLog: PR c++/60512 * c-lang.cc (c_family_register_lang_features): New. * c-objc-common.cc (struct c_feature_info): New. (c_register_features): New. * c-objc-common.h (c_register_features): New. gcc/cp/ChangeLog: PR c++/60512 * cp-lang.cc (c_family_register_lang_features): New. * cp-objcp-common.cc (struct cp_feature_selector): New. (cp_feature_selector::has_feature): New. (struct cp_feature_info): New. (cp_register_features): New. * cp-objcp-common.h (cp_register_features): New. gcc/ChangeLog: PR c++/60512 * doc/cpp.texi: Document __has_{feature,extension}. gcc/objc/ChangeLog: PR c++/60512 * objc-act.cc (struct objc_feature_info): New. (objc_nonfragile_abi_p): New. (objc_common_register_features): New. * objc-act.h (objc_common_register_features): New. * objc-lang.cc (c_family_register_lang_features): New. gcc/objcp/ChangeLog: PR c++/60512 * objcp-lang.cc (c_family_register_lang_features): New. libcpp/ChangeLog: PR c++/60512 * include/cpplib.h (struct cpp_callbacks): Add has_feature. (enum cpp_builtin_type): Add BT_HAS_{FEATURE,EXTENSION}. * init.cc: Add __has_{feature,extension}. * macro.cc (_cpp_builtin_macro_text): Handle BT_HAS_{FEATURE,EXTENSION}. gcc/testsuite/ChangeLog: PR c++/60512 * c-c++-common/has-feature-common.c: New test. * c-c++-common/has-feature-pedantic.c: New test. * g++.dg/ext/has-feature.C: New test. * gcc.dg/asan/has-feature-asan.c: New test. * gcc.dg/has-feature.c: New test. * gcc.dg/ubsan/has-feature-ubsan.c: New test. * obj-c++.dg/has-feature.mm: New test. * objc.dg/has-feature.m: New test. Co-Authored-By: Iain Sandoe <iain@sandoe.co.uk>
Diffstat (limited to 'gcc/objc')
-rw-r--r--gcc/objc/objc-act.cc46
-rw-r--r--gcc/objc/objc-act.h3
-rw-r--r--gcc/objc/objc-lang.cc10
3 files changed, 59 insertions, 0 deletions
diff --git a/gcc/objc/objc-act.cc b/gcc/objc/objc-act.cc
index fe19aa5..02ed6d9 100644
--- a/gcc/objc/objc-act.cc
+++ b/gcc/objc/objc-act.cc
@@ -10340,5 +10340,51 @@ objc_common_init_ts (void)
MARK_TS_TYPED (PROPERTY_REF);
}
+/* Information for Objective-C-specific features known to __has_feature. */
+
+struct objc_feature_info
+{
+ typedef bool (*predicate_t) ();
+
+ const char *ident;
+ predicate_t predicate;
+
+ constexpr objc_feature_info (const char *name)
+ : ident (name), predicate (nullptr) {}
+ constexpr objc_feature_info (const char *name, predicate_t p)
+ : ident (name), predicate (p) {}
+
+ bool has_feature () const
+ {
+ return predicate ? predicate () : true;
+ }
+};
+
+static bool objc_nonfragile_abi_p ()
+{
+ return flag_next_runtime && flag_objc_abi >= 2;
+}
+
+static constexpr objc_feature_info objc_features[] =
+{
+ { "objc_default_synthesize_properties" },
+ { "objc_instancetype" },
+ { "objc_nonfragile_abi", objc_nonfragile_abi_p }
+};
+
+/* Register Objective-C-specific features for __has_feature. */
+
+void
+objc_common_register_features ()
+{
+ for (unsigned i = 0; i < ARRAY_SIZE (objc_features); i++)
+ {
+ const objc_feature_info *info = objc_features + i;
+ if (!info->has_feature ())
+ continue;
+
+ c_common_register_feature (info->ident, true);
+ }
+}
#include "gt-objc-objc-act.h"
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index 68f9029..df40127 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -29,6 +29,9 @@ int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
void objc_common_init_ts (void);
const char *objc_get_sarif_source_language (const char *);
+/* Register features common to Objective-C and Objective-C++. */
+void objc_common_register_features ();
+
/* NB: The remaining public functions are prototyped in c-common.h, for the
benefit of stub-objc.cc and objc-act.cc. */
diff --git a/gcc/objc/objc-lang.cc b/gcc/objc/objc-lang.cc
index 8e56de6..107fb0e 100644
--- a/gcc/objc/objc-lang.cc
+++ b/gcc/objc/objc-lang.cc
@@ -56,6 +56,16 @@ objc_get_sarif_source_language (const char *)
return "objectivec";
}
+/* Implement c-family hook to add language-specific features
+ for __has_{feature,extension}. */
+
+void
+c_family_register_lang_features ()
+{
+ objc_common_register_features ();
+ c_register_features ();
+}
+
/* Lang hook routines common to C and ObjC appear in c-objc-common.cc;
there should be very few (if any) routines below. */