This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Ping*2: Add a simulate_enum_decl langhook


Ping*2

Richard Sandiford <richard.sandiford@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.sandiford@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.sandiford@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.  */
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]