Ping*2 Richard Sandiford <richard.sandif...@arm.com> writes: > Ping > > To give a bit more rationale: some of the functions handled by > https://gcc.gnu.org/ml/gcc-patches/2019-10/msg01002.html operate > on structs and enums. There are already langhooks for creating the > necessary struct types, but there's no direct way of creating a > language-level enum. > > One option would have been to define the enum in the header file > and have the pragma search for it by name. But then we have to be > wary of cases in which that definition lost out to an incompatible > user-defined one. (That would be an error, but not one that would > stop the pragma from being processed.) And searching for an existing > enum would be a new hook anyway. > > Having no hooks for enums didn't feel like a deliberate omission. > It looked more like a case of noone needing such a hook until now. > > Richard Sandiford <richard.sandif...@arm.com> writes: >> Similarly to the simulate_builtin_function_decl patch, this one >> adds a hook for simulating an enum declaration in the source >> language. Again, the main SVE ACLE patch has tests for various >> error conditions. >> >> Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? >> >> Richard
2019-09-26 Richard Sandiford <richard.sandif...@arm.com> gcc/ * coretypes.h (string_int_pair): New typedef. * langhooks-def.h (LANG_HOOKS_SIMULATE_ENUM_DECL): Define. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Include it. * langhooks.h (lang_hooks_for_types::simulate_enum_decl): New hook. gcc/c/ * c-tree.h (c_simulate_enum_decl): Declare. * c-decl.c (c_simulate_enum_decl): New function. * c-objc-common.h (LANG_HOOKS_SIMULATE_ENUM_DECL): Define to the above. gcc/cp/ * cp-objcp-common.h (cxx_simulate_enum_decl): Declare. (LANG_HOOKS_SIMULATE_ENUM_DECL): Define to the above. * decl.c (cxx_simulate_enum_decl): New function. Index: gcc/coretypes.h =================================================================== --- gcc/coretypes.h 2019-09-21 13:56:08.843935101 +0100 +++ gcc/coretypes.h 2019-09-26 13:02:48.907474244 +0100 @@ -341,6 +341,7 @@ typedef int reg_class_t; } typedef std::pair <tree, tree> tree_pair; +typedef std::pair <const char *, int> string_int_pair; /* Define a name->value mapping. */ template <typename ValueType> Index: gcc/langhooks-def.h =================================================================== --- gcc/langhooks-def.h 2019-09-26 13:02:42.543520465 +0100 +++ gcc/langhooks-def.h 2019-09-26 13:02:48.911474214 +0100 @@ -171,6 +171,7 @@ #define LANG_HOOKS_TREE_DUMP_INITIALIZER extern tree lhd_unit_size_without_reusable_padding (tree); #define LANG_HOOKS_MAKE_TYPE lhd_make_node +#define LANG_HOOKS_SIMULATE_ENUM_DECL NULL #define LANG_HOOKS_CLASSIFY_RECORD NULL #define LANG_HOOKS_TYPE_FOR_SIZE lhd_type_for_size #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error @@ -204,6 +205,7 @@ #define LANG_HOOKS_UNIT_SIZE_WITHOUT_REU #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \ LANG_HOOKS_MAKE_TYPE, \ + LANG_HOOKS_SIMULATE_ENUM_DECL, \ LANG_HOOKS_CLASSIFY_RECORD, \ LANG_HOOKS_TYPE_FOR_MODE, \ LANG_HOOKS_TYPE_FOR_SIZE, \ Index: gcc/langhooks.h =================================================================== --- gcc/langhooks.h 2019-09-26 13:02:42.543520465 +0100 +++ gcc/langhooks.h 2019-09-26 13:02:48.911474214 +0100 @@ -64,6 +64,10 @@ struct lang_hooks_for_types language-specific processing is required. */ tree (*make_type) (enum tree_code); + /* Make an enum type with the given name and values, associating + them all with the given source location. */ + tree (*simulate_enum_decl) (location_t, const char *, vec<string_int_pair>); + /* Return what kind of RECORD_TYPE this is, mainly for purposes of debug information. If not defined, record types are assumed to be structures. */ Index: gcc/c/c-tree.h =================================================================== --- gcc/c/c-tree.h 2019-09-26 13:02:42.539520492 +0100 +++ gcc/c/c-tree.h 2019-09-26 13:02:48.907474244 +0100 @@ -563,6 +563,8 @@ extern tree finish_enum (tree, tree, tre extern void finish_function (void); extern tree finish_struct (location_t, tree, tree, tree, class c_struct_parse_info *); +extern tree c_simulate_enum_decl (location_t, const char *, + vec<string_int_pair>); extern struct c_arg_info *build_arg_info (void); extern struct c_arg_info *get_parm_info (bool, tree); extern tree grokfield (location_t, struct c_declarator *, Index: gcc/c/c-decl.c =================================================================== --- gcc/c/c-decl.c 2019-09-26 13:02:42.539520492 +0100 +++ gcc/c/c-decl.c 2019-09-26 13:02:48.907474244 +0100 @@ -8903,6 +8903,36 @@ build_enumerator (location_t decl_loc, l return tree_cons (decl, value, NULL_TREE); } +/* Implement LANG_HOOKS_SIMULATE_ENUM_DECL. */ + +tree +c_simulate_enum_decl (location_t loc, const char *name, + vec<string_int_pair> values) +{ + location_t saved_loc = input_location; + input_location = loc; + + struct c_enum_contents the_enum; + tree enumtype = start_enum (loc, &the_enum, get_identifier (name)); + + tree value_chain = NULL_TREE; + string_int_pair *value; + unsigned int i; + FOR_EACH_VEC_ELT (values, i, value) + { + tree decl = build_enumerator (loc, loc, &the_enum, + get_identifier (value->first), + build_int_cst (integer_type_node, + value->second)); + TREE_CHAIN (decl) = value_chain; + value_chain = decl; + } + + finish_enum (enumtype, nreverse (value_chain), NULL_TREE); + + input_location = saved_loc; + return enumtype; +} /* Create the FUNCTION_DECL for a function definition. DECLSPECS, DECLARATOR and ATTRIBUTES are the parts of Index: gcc/c/c-objc-common.h =================================================================== --- gcc/c/c-objc-common.h 2019-09-26 13:02:42.539520492 +0100 +++ gcc/c/c-objc-common.h 2019-09-26 13:02:48.907474244 +0100 @@ -75,6 +75,8 @@ #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABL #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree +#undef LANG_HOOKS_SIMULATE_ENUM_DECL +#define LANG_HOOKS_SIMULATE_ENUM_DECL c_simulate_enum_decl #undef LANG_HOOKS_TYPE_FOR_MODE #define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode #undef LANG_HOOKS_TYPE_FOR_SIZE Index: gcc/cp/cp-objcp-common.h =================================================================== --- gcc/cp/cp-objcp-common.h 2019-09-26 13:02:42.539520492 +0100 +++ gcc/cp/cp-objcp-common.h 2019-09-26 13:02:48.907474244 +0100 @@ -35,6 +35,8 @@ extern tree cp_get_global_decls (); extern tree cp_pushdecl (tree); extern void cp_register_dumps (gcc::dump_manager *); extern tree cxx_make_type_hook (tree_code); +extern tree cxx_simulate_enum_decl (location_t, const char *, + vec<string_int_pair>); /* Lang hooks that are shared between C++ and ObjC++ are defined here. Hooks specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c, @@ -131,6 +133,8 @@ #define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_ #undef LANG_HOOKS_MAKE_TYPE #define LANG_HOOKS_MAKE_TYPE cxx_make_type_hook +#undef LANG_HOOKS_SIMULATE_ENUM_DECL +#define LANG_HOOKS_SIMULATE_ENUM_DECL cxx_simulate_enum_decl #undef LANG_HOOKS_TYPE_FOR_MODE #define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode #undef LANG_HOOKS_TYPE_FOR_SIZE Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c 2019-09-26 13:02:42.543520465 +0100 +++ gcc/cp/decl.c 2019-09-26 13:02:48.911474214 +0100 @@ -15383,6 +15383,40 @@ lookup_enumerator (tree enumtype, tree n return e? TREE_VALUE (e) : NULL_TREE; } +/* Implement LANG_HOOKS_SIMULATE_ENUM_DECL. */ + +tree +cxx_simulate_enum_decl (location_t loc, const char *name, + vec<string_int_pair> values) +{ + location_t saved_loc = input_location; + input_location = loc; + + tree enumtype = start_enum (get_identifier (name), NULL_TREE, NULL_TREE, + NULL_TREE, false, NULL); + if (!OPAQUE_ENUM_P (enumtype)) + { + error_at (loc, "multiple definition of %q#T", enumtype); + inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)), + "previous definition here"); + return enumtype; + } + SET_OPAQUE_ENUM_P (enumtype, false); + DECL_SOURCE_LOCATION (TYPE_NAME (enumtype)) = loc; + + string_int_pair *value; + unsigned int i; + FOR_EACH_VEC_ELT (values, i, value) + build_enumerator (get_identifier (value->first), + build_int_cst (integer_type_node, value->second), + enumtype, NULL_TREE, loc); + + finish_enum_value_list (enumtype); + finish_enum (enumtype); + + input_location = saved_loc; + return enumtype; +} /* We're defining DECL. Make sure that its type is OK. */