2001-11-14 Michael Snyder <msnyder@redhat.com>
authorMichael Snyder <msnyder@vmware.com>
Thu, 15 Nov 2001 01:55:59 +0000 (01:55 +0000)
committerMichael Snyder <msnyder@vmware.com>
Thu, 15 Nov 2001 01:55:59 +0000 (01:55 +0000)
Add address space identifiers to expression language for types.
* c-exp.y (space_identifier, cv_with_space_id,
const_or_volatile_or_space_identifier_noopt,
const_or_volatile_or_space_identifier): New terminals.
(ptype): Accept const_or_volatile_or_space_identifier.
(typebase): Accept const_or_volatile_or_space_identifier.
* c-typeprint.c (c_type_print_cv_qualifier): Rename to
c_type_print_modifier.  Handle address space modified types.
* gdbtypes.h (TYPE_FLAG_CODE_SPACE, TYPE_FLAG_DATA_SPACE):
New type flags.
(struct type): Add new field as_type for addr-space qualified types.
(TYPE_AS_TYPE): New macro, retrieves the chain of types that are
identical to this one except for address-space qualification.
* gdbtypes.c (alloc_type): Initialize new field 'as_type'.
(address_space_name_to_int): New function.
(address_space_int_to_name): New function.
(make_type_with_address_space): New function.
(make_cv_type): Handle as_type field of new struct type object.
* parse.c (check_type_stack_depth): New function.
(push_type_address_space): New function.
(follow_types): Handle types with address-space qualifier.
* parser-defs.h (enum type_pieces): Add enum tp_space_identifier.

gdb/ChangeLog
gdb/c-exp.y
gdb/c-typeprint.c
gdb/gdbtypes.c
gdb/gdbtypes.h
gdb/parse.c
gdb/parser-defs.h

index f13b54a22a9615a893d1e822621889c97b44ec95..9a60f6af65fcbeafc175111d6bac43bcd8d35391 100644 (file)
@@ -1,3 +1,27 @@
+2001-11-14  Michael Snyder  <msnyder@redhat.com>
+       Add address space identifiers to expression language for types.
+       * c-exp.y (space_identifier, cv_with_space_id, 
+       const_or_volatile_or_space_identifier_noopt, 
+       const_or_volatile_or_space_identifier): New terminals.
+       (ptype): Accept const_or_volatile_or_space_identifier.
+       (typebase): Accept const_or_volatile_or_space_identifier.
+       * c-typeprint.c (c_type_print_cv_qualifier): Rename to
+       c_type_print_modifier.  Handle address space modified types.
+       * gdbtypes.h (TYPE_FLAG_CODE_SPACE, TYPE_FLAG_DATA_SPACE):
+       New type flags.
+       (struct type): Add new field as_type for addr-space qualified types.
+       (TYPE_AS_TYPE): New macro, retrieves the chain of types that are
+       identical to this one except for address-space qualification.
+       * gdbtypes.c (alloc_type): Initialize new field 'as_type'.
+       (address_space_name_to_int): New function.
+       (address_space_int_to_name): New function.
+       (make_type_with_address_space): New function.
+       (make_cv_type): Handle as_type field of new struct type object.
+       * parse.c (check_type_stack_depth): New function.
+       (push_type_address_space): New function.
+       (follow_types): Handle types with address-space qualifier.
+       * parser-defs.h (enum type_pieces): Add enum tp_space_identifier.
+
 2001-11-14  Jim Blandy  <jimb@redhat.com>
 
        * s390-tdep.c (s390_pop_frame_regular): On the S/390, the frame
index 66057518f2820e86206372a782f279da5bc7be73..3d2d1aa661f724b0b87b521359f1fb89b74e2e7b 100644 (file)
@@ -718,24 +718,28 @@ variable: name_not_typename
                        }
        ;
 
+space_identifier : '@' NAME
+               { push_type_address_space (copy_name ($2.stoken));
+                 push_type (tp_space_identifier);
+               }
+       ;
 
-ptype  :       typebase
-       |       ptype const_or_volatile abs_decl const_or_volatile
-               { $$ = follow_types ($1); }
+const_or_volatile: const_or_volatile_noopt
+       |
        ;
-const_and_volatile:    CONST_KEYWORD VOLATILE_KEYWORD
-       |               VOLATILE_KEYWORD CONST_KEYWORD
+
+cv_with_space_id : const_or_volatile space_identifier const_or_volatile
        ;
-const_or_volatile_noopt:       const_and_volatile 
-                       { push_type (tp_const); push_type (tp_volatile);}
-       |               CONST_KEYWORD
-                       { push_type (tp_const);}
-       |               VOLATILE_KEYWORD
-                       { push_type (tp_volatile); }
+
+const_or_volatile_or_space_identifier_noopt: cv_with_space_id
+       | const_or_volatile_noopt 
        ;
-const_or_volatile: const_or_volatile_noopt
-       | 
+
+const_or_volatile_or_space_identifier: 
+               const_or_volatile_or_space_identifier_noopt
+       |
        ;
+
 abs_decl:      '*'
                        { push_type (tp_pointer); $$ = 0; }
        |       '*' abs_decl
@@ -852,8 +856,10 @@ typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
                        { $$ = lookup_template_type(copy_name($2), $4,
                                                    expression_context_block);
                        }
-       | const_or_volatile_noopt typebase { $$ = follow_types ($2); }
-       | typebase const_or_volatile_noopt { $$ = follow_types ($1); }
+       | const_or_volatile_or_space_identifier_noopt typebase 
+                       { $$ = follow_types ($2); }
+       | typebase const_or_volatile_or_space_identifier_noopt 
+                       { $$ = follow_types ($1); }
        ;
 
 typename:      TYPENAME
@@ -890,6 +896,25 @@ nonempty_typelist
                }
        ;
 
+ptype  :       typebase
+       |       ptype const_or_volatile_or_space_identifier abs_decl const_or_volatile_or_space_identifier
+               { $$ = follow_types ($1); }
+       ;
+
+const_and_volatile:    CONST_KEYWORD VOLATILE_KEYWORD
+       |               VOLATILE_KEYWORD CONST_KEYWORD
+       ;
+
+const_or_volatile_noopt:       const_and_volatile 
+                       { push_type (tp_const);
+                         push_type (tp_volatile); 
+                       }
+       |               CONST_KEYWORD
+                       { push_type (tp_const); }
+       |               VOLATILE_KEYWORD
+                       { push_type (tp_volatile); }
+       ;
+
 name   :       NAME { $$ = $1.stoken; }
        |       BLOCKNAME { $$ = $1.stoken; }
        |       TYPENAME { $$ = $1.stoken; }
@@ -1683,7 +1708,7 @@ yylex ()
          return TYPENAME;
         }
     if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
-       return TYPENAME;
+      return TYPENAME;
 
     /* Input names that aren't symbols but ARE valid hex numbers,
        when the input radix permits them, can be names or numbers
index 789d5f0b2df0594e2e62b2e9b8dd6016f195201a..c83002956867b385493e7e43c1652d63d4ab6ca3 100644 (file)
@@ -52,8 +52,9 @@ static void cp_type_print_derivation_info (struct ui_file *, struct type *);
 void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
                                  int);
 
-static void c_type_print_cv_qualifier (struct type *, struct ui_file *,
-                                      int, int);
+/* Print "const", "volatile", or address space modifiers. */
+static void c_type_print_modifier (struct type *, struct ui_file *,
+                                  int, int);
 \f
 
 
@@ -211,7 +212,7 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
     case TYPE_CODE_PTR:
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
       fprintf_filtered (stream, "*");
-      c_type_print_cv_qualifier (type, stream, 1, 0);
+      c_type_print_modifier (type, stream, 1, 0);
       break;
 
     case TYPE_CODE_MEMBER:
@@ -242,7 +243,7 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
     case TYPE_CODE_REF:
       c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
       fprintf_filtered (stream, "&");
-      c_type_print_cv_qualifier (type, stream, 1, 0);
+      c_type_print_modifier (type, stream, 1, 0);
       break;
 
     case TYPE_CODE_FUNC:
@@ -289,10 +290,11 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
    NEED_SPACE = 1 indicates an initial white space is needed */
 
 static void
-c_type_print_cv_qualifier (struct type *type, struct ui_file *stream,
-                          int need_pre_space, int need_post_space)
+c_type_print_modifier (struct type *type, struct ui_file *stream,
+                      int need_pre_space, int need_post_space)
 {
-  int flag = 0;
+  int did_print_modifier = 0;
+  char *address_space_id;
 
   /* We don't print `const' qualifiers for references --- since all
      operators affect the thing referenced, not the reference itself,
@@ -303,18 +305,27 @@ c_type_print_cv_qualifier (struct type *type, struct ui_file *stream,
       if (need_pre_space)
        fprintf_filtered (stream, " ");
       fprintf_filtered (stream, "const");
-      flag = 1;
+      did_print_modifier = 1;
     }
 
   if (TYPE_VOLATILE (type))
     {
-      if (flag || need_pre_space)
+      if (did_print_modifier || need_pre_space)
        fprintf_filtered (stream, " ");
       fprintf_filtered (stream, "volatile");
-      flag = 1;
+      did_print_modifier = 1;
     }
 
-  if (flag && need_post_space)
+  address_space_id = address_space_int_to_name (TYPE_FLAGS (type));
+  if (address_space_id)
+    {
+      if (did_print_modifier || need_pre_space)
+       fprintf_filtered (stream, " ");
+      fprintf_filtered (stream, "@%s", address_space_id);
+      did_print_modifier = 1;
+    }
+
+  if (did_print_modifier && need_post_space)
     fprintf_filtered (stream, " ");
 }
 
@@ -655,7 +666,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
   if (show <= 0
       && TYPE_NAME (type) != NULL)
     {
-      c_type_print_cv_qualifier (type, stream, 0, 1);
+      c_type_print_modifier (type, stream, 0, 1);
       fputs_filtered (TYPE_NAME (type), stream);
       return;
     }
@@ -675,7 +686,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
       break;
 
     case TYPE_CODE_STRUCT:
-      c_type_print_cv_qualifier (type, stream, 0, 1);
+      c_type_print_modifier (type, stream, 0, 1);
       /* Note TYPE_CODE_STRUCT and TYPE_CODE_CLASS have the same value,
        * so we use another means for distinguishing them.
        */
@@ -708,7 +719,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
       goto struct_union;
 
     case TYPE_CODE_UNION:
-      c_type_print_cv_qualifier (type, stream, 0, 1);
+      c_type_print_modifier (type, stream, 0, 1);
       fprintf_filtered (stream, "union ");
 
     struct_union:
@@ -1023,7 +1034,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
       break;
 
     case TYPE_CODE_ENUM:
-      c_type_print_cv_qualifier (type, stream, 0, 1);
+      c_type_print_modifier (type, stream, 0, 1);
       /* HP C supports sized enums */
       if (hp_som_som_object_present)
        switch (TYPE_LENGTH (type))
@@ -1104,7 +1115,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
          template <class T1, class T2> class "
          and then merges with the struct/union/class code to
          print the rest of the definition. */
-      c_type_print_cv_qualifier (type, stream, 0, 1);
+      c_type_print_modifier (type, stream, 0, 1);
       fprintf_filtered (stream, "template <");
       for (i = 0; i < TYPE_NTEMPLATE_ARGS (type); i++)
        {
@@ -1139,7 +1150,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
          is no type name, then complain. */
       if (TYPE_NAME (type) != NULL)
        {
-         c_type_print_cv_qualifier (type, stream, 0, 1);
+         c_type_print_modifier (type, stream, 0, 1);
          fputs_filtered (TYPE_NAME (type), stream);
        }
       else
index bf05cf0080c3d0edb91df6122ca2ce68ea7ba50b..8a941de64ddd6ee31a6362d9ebd033fbb2d2a490 100644 (file)
@@ -146,6 +146,7 @@ alloc_type (struct objfile *objfile)
   TYPE_OBJFILE (type) = objfile;
   TYPE_VPTR_FIELDNO (type) = -1;
   TYPE_CV_TYPE (type) = type;  /* chain back to itself */
+  TYPE_AS_TYPE (type) = type;  /* ditto */
 
   return (type);
 }
@@ -323,6 +324,73 @@ lookup_function_type (struct type *type)
   return make_function_type (type, (struct type **) 0);
 }
 
+/* Identify address space identifier by name --
+   return the integer flag defined in gdbtypes.h.  */
+extern int
+address_space_name_to_int (char *space_identifier)
+{
+  /* Check for known address space delimiters. */
+  if (!strcmp (space_identifier, "code"))
+    return TYPE_FLAG_CODE_SPACE;
+  else if (!strcmp (space_identifier, "data"))
+    return TYPE_FLAG_DATA_SPACE;
+  else
+    error ("Unknown address space specifier: \"%s\"", space_identifier);
+}
+
+/* Identify address space identifier by integer flag as defined in 
+   gdbtypes.h -- return the string version of the adress space name. */
+
+extern char *
+address_space_int_to_name (int space_flag)
+{
+  if (space_flag & TYPE_FLAG_CODE_SPACE)
+    return "code";
+  else if (space_flag & TYPE_FLAG_DATA_SPACE)
+    return "data";
+  else
+    return NULL;
+}
+
+/* Make an 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").
+
+   This is for Harvard architectures. */
+
+struct type *
+make_type_with_address_space (struct type *type, int space_flag)
+{
+  struct type *ntype;
+
+  ntype = type;
+  do {
+    if ((ntype->flags & space_flag) != 0)
+      return ntype;
+    ntype = TYPE_AS_TYPE (ntype);
+  } while (ntype != type);
+
+  /* Create a new, duplicate type. */
+  ntype = alloc_type (TYPE_OBJFILE (type));
+  /* Copy original type. */
+  memcpy ((char *) ntype, (char *) type, sizeof (struct type));
+
+  /* Pointers or references to the original type are not relevant to
+     the new type; but if the original type is a pointer, the new type
+     points to the same thing (so TYPE_TARGET_TYPE remains unchanged). */
+  TYPE_POINTER_TYPE (ntype) = (struct type *) 0;
+  TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;
+  TYPE_CV_TYPE (ntype) = ntype;
+
+  /* Chain the new address-space-specific type to the old type. */
+  ntype->as_type = type->as_type;
+  type->as_type = ntype;
+
+  /* Now set the address-space flag, and return the new type. */
+  ntype->flags |= space_flag;
+  return ntype;
+}
+
 
 /* Make a "c-v" variant of a type -- a type that is identical to the
    one supplied except that it may have const or volatile attributes
@@ -380,6 +448,7 @@ make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr)
   /* But zero out fields that shouldn't be copied */
   TYPE_POINTER_TYPE (ntype) = (struct type *) 0;       /* Need new pointer kind */
   TYPE_REFERENCE_TYPE (ntype) = (struct type *) 0;     /* Need new referene kind */
+  TYPE_AS_TYPE (ntype) = ntype;                /* Need new address-space kind. */
   /* Note: TYPE_TARGET_TYPE can be left as is */
 
   /* Set flags appropriately */
index 686983c01000c262e15b06a1981becefb7bf5b8e..3bc8131585317b862b60f7e72ce957ab660cc702 100644 (file)
@@ -206,6 +206,28 @@ enum type_code
 
 #define TYPE_FLAG_INCOMPLETE (1 << 8)
 
+/* 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_FLAG_INST 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_FLAG_DATA 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.  */
+
+#define TYPE_FLAG_CODE_SPACE (1 << 9)
+#define TYPE_FLAG_DATA_SPACE (1 << 10)
+
 
 struct type
   {
@@ -310,6 +332,12 @@ struct type
        are chained together in a ring. */
     struct type *cv_type;
 
+    /* Address-space delimited variant chain.  This points to a type
+       that differs from this one only in an address-space qualifier
+       attribute.  The otherwise-identical address-space delimited 
+       types are chained together in a ring. */
+    struct type *as_type;
+
     /* Flags about this type.  */
 
     int flags;
@@ -689,6 +717,7 @@ extern void allocate_cplus_struct_type (struct type *);
 #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
 #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
 #define TYPE_CV_TYPE(thistype) (thistype)->cv_type
+#define TYPE_AS_TYPE(thistype) (thistype)->as_type
 /* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
    But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
    so you only have to call check_typedef once.  Since allocate_value
@@ -1008,6 +1037,13 @@ extern struct type *make_reference_type (struct type *, struct type **);
 
 extern struct type *make_cv_type (int, int, struct type *, struct type **);
 
+extern int address_space_name_to_int (char *);
+
+extern char *address_space_int_to_name (int);
+
+extern struct type *make_type_with_address_space (struct type *type, 
+                                                 int space_identifier);
+
 extern struct type *lookup_member_type (struct type *, struct type *);
 
 extern void
index 64966edf2b5aa543f5a9decda9619a8196cb6a44..42fccc67924967f1978b3b4ca0f0162efe08cc04 100644 (file)
@@ -1208,8 +1208,8 @@ parse_expression (char *string)
 /* Stuff for maintaining a stack of types.  Currently just used by C, but
    probably useful for any language which declares its types "backwards".  */
 
-void
-push_type (enum type_pieces tp)
+static void
+check_type_stack_depth (void)
 {
   if (type_stack_depth == type_stack_size)
     {
@@ -1217,21 +1217,28 @@ push_type (enum type_pieces tp)
       type_stack = (union type_stack_elt *)
        xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
     }
+}
+
+void
+push_type (enum type_pieces tp)
+{
+  check_type_stack_depth ();
   type_stack[type_stack_depth++].piece = tp;
 }
 
 void
 push_type_int (int n)
 {
-  if (type_stack_depth == type_stack_size)
-    {
-      type_stack_size *= 2;
-      type_stack = (union type_stack_elt *)
-       xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
-    }
+  check_type_stack_depth ();
   type_stack[type_stack_depth++].int_val = n;
 }
 
+void
+push_type_address_space (char *string)
+{
+  push_type_int (address_space_name_to_int (string));
+}
+
 enum type_pieces
 pop_type (void)
 {
@@ -1257,6 +1264,7 @@ follow_types (struct type *follow_type)
   int done = 0;
   int make_const = 0;
   int make_volatile = 0;
+  int make_addr_space = 0;
   int array_size;
   struct type *range_type;
 
@@ -1273,6 +1281,11 @@ follow_types (struct type *follow_type)
          follow_type = make_cv_type (TYPE_CONST (follow_type), 
                                      make_volatile, 
                                      follow_type, 0);
+       if (make_addr_space)
+         follow_type = make_type_with_address_space (follow_type, 
+                                                     make_addr_space);
+       make_const = make_volatile = 0;
+       make_addr_space = 0;
        break;
       case tp_const:
        make_const = 1;
@@ -1280,6 +1293,9 @@ follow_types (struct type *follow_type)
       case tp_volatile:
        make_volatile = 1;
        break;
+      case tp_space_identifier:
+       make_addr_space = pop_type_int ();
+       break;
       case tp_pointer:
        follow_type = lookup_pointer_type (follow_type);
        if (make_const)
@@ -1290,15 +1306,27 @@ follow_types (struct type *follow_type)
          follow_type = make_cv_type (TYPE_CONST (follow_type), 
                                      make_volatile, 
                                      follow_type, 0);
+       if (make_addr_space)
+         follow_type = make_type_with_address_space (follow_type, 
+                                                     make_addr_space);
        make_const = make_volatile = 0;
+       make_addr_space = 0;
        break;
       case tp_reference:
        follow_type = lookup_reference_type (follow_type);
        if (make_const)
-         follow_type = make_cv_type (make_const, TYPE_VOLATILE (follow_type), follow_type, 0);
+         follow_type = make_cv_type (make_const, 
+                                     TYPE_VOLATILE (follow_type), 
+                                     follow_type, 0);
        if (make_volatile)
-         follow_type = make_cv_type (TYPE_CONST (follow_type), make_volatile, follow_type, 0);
+         follow_type = make_cv_type (TYPE_CONST (follow_type), 
+                                     make_volatile, 
+                                     follow_type, 0);
+       if (make_addr_space)
+         follow_type = make_type_with_address_space (follow_type, 
+                                                     make_addr_space);
        make_const = make_volatile = 0;
+       make_addr_space = 0;
        break;
       case tp_array:
        array_size = pop_type_int ();
index bd7fb39e4b724c91187c75700dda6e147b1ea06d..66e929f6f3ac20cd7a26250febee9f329dc5b38c 100644 (file)
@@ -90,7 +90,8 @@ enum type_pieces
     tp_array, 
     tp_function, 
     tp_const, 
-    tp_volatile
+    tp_volatile, 
+    tp_space_identifier
   };
 /* The stack can contain either an enum type_pieces or an int.  */
 union type_stack_elt
@@ -141,6 +142,8 @@ extern void push_type (enum type_pieces);
 
 extern void push_type_int (int);
 
+extern void push_type_address_space (char *);
+
 extern enum type_pieces pop_type (void);
 
 extern int pop_type_int (void);