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

commit r16-8370-g3c057b70feda8d5f6fd1328ba3a0eeff4411ef21
Author: Jakub Jelinek <[email protected]>
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  <[email protected]>
    
            * 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 <[email protected]>

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);
 }

Reply via email to