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.
This commit is contained in:
Michael Snyder 2001-11-15 01:55:59 +00:00
parent 73d074b4e2
commit 47663de598
7 changed files with 242 additions and 46 deletions

View 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

View 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_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); }
;
const_or_volatile: const_or_volatile_noopt
|
|
;
cv_with_space_id : const_or_volatile space_identifier const_or_volatile
;
const_or_volatile_or_space_identifier_noopt: cv_with_space_id
| 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

View 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);
@ -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

View 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 */

View 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

View 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 ();

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