mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-18 14:04:24 +08:00
gdb-2.5.2
This commit is contained in:
parent
632ea0ccc5
commit
6368691e88
192
gdb/dbxread.c
192
gdb/dbxread.c
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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); }
|
||||
;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
77
gdb/symtab.c
77
gdb/symtab.c
@ -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.
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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.");
|
||||
}
|
||||
|
31
gdb/valops.c
31
gdb/valops.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
295
gdb/valprint.c
295
gdb/valprint.c
@ -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);
|
||||
|
@ -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.");
|
||||
}
|
||||
|
||||
|
@ -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)";
|
||||
|
Loading…
Reference in New Issue
Block a user