[gcc r16-8370] c++: Use anon enums in eval_data_member_spec

Jakub Jelinek jakub@gcc.gnu.org
Tue Mar 31 21:46:53 GMT 2026


https://gcc.gnu.org/g:3c057b70feda8d5f6fd1328ba3a0eeff4411ef21

commit r16-8370-g3c057b70feda8d5f6fd1328ba3a0eeff4411ef21
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Mar 31 23:38:11 2026 +0200

    c++: Use anon enums in eval_data_member_spec
    
    On Mon, Mar 30, 2026 at 03:46:57PM -0400, Jason Merrill wrote:
    > Maybe it would be helpful to have local enums to name the indices in args?
    
    Here is incremental patch to use local enums for those.
    Tested on x86_64-linux, ok for trunk (it conflicts with the annotations
    addition patch, but it can be easily resolved)?
    
    2026-03-31  Jakub Jelinek  <jakub@redhat.com>
    
            * reflect.cc (eval_data_member_spec): Add anonymous enums for
            fields in std::meta::data_member_options and
            std::meta::data_member_options::_Name and use them instead of
            hardcoded constants.
    
    Reviewed-by: Jason Merrill <jason@redhat.com>

Diff:
---
 gcc/cp/reflect.cc | 67 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 35 insertions(+), 32 deletions(-)

diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 405790d5f357..145b04a60068 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -5566,27 +5566,28 @@ eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
       *non_constant_p = true;
       return NULL_TREE;
     }
-  tree args[5] = { type, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
+  enum { m_name = 1, m_alignment, m_bit_width, m_no_unique_address, n_args };
+  tree args[n_args] = { type, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
   for (tree field = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (opts)));
        field; field = next_aggregate_field (DECL_CHAIN (field)))
     if (tree name = DECL_NAME (field))
       {
 	if (id_equal (name, "name"))
-	  args[1] = field;
+	  args[m_name] = field;
 	else if (id_equal (name, "alignment"))
-	  args[2] = field;
+	  args[m_alignment] = field;
 	else if (id_equal (name, "bit_width"))
-	  args[3] = field;
+	  args[m_bit_width] = field;
 	else if (id_equal (name, "no_unique_address"))
-	  args[4] = field;
+	  args[m_no_unique_address] = field;
       }
-  for (int i = 1; i < 5; ++i)
+  for (int i = m_name; i < n_args; ++i)
     {
       if (args[i] == NULL_TREE)
 	goto fail;
       tree opt = build3 (COMPONENT_REF, TREE_TYPE (args[i]), opts, args[i],
 			 NULL_TREE);
-      if (i == 4)
+      if (i == m_no_unique_address)
 	{
 	  /* The no_unique_address handling is simple.  */
 	  if (TREE_CODE (TREE_TYPE (opt)) != BOOLEAN_TYPE)
@@ -5628,7 +5629,7 @@ eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
 				 NULL_TREE, tf_warning_or_error);
       if (error_operand_p (deref))
 	goto fail;
-      if (i != 1)
+      if (i != m_name)
 	{
 	  /* For alignment and bit_width otherwise it should be int.  */
 	  if (TYPE_MAIN_VARIANT (TREE_TYPE (deref)) != integer_type_node)
@@ -5646,27 +5647,29 @@ eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
       /* Otherwise it is a name.  */
       if (!CLASS_TYPE_P (TREE_TYPE (deref)))
 	goto fail;
-      tree fields[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
+      enum { m_is_u8, m_u8s, m_s, n_fields };
+      tree fields[n_fields] = { NULL_TREE, NULL_TREE, NULL_TREE };
       for (tree field = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (deref)));
 	   field; field = next_aggregate_field (DECL_CHAIN (field)))
 	if (tree name = DECL_NAME (field))
 	  {
 	    if (id_equal (name, "_M_is_u8"))
-	      fields[0] = field;
+	      fields[m_is_u8] = field;
 	    else if (id_equal (name, "_M_u8s"))
-	      fields[1] = field;
+	      fields[m_u8s] = field;
 	    else if (id_equal (name, "_M_s"))
-	      fields[2] = field;
+	      fields[m_s] = field;
 	  }
-      for (int j = 0; j < 3; ++j)
+      for (int j = 0; j < n_fields; ++j)
 	{
 	  if (fields[j] == NULL_TREE)
 	    goto fail;
-	  if (j && j == (fields[0] == boolean_true_node ? 2 : 1))
+	  if (j != m_is_u8
+	      && j == (fields[m_is_u8] == boolean_true_node ? m_s : m_u8s))
 	    continue;
 	  tree f = build3 (COMPONENT_REF, TREE_TYPE (fields[j]), deref,
 			   fields[j], NULL_TREE);
-	  if (j == 0)
+	  if (j == m_is_u8)
 	    {
 	      /* The _M_is_u8 handling is simple.  */
 	      if (TREE_CODE (TREE_TYPE (f)) != BOOLEAN_TYPE)
@@ -5679,9 +5682,9 @@ eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
 	      if (TREE_CODE (f) != INTEGER_CST)
 		goto fail;
 	      if (integer_zerop (f))
-		fields[0] = boolean_false_node;
+		fields[m_is_u8] = boolean_false_node;
 	      else
-		fields[0] = boolean_true_node;
+		fields[m_is_u8] = boolean_true_node;
 	      continue;
 	    }
 	  /* _M_u8s/_M_s handling is the same except for encoding.  */
@@ -5713,7 +5716,7 @@ eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
 	      || TREE_CODE (TREE_TYPE (f)) != ARRAY_TYPE)
 	    goto fail;
 	  tree eltt = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (f)));
-	  if (eltt != (j == 1 ? char8_type_node : char_type_node))
+	  if (eltt != (j == m_u8s ? char8_type_node : char_type_node))
 	    goto fail;
 	  tree field, value;
 	  unsigned k;
@@ -5794,12 +5797,12 @@ eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
 	  istr.len = strlen (namep) + 1;
 	  istr.text = (const unsigned char *) namep;
 	  if (!cpp_translate_string (parse_in, &istr, &ostr,
-				     j == 2 ? CPP_STRING : CPP_UTF8STRING,
+				     j == m_s ? CPP_STRING : CPP_UTF8STRING,
 				     true))
 	    {
 	      if (len >= 64)
 		XDELETEVEC (namep);
-	      if (j == 2)
+	      if (j == m_s)
 		return throw_exception (loc, ctx,
 					"conversion from ordinary literal "
 					"encoding to source charset "
@@ -5831,53 +5834,53 @@ eval_data_member_spec (location_t loc, const constexpr_ctx *ctx,
 	    }
 	}
     }
-  if (args[1] == NULL_TREE && args[3] == NULL_TREE)
+  if (args[m_name] == NULL_TREE && args[m_bit_width] == NULL_TREE)
     return throw_exception (loc, ctx,
 			    "neither name nor bit_width specified",
 			    fun, non_constant_p, jump_target);
-  if (args[3])
+  if (args[m_bit_width])
     {
       if (!CP_INTEGRAL_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
 	return throw_exception (loc, ctx,
 				"bit_width specified with non-integral "
 				"and non-enumeration type",
 				fun, non_constant_p, jump_target);
-      if (args[2])
+      if (args[m_alignment])
 	return throw_exception (loc, ctx,
 				"both alignment and bit_width specified",
 				fun, non_constant_p, jump_target);
-      if (args[4] == boolean_true_node)
+      if (args[m_no_unique_address] == boolean_true_node)
 	return throw_exception (loc, ctx,
 				"bit_width specified with "
 				"no_unique_address true",
 				fun, non_constant_p, jump_target);
-      if (integer_zerop (args[3]) && args[1])
+      if (integer_zerop (args[m_bit_width]) && args[m_name])
 	return throw_exception (loc, ctx,
 				"bit_width 0 with specified name",
 				fun, non_constant_p, jump_target);
-      if (tree_int_cst_sgn (args[3]) < 0)
+      if (tree_int_cst_sgn (args[m_bit_width]) < 0)
 	return throw_exception (loc, ctx, "bit_width is negative",
 				fun, non_constant_p, jump_target);
     }
-  if (args[2])
+  if (args[m_alignment])
     {
-      if (!integer_pow2p (args[2]))
+      if (!integer_pow2p (args[m_alignment]))
 	return throw_exception (loc, ctx,
 				"alignment is not power of two",
 				fun, non_constant_p, jump_target);
-      if (tree_int_cst_sgn (args[2]) < 0)
+      if (tree_int_cst_sgn (args[m_alignment]) < 0)
 	return throw_exception (loc, ctx, "alignment is negative",
 				fun, non_constant_p, jump_target);
       tree al = cxx_sizeof_or_alignof_type (loc, type, ALIGNOF_EXPR, true,
 					    tf_none);
       if (TREE_CODE (al) == INTEGER_CST
-	  && wi::to_widest (al) > wi::to_widest (args[2]))
+	  && wi::to_widest (al) > wi::to_widest (args[m_alignment]))
 	return throw_exception (loc, ctx,
 				"alignment is smaller than alignment_of",
 				fun, non_constant_p, jump_target);
     }
-  tree ret = make_tree_vec (5);
-  for (int i = 0; i < 5; ++i)
+  tree ret = make_tree_vec (n_args);
+  for (int i = 0; i < n_args; ++i)
     TREE_VEC_ELT (ret, i) = args[i];
   return get_reflection_raw (loc, ret, REFLECT_DATA_MEMBER_SPEC);
 }


More information about the Gcc-cvs mailing list