]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Compare unqualified names in ada_identical_enum_types_p
authorTom Tromey <tromey@adacore.com>
Mon, 26 Aug 2024 18:54:17 +0000 (12:54 -0600)
committerTom Tromey <tromey@adacore.com>
Thu, 6 Mar 2025 21:17:17 +0000 (14:17 -0700)
With the coming changes to GNAT, gdb must compare the unqualified
names of two enum types.

Currently, GNAT will fully-qualify enumeration constant names, so for
instance one might see "enum_with_gap__lit4" as the name.

GNAT also may emit a copy of an enumeration type when a newtype is
involved.  E.g., in the arr_acc_idx_w_gap.exp test case, this can
occur for the base type of this subtype:

   type Enum_Subrange is new Enum_With_Gaps range Lit1 .. Lit3;

(Note that the base type of this subrange is anonymous.)

With some forthcoming changes to GNAT, these names will no longer be
qualified -- and because the newtype is anonymous, they can't be
identically qualified.  But, in gdb we still want "lit4" to resolve
without ambiguity in this scenario.

The fix is to change ada_identical_enum_types_p to compare unqualified
enum names.  This will work correctly with both variants of the
compiler, and with -fgnat-encodings=all as well.

gdb/ada-lang.c

index d26139b802ffec4b83662ce647be1fcacad95297..ab92f6473ac32f9915bf4fd894867da3e5e50db9 100644 (file)
@@ -203,6 +203,8 @@ static int symbols_are_identical_enums
 
 static bool ada_identical_enum_types_p (struct type *type1,
                                        struct type *type2);
+
+static const char *ada_unqualify_enum_name (const char *name);
 \f
 
 /* The character set used for source files.  */
@@ -4976,8 +4978,8 @@ ada_identical_enum_types_p (struct type *type1, struct type *type2)
      suffix).  */
   for (int i = 0; i < type1->num_fields (); i++)
     {
-      const char *name_1 = type1->field (i).name ();
-      const char *name_2 = type2->field (i).name ();
+      const char *name_1 = ada_unqualify_enum_name (type1->field (i).name ());
+      const char *name_2 = ada_unqualify_enum_name (type2->field (i).name ());
       int len_1 = strlen (name_1);
       int len_2 = strlen (name_2);
 
@@ -8951,15 +8953,12 @@ ada_aligned_value_addr (struct type *type, const gdb_byte *valaddr)
 }
 
 
+/* Remove qualifications from the enumeration constant named NAME,
+   returning a pointer to the constant's base name.  */
 
-/* The printed representation of an enumeration literal with encoded
-   name NAME.  The value is good to the next call of ada_enum_name.  */
-const char *
-ada_enum_name (const char *name)
+static const char *
+ada_unqualify_enum_name (const char *name)
 {
-  static std::string storage;
-  const char *tmp;
-
   /* First, unqualify the enumeration name:
      1. Search for the last '.' character.  If we find one, then skip
      all the preceding characters, the unqualified name starts
@@ -8969,7 +8968,7 @@ ada_enum_name (const char *name)
      but stop searching when we hit an overloading suffix, which is
      of the form "__" followed by digits.  */
 
-  tmp = strrchr (name, '.');
+  const char *tmp = strrchr (name, '.');
   if (tmp != NULL)
     name = tmp + 1;
   else
@@ -8983,6 +8982,17 @@ ada_enum_name (const char *name)
        }
     }
 
+  return name;
+}
+
+/* The printed representation of an enumeration literal with encoded
+   name NAME.  The value is good to the next call of ada_enum_name.  */
+const char *
+ada_enum_name (const char *name)
+{
+  static std::string storage;
+
+  name = ada_unqualify_enum_name (name);
   if (name[0] == 'Q')
     {
       int v;
@@ -9021,7 +9031,7 @@ ada_enum_name (const char *name)
     }
   else
     {
-      tmp = strstr (name, "__");
+      const char *tmp = strstr (name, "__");
       if (tmp == NULL)
        tmp = strstr (name, "$");
       if (tmp != NULL)