gdb-2.5.2

This commit is contained in:
gdb-2.5.2 1988-06-01 01:00:00 +01:00 committed by Pedro Alves
parent 632ea0ccc5
commit 6368691e88
13 changed files with 446 additions and 349 deletions

View File

@ -1744,8 +1744,7 @@ condense_addl_misc_bunches ()
}
/**************************** ADD_FILE_COMMAND() ****************************/
/* This function allows the addition of incrementally linked object files.
Useful for debugging `sun_kick'. */
/* This function allows the addition of incrementally linked object files. */
void
add_file_command (arg_string)
@ -1762,116 +1761,107 @@ add_file_command (arg_string)
char* name;
unsigned text_addr;
if (arg_string == 0)
error ("add-file takes a file name and an address");
for( ; *arg_string == ' '; arg_string++ );
name = arg_string;
for( ; *arg_string != ' ' ; arg_string++ );
for( ; *arg_string && *arg_string != ' ' ; arg_string++ );
*arg_string++ = (char) 0;
for( ; *arg_string == ' '; arg_string++ );
text_addr = (unsigned) atoi(arg_string);
printf("filename \"%s\", and text_addr = 0x%x\n", name, text_addr );
if (name[0] == 0)
error ("add-file takes a file name and an address");
text_addr = parse_and_eval_address (arg_string);
dont_repeat ();
if (name == 0)
if (query ("add symbol table from filename \"%s\" at text_addr = 0x%x\n", name, text_addr))
{
if (symtab_list && !query ("Discard symbol table? ", 0))
error ("Not confirmed.");
free_all_symtabs ();
return;
}
desc = open (name, O_RDONLY);
if (desc < 0)
perror_with_name (name);
/* if (symtab_list && !query ("Add new symbols from \"%s\"? ", name))
error ("Not confirmed.");
*/
{
char *absolute_name;
desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
if (desc < 0)
perror_with_name (name);
else
name = absolute_name;
}
old_chain = make_cleanup (close, desc);
make_cleanup (free_current_contents, &name);
old_chain = make_cleanup (close, desc);
make_cleanup (free_current_contents, &name);
val = myread (desc, &hdr, sizeof hdr);
if (val < 0)
perror_with_name (name);
val = myread (desc, &hdr, sizeof hdr);
if (val < 0)
perror_with_name (name);
if (N_BADMAG (hdr))
error ("File \"%s\" has a bad header.", name);
if (N_BADMAG (hdr))
error ("File \"%s\" has a bad header.", name);
if (hdr.a_syms == 0)
{
printf ("%s does not have a symbol-table.\n", name);
fflush (stdout);
return;
}
if (hdr.a_syms == 0)
{
printf ("%s does not have a symbol-table.\n", name);
/* Now read the string table, all at once. */
val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0);
if (val < 0)
perror_with_name (name);
val = myread (desc, &buffer, sizeof buffer);
if (val < 0)
perror_with_name (name);
stringtab = (char *) alloca (buffer);
bcopy (&buffer, stringtab, sizeof buffer);
val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer);
if (val < 0)
perror_with_name (name);
/* That puts us at the symsegs. Read them. ########## Also need other
changes if they exist. */
/* Position to read the symbol table. Do not read it all at once. */
val = lseek (desc, N_SYMOFF (hdr), 0);
if (val < 0)
perror_with_name (name);
printf ("Reading symbol data from %s...", name);
fflush (stdout);
init_misc_functions ();
make_cleanup (discard_misc_bunches, 0);
init_header_files ();
make_cleanup (free_header_files, 0);
read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist),
text_addr, hdr.a_text) ;
/* Sort symbols alphabetically within each block. */
sort_syms ();
/* Go over the all misc functions and install them in vector. */
condense_addl_misc_bunches ();
/* Don't allow char * to have a typename (else would get caddr_t.) */
TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
/* Make a default for file to list. */
select_source_symtab (symtab_list);
do_cleanups (old_chain);
/* Free the symtabs made by read_symsegs, but not their contents,
which have been copied into symtabs on symtab_list. */
while (symseg_chain)
{
register struct symtab *s = symseg_chain->next;
free (symseg_chain);
symseg_chain = s;
}
printf ("done.\n");
fflush (stdout);
return;
}
/* Now read the string table, all at once. */
val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0);
if (val < 0)
perror_with_name (name);
val = myread (desc, &buffer, sizeof buffer);
if (val < 0)
perror_with_name (name);
stringtab = (char *) alloca (buffer);
bcopy (&buffer, stringtab, sizeof buffer);
val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer);
if (val < 0)
perror_with_name (name);
/* That puts us at the symsegs. Read them. ########## Also need other
changes if they exist. */
/* Position to read the symbol table. Do not read it all at once. */
val = lseek (desc, N_SYMOFF (hdr), 0);
if (val < 0)
perror_with_name (name);
printf ("Reading symbol data from %s...", name);
fflush (stdout);
init_misc_functions ();
make_cleanup (discard_misc_bunches, 0);
init_header_files ();
make_cleanup (free_header_files, 0);
read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist)
,text_addr, hdr.a_text) ;
/* Sort symbols alphabetically within each block. */
sort_syms ();
/* Go over the all misc functions and install them in vector. */
condense_addl_misc_bunches ();
/* Don't allow char * to have a typename (else would get caddr_t.) */
TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
/* Make a default for file to list. */
select_source_symtab (symtab_list);
do_cleanups (old_chain);
/* Free the symtabs made by read_symsegs, but not their contents,
which have been copied into symtabs on symtab_list. */
while (symseg_chain)
{
register struct symtab *s = symseg_chain->next;
free (symseg_chain);
symseg_chain = s;
}
printf ("done.\n");
fflush (stdout);
else error ("Not confirmed.");
}
static struct symbol *
@ -2174,15 +2164,15 @@ read_type (pp)
{
struct type *domain = read_type (pp);
char c;
struct type *ptrtype;
struct type *memtype;
if (*(*pp)++ != ',')
error ("invalid member pointer data format, at symtab pos %d.",
error ("invalid member type data format, at symtab pos %d.",
symnum);
ptrtype = read_type (pp);
memtype = read_type (pp);
type = dbx_alloc_type (typenums);
smash_to_member_pointer_type (type, domain, ptrtype);
smash_to_member_type (type, domain, memtype);
}
break;

View File

@ -420,32 +420,40 @@ the terms of Paragraph 1 above, provided that you also do the following:
that in whole or in part contains or is a derivative of this
program or any part thereof, to be licensed at no charge to all
third parties on terms identical to those contained in this
License Agreement (except that you may choose to grant more
extensive warranty protection to third parties, at your option).
License Agreement (except that you may choose to grant more extensive
warranty protection to some or all third parties, at your option).
c) You may charge a distribution fee for the physical act of
transferring a copy, and you may at your option offer warranty
protection in exchange for a fee.
3. You may copy and distribute this program or any portion of it in
compiled, executable or object code form under the terms of Paragraphs
1 and 2 above provided that you do the following:
Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.
a) cause each such copy to be accompanied by the
corresponding machine-readable source code, which must
be distributed under the terms of Paragraphs 1 and 2 above; or,
3. You may copy and distribute this program (or a portion or derivative
of it, under Paragraph 2) in object code or executable form under the terms
of Paragraphs 1 and 2 above provided that you also do one of the following:
b) cause each such copy to be accompanied by a
written offer, with no time limit, to give any third party
free (except for a nominal shipping charge) a machine readable
copy of the corresponding source code, to be distributed
under the terms of Paragraphs 1 and 2 above; or,
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) in the case of a recipient of this program in compiled, executable
or object code form (without the corresponding source code) you
shall cause copies you distribute to be accompanied by a copy
of the written offer of source code which you received along
with the copy you received.
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal
shipping charge) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
For an executable file, complete source code means all the source code for
all modules it contains; but, as a special exception, it need not include
source code for modules which are standard libraries that accompany the
operating system on which the executable file runs.
4. You may not copy, sublicense, distribute or transfer this program
except as expressly provided under this License Agreement. Any attempt
@ -504,7 +512,11 @@ YYSTYPE yylval; /* the semantic value of the */
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
int yynerr; /* number of parse errors so far */
#ifdef YYDEBUG
int yydebug = 0; /* nonzero means print parse trace */
#endif
#endif /* YYIMPURE */
@ -523,7 +535,7 @@ int yydebug = 0; /* nonzero means print parse trace */
#endif
#line 87 "bison.simple"
#line 165 "bison.simple"
int
yyparse()
{
@ -551,7 +563,9 @@ yyparse()
YYSTYPE yylval;
YYLTYPE yylloc;
#ifdef YYDEBUG
extern int yydebug;
#endif
#endif
@ -562,11 +576,14 @@ yyparse()
int yylen;
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Starting parse\n");
#endif
yystate = 0;
yyerrstatus = 0;
yynerr = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
@ -624,15 +641,19 @@ yynewstate:
yylsp = yyls + size - 1;
yyvsp = yyvs + size - 1;
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);
#endif
if (yyssp >= yyss + yymaxdepth - 1)
YYERROR;
}
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Entering state %d\n", yystate);
#endif
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
@ -651,6 +672,10 @@ yyresume:
if (yychar == YYEMPTY)
{
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Reading a token: ");
#endif
yychar = YYLEX;
}
@ -661,15 +686,19 @@ yyresume:
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Now at end of input.\n");
#endif
}
else
{
yychar1 = YYTRANSLATE(yychar);
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Parsing next token; it is %d (%s)\n", yychar, yytname[yychar1]);
fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]);
#endif
}
yyn += yychar1;
@ -700,8 +729,10 @@ yyresume:
/* Shift the lookahead token. */
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
#endif
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
@ -728,6 +759,7 @@ yyreduce:
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen]; /* implement default value of the action */
#ifdef YYDEBUG
if (yydebug)
{
if (yylen == 1)
@ -737,6 +769,7 @@ yyreduce:
fprintf (stderr, "Reducing %d values via line %d, ",
yylen, yyrline[yyn]);
}
#endif
switch (yyn) {
@ -1161,19 +1194,19 @@ case 67:
break;}
case 68:
#line 581 "expread.y"
{ yyval.tval = lookup_member_pointer_type (builtin_type_int, yyvsp[-2].tval); ;
{ yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); ;
break;}
case 69:
#line 583 "expread.y"
{ yyval.tval = lookup_member_pointer_type (yyvsp[-5].tval, yyvsp[-3].tval); ;
{ yyval.tval = lookup_member_type (yyvsp[-5].tval, yyvsp[-3].tval); ;
break;}
case 70:
#line 585 "expread.y"
{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ;
{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ;
break;}
case 71:
#line 587 "expread.y"
{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval);
{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval);
free (yyvsp[-1].tvec); ;
break;}
case 72:
@ -1222,6 +1255,7 @@ case 78:
yylsp -= yylen;
yyssp -= yylen;
#ifdef YYDEBUG
if (yydebug)
{
short *ssp1 = yyss - 1;
@ -1230,6 +1264,7 @@ case 78:
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
*++yyvsp = yyval;
@ -1268,11 +1303,8 @@ yyerrlab: /* here on detecting error */
if (! yyerrstatus)
/* If not already recovering from an error, report this error. */
{
#ifdef ESKIT
db_yyerror("parse error", yyssp, yychar);
#else
++yynerr;
yyerror("parse error");
#endif
}
if (yyerrstatus == 3)
@ -1283,8 +1315,10 @@ yyerrlab: /* here on detecting error */
if (yychar == YYEOF)
YYERROR;
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
#endif
yychar = YYEMPTY;
}
@ -1312,6 +1346,7 @@ yyerrpop: /* pop the current state because it cannot handle the error token */
yylsp--;
yystate = *--yyssp;
#ifdef YYDEBUG
if (yydebug)
{
short *ssp1 = yyss - 1;
@ -1320,6 +1355,7 @@ yyerrpop: /* pop the current state because it cannot handle the error token */
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
yyerrhandle:
@ -1345,8 +1381,10 @@ yyerrhandle:
if (yyn == YYFINAL)
YYACCEPT;
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Shifting error token, ");
#endif
*++yyvsp = yylval;
*++yylsp = yylloc;

View File

@ -578,13 +578,13 @@ type : typebase
| type '&'
{ $$ = lookup_reference_type ($1); }
| typebase COLONCOLON '*'
{ $$ = lookup_member_pointer_type (builtin_type_int, $1); }
{ $$ = lookup_member_type (builtin_type_int, $1); }
| type '(' typebase COLONCOLON '*' ')'
{ $$ = lookup_member_pointer_type ($1, $3); }
{ $$ = lookup_member_type ($1, $3); }
| type '(' typebase COLONCOLON '*' ')' '(' ')'
{ $$ = lookup_member_pointer_type (lookup_function_type ($1, 0), $3); }
{ $$ = lookup_member_type (lookup_function_type ($1, 0), $3); }
| type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')'
{ $$ = lookup_member_pointer_type (lookup_function_type ($1, $8), $3);
{ $$ = lookup_member_type (lookup_function_type ($1, $8), $3);
free ($8); }
;

View File

@ -62,6 +62,8 @@ enum exp_opcode
BINOP_EXP, /* Exponentiation */
/* C++. */
BINOP_MIN, /* <? */
BINOP_MAX, /* >? */
BINOP_SCOPE, /* :: */
/* STRUCTOP_MEMBER is used for pointer-to-member constructs.

View File

@ -397,6 +397,13 @@ executable file.
@samp{core-file} with no argument specifies that no core file is
to be used.
@item add-file @var{filename} @var{address}
When performing incremental linking, the symbol table of an incrementally
linked file may be included in the link step, but GDB+ needs to be told
where that symbol table is in the address space. By issuing this command,
it is possible to symbolically debug programs which make use of incremental
loading in a completely natural fashion.
@item kill
@kindex kill
Cancel running the program under GDB+. This could be used if you wish

View File

@ -120,7 +120,7 @@ enum type_code
TYPE_CODE_PASCAL_ARRAY, /* Array with explicit type of index */
/* C++ */
TYPE_CODE_MPTR, /* Member pointer type */
TYPE_CODE_MEMBER, /* Member type */
TYPE_CODE_REF, /* C++ Reference types */
};

View File

@ -236,63 +236,54 @@ lookup_reference_type (type)
}
/* Given a type TYPE, return a type of pointers to that type.
/* 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
of the aggregate that the member belongs to. */
struct type *
lookup_member_pointer_type (type, domain)
lookup_member_type (type, domain)
struct type *type, *domain;
{
register struct type *ptype = TYPE_POINTER_TYPE (type);
register struct type *mtype = TYPE_MAIN_VARIANT (type);
struct type *main_type;
if (ptype)
main_type = mtype;
while (mtype)
{
ptype = TYPE_MAIN_VARIANT (ptype);
main_type = ptype;
while (ptype)
{
if (TYPE_DOMAIN_TYPE (ptype) == domain)
return ptype;
ptype = TYPE_CHAIN (ptype);
}
}
else
{
main_type = lookup_pointer_type (type);
TYPE_POINTER_TYPE (type) = main_type;
if (TYPE_DOMAIN_TYPE (mtype) == domain)
return mtype;
mtype = TYPE_CHAIN (mtype);
}
/* This is the first time anyone wanted a pointer to a TYPE. */
/* This is the first time anyone wanted this member type. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
ptype = (struct type *) xmalloc (sizeof (struct type));
mtype = (struct type *) xmalloc (sizeof (struct type));
else
ptype = (struct type *) obstack_alloc (symbol_obstack,
mtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
bzero (ptype, sizeof (struct type));
TYPE_MAIN_VARIANT (ptype) = main_type;
TYPE_TARGET_TYPE (ptype) = type;
TYPE_DOMAIN_TYPE (ptype) = domain;
TYPE_POINTER_TYPE (type) = ptype;
bzero (mtype, sizeof (struct type));
TYPE_MAIN_VARIANT (mtype) = main_type;
TYPE_TARGET_TYPE (mtype) = type;
TYPE_DOMAIN_TYPE (mtype) = domain;
/* New type is permanent if type pointed to is permanent. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM;
/* We assume the machine has only one representation for pointers! */
TYPE_LENGTH (ptype) = sizeof (char *);
TYPE_CODE (ptype) = TYPE_CODE_MPTR;
TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
/* In practice, this is never used. */
TYPE_LENGTH (mtype) = 1;
TYPE_CODE (mtype) = TYPE_CODE_MEMBER;
/* Now splice in the new member pointer type. */
if (main_type)
{
/* This type was not "smashed". */
TYPE_CHAIN (ptype) = TYPE_CHAIN (main_type);
TYPE_CHAIN (main_type) = ptype;
TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
TYPE_CHAIN (main_type) = mtype;
}
return ptype;
return mtype;
}
/* Given a type TYPE, return a type of functions that return that type.
@ -348,31 +339,21 @@ smash_to_pointer_type (type, to_type)
}
}
/* Smash TYPE to be a type of pointers to TO_TYPE.
If TO_TYPE is not permanent and has no pointer-type yet,
record TYPE as its pointer-type.
TYPE is the type of the member. DOMAIN is the type of
the aggregate that the member belongs to. */
/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. */
void
smash_to_member_pointer_type (type, domain, to_type)
smash_to_member_type (type, domain, to_type)
struct type *type, *domain, *to_type;
{
bzero (type, sizeof (struct type));
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
/* We assume the machine has only one representation for pointers! */
TYPE_LENGTH (type) = sizeof (char *);
TYPE_CODE (type) = TYPE_CODE_MPTR;
TYPE_MAIN_VARIANT (type) = lookup_pointer_type (to_type);
/* In practice, this is never needed. */
TYPE_LENGTH (type) = 1;
TYPE_CODE (type) = TYPE_CODE_MEMBER;
if (TYPE_POINTER_TYPE (to_type) == 0
&& !(TYPE_FLAGS (type) & TYPE_FLAG_PERM))
{
TYPE_POINTER_TYPE (to_type) = type;
}
TYPE_MAIN_VARIANT (type) = lookup_member_type (domain, to_type);
}
/* Smash TYPE to be a type of reference to TO_TYPE.

View File

@ -234,7 +234,7 @@ extern int find_pc_misc_function ();
/* C++ stuff. */
extern struct type *lookup_reference_type ();
extern struct type *lookup_member_pointer_type ();
extern struct type *lookup_member_type ();
extern struct type *lookup_class ();
/* end of C++ stuff. */

View File

@ -27,6 +27,8 @@ anyone else from sharing it farther. Help stamp out software hoarding!
START_FILE
value value_x_binop ();
value
value_add (arg1, arg2)
value arg1, arg2;
@ -63,7 +65,7 @@ value_add (arg1, arg2)
return val;
}
return value_binop (arg1, arg2, BINOP_ADD);
return value_x_binop (arg1, arg2, BINOP_ADD);
}
value
@ -96,7 +98,7 @@ value_sub (arg1, arg2)
return val;
}
return value_binop (arg1, arg2, BINOP_SUB);
return value_x_binop (arg1, arg2, BINOP_SUB);
}
/* Return the value of ARRAY[IDX]. */
@ -107,7 +109,70 @@ value_subscript (array, idx)
{
return value_ind (value_add (array, idx));
}
/* Check to see if either argument is a structure. If so, then
create an argument vector that calls arg1.operator @ (arg1,arg2)
and return that value (where '@' is any binary operator which
is legal for GNU C++). If both args are scalar types then just
return value_binop(). */
value
value_x_binop (arg1, arg2, op)
value arg1, arg2;
int op;
{
value * argvec;
char *ptr;
char tstr[13];
COERCE_ENUM (arg1);
COERCE_ENUM (arg2);
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
|| TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT)
{
/* now we know that what we have to do is construct our
arg vector and find the right function to call it with. */
if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
error ("friend functions not implemented yet");
argvec = (value *) alloca (sizeof (value) * 4);
argvec[1] = value_addr (arg1);
argvec[2] = arg2;
argvec[3] = 0;
/* make the right function name up */
strcpy(tstr,"operator __");
ptr = tstr+9;
switch (op)
{
case BINOP_ADD: *ptr++ = '+'; *ptr = '\0'; break;
case BINOP_SUB: *ptr++ = '-'; *ptr = '\0'; break;
case BINOP_MUL: *ptr++ = '*'; *ptr = '\0'; break;
case BINOP_DIV: *ptr++ = '/'; *ptr = '\0'; break;
case BINOP_REM: *ptr++ = '%'; *ptr = '\0';break;
case BINOP_LSH: *ptr++ = '<'; *ptr = '<'; break;
case BINOP_RSH: *ptr++ = '>'; *ptr = '>'; break;
case BINOP_LOGAND: *ptr++ = '&'; *ptr = '\0'; break;
case BINOP_LOGIOR: *ptr++ = '|'; *ptr = '\0'; break;
case BINOP_LOGXOR: *ptr++ = '^'; *ptr = '\0'; break;
case BINOP_AND: *ptr++ = '&'; *ptr = '&'; break;
case BINOP_OR: *ptr++ = '|'; *ptr = '|'; break;
case BINOP_MIN: *ptr++ = '<'; *ptr = '?'; break;
case BINOP_MAX: *ptr++ = '>'; *ptr = '?'; break;
default:
error ("Invalid binary operation specified.");
}
argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
if (argvec[0])
return call_function (argvec[0], 2, argvec + 1);
else error ("member function %s not found", tstr);
}
return value_binop(arg1, arg2, op);
}
/* Perform a binary operation on two integers or two floats.
Does not support addition and subtraction on pointers;
use value_add or value_sub if you want to handle those possibilities. */
@ -219,6 +284,14 @@ value_binop (arg1, arg2, op)
v = v1 || v2;
break;
case BINOP_MIN:
v = v1 < v2 ? v1 : v2;
break;
case BINOP_MAX:
v = v1 > v2 ? v1 : v2;
break;
default:
error ("Invalid binary operation on numbers.");
}

View File

@ -56,17 +56,11 @@ value_cast (type, arg2)
return value_from_long (type, value_as_long (arg2));
else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2)))
{
if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR))
printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n");
VALUE_TYPE (arg2) = type;
return arg2;
}
else if (VALUE_LVAL (arg2) == lval_memory)
{
if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR))
printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n");
return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
}
else
@ -286,8 +280,8 @@ value_ind (arg1)
{
COERCE_ARRAY (arg1);
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MPTR)
error ("not implemented: member pointers in value_ind");
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MEMBER)
error ("not implemented: member types in value_ind");
/* Allow * on an integer so we can cast it to whatever we want. */
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT)
@ -425,8 +419,13 @@ call_function (function, nargs, args)
register struct type *ftype = VALUE_TYPE (function);
register enum type_code code = TYPE_CODE (ftype);
if (code == TYPE_CODE_MPTR)
error ("not implemented: member pointer to call_function");
/* If it's a member function, just look at the function
part of it. */
if (code == TYPE_CODE_MEMBER)
{
ftype = TYPE_TARGET_TYPE (ftype);
code = TYPE_CODE (ftype);
}
/* Determine address to call. */
if (code == TYPE_CODE_FUNC)
@ -601,8 +600,8 @@ value_struct_elt (arg1, args, name, err)
t = VALUE_TYPE (arg1);
}
if (TYPE_CODE (t) == TYPE_CODE_MPTR)
error ("not implemented: member pointers in value_struct_elt");
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in value_struct_elt");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
@ -809,8 +808,8 @@ check_field (arg1, name)
t = VALUE_TYPE (arg1);
}
if (TYPE_CODE (t) == TYPE_CODE_MPTR)
error ("not implemented: member pointers in check_field");
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in check_field");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
@ -886,7 +885,7 @@ value_struct_elt_for_address (domain, intype, name)
error ("pointers to bitfield members not allowed");
v = value_from_long (builtin_type_int, TYPE_FIELD_BITPOS (t, i) >> 3);
VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FIELD_TYPE (t, i), baseclass);
VALUE_TYPE (v) = lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass);
return v;
}
}
@ -936,7 +935,7 @@ value_struct_elt_for_address (domain, intype, name)
0, VAR_NAMESPACE);
v = locate_var_value (s, 0);
}
VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FN_FIELD_TYPE (f, j), baseclass);
VALUE_TYPE (v) = lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), baseclass);
return v;
}
}

View File

@ -168,147 +168,151 @@ val_print (type, valaddr, address, stream)
/* Array of unspecified length: treat like pointer. */
case TYPE_CODE_PTR:
fprintf (stream, "0x%x", * (int *) valaddr);
/* For a pointer to char or unsigned char,
also print the string pointed to, unless pointer is null. */
if ((TYPE_TARGET_TYPE (type) == builtin_type_char
|| TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char)
&& unpack_long (type, valaddr) != 0)
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
{
fputc (' ', stream);
fputc ('"', stream);
for (i = 0; i < print_max; i++)
struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type));
struct fn_field *f;
int j, len2;
char *kind = "";
val = unpack_long (builtin_type_int, valaddr);
if (TYPE_CODE (target) == TYPE_CODE_FUNC)
{
QUIT;
read_memory (unpack_long (type, valaddr) + i, &c, 1);
if (c == 0)
break;
printchar (c, stream);
if (val < 128)
{
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
{
kind = "virtual";
goto common;
}
}
}
}
else
{
struct symbol *sym = find_pc_function (val);
if (sym == 0)
error ("invalid pointer to member function");
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
goto common;
}
}
}
common:
if (i < len)
{
fprintf (stream, "& ");
type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
fprintf (stream, kind);
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
TYPE_FN_FIELDLIST_NAME (domain, i), stream);
else
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j), "",
TYPE_FN_FIELDLIST_NAME (domain, i), stream);
break;
}
}
else
{
/* VAL is a byte offset into the structure type DOMAIN.
Find the name of the field for that offset and
print it. */
int extra = 0;
int bits = 0;
len = TYPE_NFIELDS (domain);
val <<= 3; /* @@ Make VAL into bit offset */
for (i = 0; i < len; i++)
{
int bitpos = TYPE_FIELD_BITPOS (domain, i);
QUIT;
if (val == bitpos)
break;
if (val < bitpos && i > 0)
{
int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
/* Somehow pointing into a field. */
i -= 1;
extra = (val - TYPE_FIELD_BITPOS (domain, i));
if (extra & 0x3)
bits = 1;
else
extra >>= 3;
break;
}
}
if (i < len)
{
fprintf (stream, "& ");
type_print_base (domain, stream, 0, 0);
fprintf (stream, "::");
fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
if (extra)
fprintf (stream, " + %d bytes", extra);
if (bits)
fprintf (stream, " (offset in bits)");
break;
}
}
fputc ('(', stream);
type_print (type, "", stream, -1);
fprintf (stream, ") %d", val >> 3);
}
else
{
fprintf (stream, "0x%x", * (int *) valaddr);
/* For a pointer to char or unsigned char,
also print the string pointed to, unless pointer is null. */
if ((TYPE_TARGET_TYPE (type) == builtin_type_char
|| TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char)
&& unpack_long (type, valaddr) != 0)
{
fputc (' ', stream);
fputc ('"', stream);
for (i = 0; i < print_max; i++)
{
QUIT;
read_memory (unpack_long (type, valaddr) + i, &c, 1);
if (c == 0)
break;
printchar (c, stream);
}
fputc ('"', stream);
if (i == print_max)
fprintf (stream, "...");
fflush (stream);
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return i + (i != print_max);
}
fputc ('"', stream);
if (i == print_max)
fprintf (stream, "...");
fflush (stream);
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return i + (i != print_max);
}
break;
case TYPE_CODE_MPTR:
{
struct type *domain = TYPE_DOMAIN_TYPE (type);
struct type *target = TYPE_TARGET_TYPE (type);
struct fn_field *f;
int j, len2;
char *kind = "";
val = unpack_long (builtin_type_int, valaddr);
if (TYPE_CODE (target) == TYPE_CODE_FUNC)
{
if (val < 128)
{
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
{
kind = " virtual";
goto common;
}
}
}
}
else
{
struct symbol *sym = find_pc_function (val);
if (sym == 0)
error ("invalid pointer to member function");
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
goto common;
}
}
}
common:
if (i < len)
{
fprintf (stream, "& ");
type_print_base (domain, stream, 0, 0);
fprintf (stream, "::%s", kind);
type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
TYPE_FN_FIELDLIST_NAME (domain, i), stream);
else
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j), "",
TYPE_FN_FIELDLIST_NAME (domain, i), stream);
break;
}
}
else
{
/* VAL is a byte offset into the structure type DOMAIN.
Find the name of the field for that offset and
print it. */
int extra = 0;
int bits = 0;
len = TYPE_NFIELDS (domain);
val <<= 3; /* @@ Make VAL into bit offset */
for (i = 0; i < len; i++)
{
int bitpos = TYPE_FIELD_BITPOS (domain, i);
QUIT;
if (val == bitpos)
break;
if (val < bitpos && i > 0)
{
int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
/* Somehow pointing into a field. */
i -= 1;
extra = (val - TYPE_FIELD_BITPOS (domain, i));
if (extra & 0x3)
bits = 1;
else
extra >>= 3;
break;
}
}
if (i < len)
{
fprintf (stream, "& ");
type_print_base (domain, stream, 0, 0);
fprintf (stream, "::");
fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
if (extra)
fprintf (stream, " + %d bytes", extra);
if (bits)
fprintf (stream, " (offset in bits)");
break;
}
}
fputc ('(', stream);
type_print (type, "", stream, -1);
fprintf (stream, ") %d", val >> 3);
break;
}
case TYPE_CODE_MEMBER:
error ("not implemented: member type in val_print");
break;
case TYPE_CODE_REF:
fprintf (stream, "(0x%x &) = ", * (int *) valaddr);
@ -489,7 +493,7 @@ type_print_1 (type, varstring, stream, show, level)
&&
(code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
|| code == TYPE_CODE_ARRAY
|| code == TYPE_CODE_MPTR
|| code == TYPE_CODE_MEMBER
|| code == TYPE_CODE_REF)))
fprintf (stream, " ");
type_print_varspec_prefix (type, stream, show, 0);
@ -550,12 +554,11 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr)
fputc ('*', stream);
break;
case TYPE_CODE_MPTR:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
if (passed_a_ptr)
fputc ('(', stream);
type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, 1);
fprintf (stream, "::*");
case TYPE_CODE_MEMBER:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0,
passed_a_ptr);
fprintf (stream, "::");
break;
case TYPE_CODE_REF:
@ -604,10 +607,12 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr)
fprintf (stream, "]");
break;
case TYPE_CODE_MPTR:
case TYPE_CODE_MEMBER:
if (passed_a_ptr)
fputc (')', stream);
/* Fall through. */
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
break;
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1);
@ -660,7 +665,7 @@ type_print_base (type, stream, show, level)
{
case TYPE_CODE_ARRAY:
case TYPE_CODE_PTR:
case TYPE_CODE_MPTR:
case TYPE_CODE_MEMBER:
case TYPE_CODE_REF:
case TYPE_CODE_FUNC:
type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);

View File

@ -464,8 +464,7 @@ unpack_long (type, valaddr)
if (len == sizeof (long))
return * (unsigned long *) valaddr;
}
else if (code == TYPE_CODE_INT
|| code == TYPE_CODE_MPTR)
else if (code == TYPE_CODE_INT)
{
if (len == sizeof (char))
return * (char *) valaddr;
@ -485,6 +484,9 @@ unpack_long (type, valaddr)
if (len == sizeof (char *))
return (CORE_ADDR) * (char **) valaddr;
}
else if (code == TYPE_CODE_MEMBER)
error ("not impelmented: member types in unpack_long");
error ("Value not integer or pointer.");
}

View File

@ -1,3 +1,3 @@
/* Define the current version number of GDB. */
char *version = "2.5.1 (GNU C++ 1.21.0 compatible)";
char *version = "2.5.2 (GNU C++ 1.22.0 compatible)";