[PATCH v2 07/17] gdb: split make_type_with_address_space

Tankut Baris Aktemur <[email protected]> Wed, 22 Jul 2026 05:41:56 -0500
Newsgroups gmane.comp.gdb.patches
Message-ID <20260722-users-aktemur-type-instance-flags-v2-7-d60dcbc2a76f@amd.com>
The function make_type_with_address_space is used for creating a type
variant with a particular Harvard address space or an address class
id.  The argument is type instance flags.  Split the function into
two, each doing one task: (1) making a type variant with a given
Harvard address space id, and (2) making a type variant with a given
address class id.  This is a step towards making function signatures
clearer and more descriptive.

Hardcoded shift operations ("<< 2", "<< 4", ">> 4") will go away in a
future patch.
---
 gdb/dwarf2/read.c |  6 +-----
 gdb/gdbtypes.c    | 42 +++++++++++++++++++++++++++++++++---------
 gdb/gdbtypes.h    | 54 ++++++++++++++++++++++++++++++++++--------------------
 gdb/gnu-v3-abi.c  |  2 +-
 gdb/printcmd.c    | 13 ++++++++++++-
 gdb/type-stack.c  | 27 +++++++++++++++++----------
 6 files changed, 98 insertions(+), 46 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3671e39daa2..ce4d6ca8675 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -12056,11 +12056,7 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
 	  unsigned int aclass
 	    = gdbarch_address_class_dwarf_to_id (gdbarch, byte_size,
 						 addr_class);
-	  type_instance_flags type_flags
-	    = (enum type_instance_flag_value) (aclass << 4);
-	  gdb_assert ((type_flags & ~TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
-		      == 0);
-	  type = make_type_with_address_space (type, type_flags);
+	  type = make_type_with_address_class (type, aclass);
 	}
       else if (type->length () != byte_size)
 	{
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 97f1b3e1417..aa80dfb51c0 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -590,7 +590,7 @@ make_qualified_type (struct type *type, type_instance_flags new_flags,
   return ntype;
 }
 
-/* Make an address-space-delimited variant of a type -- a type that
+/* Make a Harvard-address-space-delimited variant of a type -- a type that
    is identical to the one supplied except that it has an address
    space attribute attached to it (such as "code" or "data").
 
@@ -600,16 +600,40 @@ make_qualified_type (struct type *type, type_instance_flags new_flags,
    representations.  */
 
 struct type *
-make_type_with_address_space (struct type *type,
-			      type_instance_flags space_flag)
+make_type_with_harvard_address_space (struct type *type,
+				      enum harvard_address_space aspace)
 {
-  type_instance_flags new_flags = ((type->instance_flags ()
-				    & ~(TYPE_INSTANCE_FLAG_CODE_SPACE
-					| TYPE_INSTANCE_FLAG_DATA_SPACE
-					| TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL))
-				   | space_flag);
+  type_instance_flags new_flags
+    = (enum type_instance_flag_value) (aspace << 2);
 
-  return make_qualified_type (type, new_flags, NULL);
+  gdb_assert ((new_flags & ~(TYPE_INSTANCE_FLAG_CODE_SPACE
+			     | TYPE_INSTANCE_FLAG_DATA_SPACE)) == 0);
+  new_flags |= (type->instance_flags ()
+		& ~(TYPE_INSTANCE_FLAG_CODE_SPACE
+		    | TYPE_INSTANCE_FLAG_DATA_SPACE));
+
+  return make_qualified_type (type, new_flags, nullptr);
+}
+
+/* Make an address-class-delimited variant of a type -- a type that is
+   identical to the one supplied except that it has an address class
+   attribute attached to it.  The address class attribute is
+   architecture specific.  It may denote an alternately sized pointer
+   or a pointer with alternate representation.  */
+
+struct type *
+make_type_with_address_class (struct type *type,
+			      unsigned int address_class)
+{
+  type_instance_flags new_flags
+    = (enum type_instance_flag_value) (address_class << 4);
+
+  gdb_assert ((new_flags & ~TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL) == 0);
+
+  new_flags |= (type->instance_flags ()
+		& ~TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL);
+
+  return make_qualified_type (type, new_flags, nullptr);
 }
 
 /* See gdbtypes.h.  */
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 1d5c96ab2c1..1749c3ba741 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -71,6 +71,34 @@ enum type_code
 
   };
 
+/* Enum encoded in instance flags of a type to denote which Harvard
+   address space the type refers to.
+
+   Harvard architectures have separate instruction and data address
+   spaces (and perhaps others).  GDB usually defines a flat address
+   space that is a superset of the architecture's two (or more)
+   address spaces, but this is an extension of the architecture's
+   model.
+
+   If using HARVARD_ASPACE_CODE, an object of the corresponding type
+   resides in instruction memory, even if its address (in the extended
+   flat address space) does not reflect this.
+
+   Similarly, if using HARVARD_ASPACE_DATA, then an object of the
+   corresponding type resides in the data memory space, even if this
+   is not indicated by its (flat address space) address.
+
+   If using HARVARD_ASPACE_NONE, the default space for functions /
+   methods is instruction space, and for data objects is data
+   memory.  */
+
+enum harvard_address_space
+{
+  HARVARD_ASPACE_NONE = 0,
+  HARVARD_ASPACE_CODE = 1,
+  HARVARD_ASPACE_DATA = 2,
+};
+
 /* Some bits for the type's instance_flags word.  See the macros
    below for documentation on each bit.  */
 
@@ -135,24 +163,7 @@ DEF_ENUM_FLAGS_TYPE (enum type_instance_flag_value, type_instance_flags);
   (((t)->dyn_prop (DYN_PROP_BYTE_SIZE) != nullptr)	\
    || ((t)->dyn_prop (DYN_PROP_BIT_SIZE) != nullptr))
 
-/* Instruction-space delimited type.  This is for Harvard architectures
-   which have separate instruction and data address spaces (and perhaps
-   others).
-
-   GDB usually defines a flat address space that is a superset of the
-   architecture's two (or more) address spaces, but this is an extension
-   of the architecture's model.
-
-   If TYPE_INSTANCE_FLAG_CODE_SPACE is set, an object of the corresponding type
-   resides in instruction memory, even if its address (in the extended
-   flat address space) does not reflect this.
-
-   Similarly, if TYPE_INSTANCE_FLAG_DATA_SPACE is set, then an object of the
-   corresponding type resides in the data memory space, even if
-   this is not indicated by its (flat address space) address.
-
-   If neither flag is set, the default space for functions / methods
-   is instruction space, and for data objects is data memory.  */
+/* See enum harvard_address_space above.  */
 
 #define TYPE_CODE_SPACE(t) \
   ((((t)->instance_flags ()) & TYPE_INSTANCE_FLAG_CODE_SPACE) != 0)
@@ -2420,8 +2431,11 @@ extern struct type *make_atomic_type (struct type *);
 
 extern void replace_type (struct type *, struct type *);
 
-extern struct type *make_type_with_address_space
-  (struct type *type, type_instance_flags space_identifier);
+extern struct type *make_type_with_harvard_address_space
+  (struct type *type, enum harvard_address_space aspace);
+
+extern struct type *make_type_with_address_class
+  (struct type *type, unsigned int address_class);
 
 /* Implement direct support for MEMBER_TYPE in GNU C++.
    TO_TYPE is the type of the member.  DOMAIN is the type of the aggregate that
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index 35910be0f06..52e31776242 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -184,7 +184,7 @@ get_gdb_vtable_type (struct gdbarch *arch)
   t->set_name ("gdb_gnu_v3_abi_vtable");
   INIT_CPLUS_SPECIFIC (t);
 
-  result = make_type_with_address_space (t, TYPE_INSTANCE_FLAG_CODE_SPACE);
+  result = make_type_with_harvard_address_space (t, HARVARD_ASPACE_CODE);
   vtable_type_gdbarch_data.set (arch, result);
   return result;
 }
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 15c086a9284..b79dbe24c17 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1055,7 +1055,18 @@ format_to_type (format_data fmt, gdbarch *gdbarch, type_instance_flags flags)
     }
 
   gdb_assert (val_type != nullptr);
-  val_type = make_type_with_address_space (val_type, flags);
+
+  if ((flags & TYPE_INSTANCE_FLAG_CODE_SPACE) != 0)
+    val_type = make_type_with_harvard_address_space (val_type,
+						     HARVARD_ASPACE_CODE);
+  else if ((flags & TYPE_INSTANCE_FLAG_DATA_SPACE) != 0)
+    val_type = make_type_with_harvard_address_space (val_type,
+						     HARVARD_ASPACE_DATA);
+
+  unsigned int aclass
+    = (unsigned int) (flags & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL) >> 4;
+  if (aclass != 0)
+    val_type = make_type_with_address_class (val_type, aclass);
 
   return val_type;
 }
diff --git a/gdb/type-stack.c b/gdb/type-stack.c
index dce1a138e36..c5ff1d718c4 100644
--- a/gdb/type-stack.c
+++ b/gdb/type-stack.c
@@ -57,12 +57,12 @@ type_stack::insert (struct gdbarch *gdbarch, const char *string)
   if (streq (string, "code"))
     {
       insert_into (slot, tp_harvard_aspace_identifier);
-      insert_into (slot, TYPE_INSTANCE_FLAG_CODE_SPACE);
+      insert_into (slot, HARVARD_ASPACE_CODE);
     }
   else if (streq (string, "data"))
     {
       insert_into (slot, tp_harvard_aspace_identifier);
-      insert_into (slot, TYPE_INSTANCE_FLAG_DATA_SPACE);
+      insert_into (slot, HARVARD_ASPACE_DATA);
     }
   else if (unsigned int aclass = 0;
 	   gdbarch_address_class_name_to_id_p (gdbarch)
@@ -71,7 +71,7 @@ type_stack::insert (struct gdbarch *gdbarch, const char *string)
 						aclass))
     {
       insert_into (slot, tp_aclass_identifier);
-      insert_into (slot, (enum type_instance_flag_value) (aclass << 4));
+      insert_into (slot, aclass);
     }
   else
     error (_("Unknown address space/class specifier: \"%s\""), string);
@@ -114,7 +114,8 @@ type_stack::follow_types (struct type *follow_type)
   int done = 0;
   int make_const = 0;
   int make_volatile = 0;
-  type_instance_flags make_addr_space = 0;
+  harvard_address_space make_harvard_aspace = HARVARD_ASPACE_NONE;
+  int make_address_class = 0;
   bool make_restrict = false;
   bool make_atomic = false;
   int array_size;
@@ -133,10 +134,10 @@ type_stack::follow_types (struct type *follow_type)
 	make_volatile = 1;
 	break;
       case tp_harvard_aspace_identifier:
-	make_addr_space = (enum type_instance_flag_value) pop_int ();
+	make_harvard_aspace = (harvard_address_space) pop_int ();
 	break;
       case tp_aclass_identifier:
-	make_addr_space = (enum type_instance_flag_value) pop_int ();
+	make_address_class = pop_int ();
 	break;
       case tp_atomic:
 	make_atomic = true;
@@ -161,15 +162,21 @@ type_stack::follow_types (struct type *follow_type)
 	  follow_type = make_cv_type (TYPE_CONST (follow_type),
 				      make_volatile,
 				      follow_type);
-	if (make_addr_space)
-	  follow_type = make_type_with_address_space (follow_type,
-						      make_addr_space);
+	if (make_harvard_aspace != HARVARD_ASPACE_NONE)
+	  follow_type
+	    = make_type_with_harvard_address_space (follow_type,
+						    make_harvard_aspace);
+	if (make_address_class != 0)
+	  follow_type
+	    = make_type_with_address_class (follow_type,
+					    make_address_class);
 	if (make_restrict)
 	  follow_type = make_restrict_type (follow_type);
 	if (make_atomic)
 	  follow_type = make_atomic_type (follow_type);
 	make_const = make_volatile = 0;
-	make_addr_space = 0;
+	make_harvard_aspace = HARVARD_ASPACE_NONE;
+	make_address_class = 0;
 	make_restrict = make_atomic = false;
 	break;
       case tp_array:

-- 
2.34.1