[RFC/RFA] gdb extension for Harvard architectures

Michael Snyder
2001-09-28T13:07:00Z

This is an extension to help with debugging on Harvard architectures
(machines with two or more address spaces, typically one for
instructions and one for data). The idea here is to provide the user
with a mechanism for specifying the address space of a pointer or
a raw address (eg. to display the contents of code memory as opposed
to data memory, when the address alone is not enough to differentiate).

Rather than provide extensions for specific commands such as print
and examine, it seemed more useful and general to provide an
extension to the syntax for type expressions. Thus we can identify
a pointer to (say) code address space by using a pointer cast, and
that expression can be used in any command that accepts an expression.

(gdb) x /xb (@code short *) foo
(gdb) print *(@data char *) 0x1000
(gdb) set *(@code long long *) 0x1000 = 0

The idea is that the modifiers "@code" and "@data" can be used
anywhere where it would be legal to use "const" or "volatile".
I've used the "@" character to remove the new keywords from the
user name space, but I'm open to discussion on that choice
("$" might be another possibility).

So, for instance, a (@code int *) would be a pointer to an int in
code space, while a (int * @code) would be a pointer in code space
to an int (presumably in data space).

The idea should be extendable to more address spaces (eg. if
there was an I/O space), and possibly also to segmented architectures.

Here's a somewhat preliminary (but buildable and working) patch:
2001-09-28 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.
* 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.

Index: c-exp.y
===================================================================
RCS file: /cvs/src/src/gdb/c-exp.y,v
retrieving revision 1.6
diff -c -3 -p -r1.6 c-exp.y
*** c-exp.y 2001/09/27 21:16:43 1.6
--- c-exp.y 2001/09/28 19:40:34
*************** variable: name_not_typename
*** 718,741 ****
}
;

!
! 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
! |
;
abs_decl: '*'
{ push_type (tp_pointer); $$ = 0; }
| '*' abs_decl
--- 718,741 ----
}
;

! space_identifier : '@' NAME
! { push_type_address_space (copy_name ($2.stoken));
! push_type (tp_space_identifier);
! }
;
! 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
*************** typebase /* Implements (approximately):
*** 852,859 ****
{ $$ = 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); }
;

typename: TYPENAME
--- 852,861 ----
{ $$ = lookup_template_type(copy_name($2), $4,
expression_context_block);
}
! | const_or_volatile_or_space_identifier_noopt typebase
! { $$ = follow_types ($2); }
! | typebase const_or_volatile_or_space_identifier_noopt
! { $$ = follow_types ($1); }
;

typename: TYPENAME
*************** nonempty_typelist
*** 889,894 ****
--- 891,910 ----
$$[$<ivec>$[0]] = $3;
}
;
+ 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; }
*************** yylex ()
*** 1683,1689 ****
--- 1699,1707 ----
return TYPENAME;
}
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
+ {
return TYPENAME;
+ }

/* Input names that aren't symbols but ARE valid hex numbers,
when the input radix permits them, can be names or numbers
*************** yyerror (msg)
*** 1715,1717 ****
--- 1733,1736 ----
{
error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
}
+
Index: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.11
diff -c -3 -p -r1.11 c-typeprint.c
*** c-typeprint.c 2001/04/27 00:19:09 1.11
--- c-typeprint.c 2001/09/28 19:40:34
*************** static void cp_type_print_derivation_inf
*** 52,59 ****
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);
\f

--- 52,60 ----
void c_type_print_varspec_prefix (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

*************** c_type_print_varspec_prefix (struct type
*** 211,217 ****
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);
break;

case TYPE_CODE_MEMBER:
--- 212,218 ----
case TYPE_CODE_PTR:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
fprintf_filtered (stream, "*");
! c_type_print_modifier (type, stream, 1, 0);
break;

case TYPE_CODE_MEMBER:
*************** c_type_print_varspec_prefix (struct type
*** 242,248 ****
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);
break;

case TYPE_CODE_FUNC:
--- 243,249 ----
case TYPE_CODE_REF:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
fprintf_filtered (stream, "&");
! c_type_print_modifier (type, stream, 1, 0);
break;

case TYPE_CODE_FUNC:
*************** c_type_print_varspec_prefix (struct type
*** 289,298 ****
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)
{
! int flag = 0;

/* We don't print `const' qualifiers for references --- since all
operators affect the thing referenced, not the reference itself,
--- 290,300 ----
NEED_SPACE = 1 indicates an initial white space is needed */

static void
! c_type_print_modifier (struct type *type, struct ui_file *stream,
! int need_pre_space, int need_post_space)
{
! 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,
*************** c_type_print_cv_qualifier (struct type *
*** 303,326 ****
if (need_pre_space)
fprintf_filtered (stream, " ");
fprintf_filtered (stream, "const");
! flag = 1;
}

if (TYPE_VOLATILE (type))
{
! if (flag || need_pre_space)
fprintf_filtered (stream, " ");
fprintf_filtered (stream, "volatile");
! flag = 1;
}

! if (flag && need_post_space)
fprintf_filtered (stream, " ");
}

-
-
-
static void
c_type_print_args (struct type *type, struct ui_file *stream)
{
--- 305,334 ----
if (need_pre_space)
fprintf_filtered (stream, " ");
fprintf_filtered (stream, "const");
! did_print_modifier = 1;
}

if (TYPE_VOLATILE (type))
{
! if (did_print_modifier || need_pre_space)
fprintf_filtered (stream, " ");
fprintf_filtered (stream, "volatile");
! did_print_modifier = 1;
}

! 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, " ");
}

static void
c_type_print_args (struct type *type, struct ui_file *stream)
{
*************** c_type_print_base (struct type *type, st
*** 655,661 ****
if (show <= 0
&& TYPE_NAME (type) != NULL)
{
! c_type_print_cv_qualifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
return;
}
--- 663,669 ----
if (show <= 0
&& TYPE_NAME (type) != NULL)
{
! c_type_print_modifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
return;
}
*************** c_type_print_base (struct type *type, st
*** 675,681 ****
break;

case TYPE_CODE_STRUCT:
! c_type_print_cv_qualifier (type, stream, 0, 1);
/* Note TYPE_CODE_STRUCT and TYPE_CODE_CLASS have the same value,
* so we use another means for distinguishing them.
*/
--- 683,689 ----
break;

case TYPE_CODE_STRUCT:
! 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.
*/
*************** c_type_print_base (struct type *type, st
*** 708,714 ****
goto struct_union;

case TYPE_CODE_UNION:
! c_type_print_cv_qualifier (type, stream, 0, 1);
fprintf_filtered (stream, "union ");

struct_union:
--- 716,722 ----
goto struct_union;

case TYPE_CODE_UNION:
! c_type_print_modifier (type, stream, 0, 1);
fprintf_filtered (stream, "union ");

struct_union:
*************** c_type_print_base (struct type *type, st
*** 1023,1029 ****
break;

case TYPE_CODE_ENUM:
! c_type_print_cv_qualifier (type, stream, 0, 1);
/* HP C supports sized enums */
if (hp_som_som_object_present)
switch (TYPE_LENGTH (type))
--- 1031,1037 ----
break;

case TYPE_CODE_ENUM:
! c_type_print_modifier (type, stream, 0, 1);
/* HP C supports sized enums */
if (hp_som_som_object_present)
switch (TYPE_LENGTH (type))
*************** c_type_print_base (struct type *type, st
*** 1104,1110 ****
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);
fprintf_filtered (stream, "template <");
for (i = 0; i < TYPE_NTEMPLATE_ARGS (type); i++)
{
--- 1112,1118 ----
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_modifier (type, stream, 0, 1);
fprintf_filtered (stream, "template <");
for (i = 0; i < TYPE_NTEMPLATE_ARGS (type); i++)
{
*************** c_type_print_base (struct type *type, st
*** 1139,1145 ****
is no type name, then complain. */
if (TYPE_NAME (type) != NULL)
{
! c_type_print_cv_qualifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
}
else
--- 1147,1153 ----
is no type name, then complain. */
if (TYPE_NAME (type) != NULL)
{
! c_type_print_modifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
}
else
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.25
diff -c -3 -p -r1.25 gdbtypes.c
*** gdbtypes.c 2001/08/24 04:46:43 1.25
--- gdbtypes.c 2001/09/28 19:40:35
*************** alloc_type (struct objfile *objfile)
*** 144,149 ****
--- 144,150 ----
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);
}
*************** lookup_function_type (struct type *type)
*** 321,327 ****
--- 322,396 ----
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
CNST is a flag for setting the const attribute
*************** make_cv_type (int cnst, int voltl, struc
*** 378,383 ****
--- 447,453 ----
/* 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 */
*************** make_cv_type (int cnst, int voltl, struc
*** 398,406 ****
return ntype;
}

-
-
-
/* Implement direct support for MEMBER_TYPE in GNU C++.
May need to construct such a type if this is the first use.
The TYPE is the type of the member. The DOMAIN is the type
--- 468,473 ----
*************** build_gdbtypes (void)
*** 2842,2847 ****
--- 2909,2915 ----
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
0,
"short", (struct objfile *) NULL);
+
builtin_type_unsigned_short =
init_type (TYPE_CODE_INT, TARGET_SHORT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED,
Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.16
diff -c -3 -p -r1.16 gdbtypes.h
*** gdbtypes.h 2001/09/08 10:16:57 1.16
--- gdbtypes.h 2001/09/28 19:40:35
*************** enum type_code
*** 206,212 ****
--- 206,234 ----

#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
{

*************** struct type
*** 310,315 ****
--- 332,343 ----
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;
*************** extern void allocate_cplus_struct_type (
*** 689,694 ****
--- 717,723 ----
#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
*************** extern struct type *lookup_reference_typ
*** 1005,1010 ****
--- 1034,1046 ----
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 *);

Index: parse.c
===================================================================
RCS file: /cvs/src/src/gdb/parse.c,v
retrieving revision 1.16
diff -c -3 -p -r1.16 parse.c
*** parse.c 2001/09/27 22:39:05 1.16
--- parse.c 2001/09/28 19:40:35
*************** parse_expression (char *string)
*** 1208,1215 ****
/* 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)
{
if (type_stack_depth == type_stack_size)
{
--- 1208,1215 ----
/* Stuff for maintaining a stack of types. Currently just used by C, but
probably useful for any language which declares its types "backwards". */

! static void
! check_type_stack_depth (void)
{
if (type_stack_depth == type_stack_size)
{
*************** push_type (enum type_pieces tp)
*** 1217,1237 ****
type_stack = (union type_stack_elt *)
xrealloc ((char *) type_stack, type_stack_size * sizeof (*type_stack));
}
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));
! }
type_stack[type_stack_depth++].int_val = n;
}

enum type_pieces
pop_type (void)
{
--- 1217,1244 ----
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)
{
! 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)
{
*************** follow_types (struct type *follow_type)
*** 1257,1262 ****
--- 1264,1270 ----
int done = 0;
int make_const = 0;
int make_volatile = 0;
+ int make_addr_space = 0;
int array_size;
struct type *range_type;

*************** follow_types (struct type *follow_type)
*** 1273,1278 ****
--- 1281,1291 ----
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;
*************** follow_types (struct type *follow_type)
*** 1280,1285 ****
--- 1293,1301 ----
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)
*************** follow_types (struct type *follow_type)
*** 1290,1304 ****
follow_type = make_cv_type (TYPE_CONST (follow_type),
make_volatile,
follow_type, 0);
make_const = make_volatile = 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);
if (make_volatile)
! follow_type = make_cv_type (TYPE_CONST (follow_type), make_volatile, follow_type, 0);
make_const = make_volatile = 0;
break;
case tp_array:
array_size = pop_type_int ();
--- 1306,1332 ----
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);
if (make_volatile)
! 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: parser-defs.h
===================================================================
RCS file: /cvs/src/src/gdb/parser-defs.h,v
retrieving revision 1.5
diff -c -3 -p -r1.5 parser-defs.h
*** parser-defs.h 2001/09/27 22:39:05 1.5
--- parser-defs.h 2001/09/28 19:40:36
*************** enum type_pieces
*** 90,96 ****
tp_array,
tp_function,
tp_const,
! tp_volatile
};
/* The stack can contain either an enum type_pieces or an int. */
union type_stack_elt
--- 90,97 ----
tp_array,
tp_function,
tp_const,
! tp_volatile,
! tp_space_identifier
};
/* The stack can contain either an enum type_pieces or an int. */
union type_stack_elt
*************** extern char *copy_name (struct stoken);
*** 140,145 ****
--- 141,148 ----
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);

From ac131313@cygnus.com Fri Sep 28 13:34:00 2001
From: Andrew Cagney <ac131313@cygnus.com>
To: Daniel Jacobowitz <drow@mvista.com>, fnasser@cygnus.com
Cc: gdb-patches@sources.redhat.com
Subject: Re: [rfa/testsuite/mi] Recognize a few incorrect outputs
Date: Fri, 28 Sep 2001 13:34:00 -0000
Message-id: <3BB4DEBB.1020906@cygnus.com>
References: <20010928151616.A14106@nevyn.them.org>
X-SW-Source: 2001-09/msg00433.html
Content-length: 985

> <gripe>
> A lot of GDB tests seem to be written with only pass and timeout
> alternatives, or only with overly-specialized fails. The hypocrite-alert
> readers of this message will note that I'm guilty of the same thing; this is
> Just Enough to make them catch a few errors I could think of, not enough to
> recognize completely wrong output. Someday, someone more motivated than I
> should clean this up.
> </gripe>

For the MI, this is a pretty obvious fix. I've been doing the same
thing my self (when I noticed it). One suggestion, can you make that
fail expression less strict so that it picks. Something like:

<correct-output> (gdb) <more-output> (gdb)
pass

.* (gdb) .* (gdb)
fail

timeout
fail

alternatively (hmm, better?), keep the expression as you have it but add
a comment in paren vis:

fail "continue to incr_a (compiler bug info is wrong)"

Fernando,

Given the compiler debug info is ``wrong'' would this even qualify for
as an xfail?

Andrew