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() ****************************/ /**************************** ADD_FILE_COMMAND() ****************************/
/* This function allows the addition of incrementally linked object files. /* This function allows the addition of incrementally linked object files. */
Useful for debugging `sun_kick'. */
void void
add_file_command (arg_string) add_file_command (arg_string)
@ -1762,116 +1761,107 @@ add_file_command (arg_string)
char* name; char* name;
unsigned text_addr; unsigned text_addr;
if (arg_string == 0)
error ("add-file takes a file name and an address");
for( ; *arg_string == ' '; arg_string++ ); for( ; *arg_string == ' '; arg_string++ );
name = arg_string; name = arg_string;
for( ; *arg_string != ' ' ; arg_string++ ); for( ; *arg_string && *arg_string != ' ' ; arg_string++ );
*arg_string++ = (char) 0; *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 (); 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)) desc = open (name, O_RDONLY);
error ("Not confirmed."); if (desc < 0)
free_all_symtabs (); perror_with_name (name);
return;
}
/* if (symtab_list && !query ("Add new symbols from \"%s\"? ", name)) old_chain = make_cleanup (close, desc);
error ("Not confirmed."); make_cleanup (free_current_contents, &name);
*/
{
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); val = myread (desc, &hdr, sizeof hdr);
make_cleanup (free_current_contents, &name); if (val < 0)
perror_with_name (name);
val = myread (desc, &hdr, sizeof hdr); if (N_BADMAG (hdr))
if (val < 0) error ("File \"%s\" has a bad header.", name);
perror_with_name (name);
if (N_BADMAG (hdr)) if (hdr.a_syms == 0)
error ("File \"%s\" has a bad header.", name); {
printf ("%s does not have a symbol-table.\n", name);
fflush (stdout);
return;
}
if (hdr.a_syms == 0) /* Now read the string table, all at once. */
{ val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0);
printf ("%s does not have a symbol-table.\n", name); 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); fflush (stdout);
return;
} }
else error ("Not confirmed.");
/* 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);
} }
static struct symbol * static struct symbol *
@ -2174,15 +2164,15 @@ read_type (pp)
{ {
struct type *domain = read_type (pp); struct type *domain = read_type (pp);
char c; char c;
struct type *ptrtype; struct type *memtype;
if (*(*pp)++ != ',') if (*(*pp)++ != ',')
error ("invalid member pointer data format, at symtab pos %d.", error ("invalid member type data format, at symtab pos %d.",
symnum); symnum);
ptrtype = read_type (pp); memtype = read_type (pp);
type = dbx_alloc_type (typenums); type = dbx_alloc_type (typenums);
smash_to_member_pointer_type (type, domain, ptrtype); smash_to_member_type (type, domain, memtype);
} }
break; 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 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 program or any part thereof, to be licensed at no charge to all
third parties on terms identical to those contained in this third parties on terms identical to those contained in this
License Agreement (except that you may choose to grant more License Agreement (except that you may choose to grant more extensive
extensive warranty protection to third parties, at your option). warranty protection to some or all third parties, at your option).
c) You may charge a distribution fee for the physical act of c) You may charge a distribution fee for the physical act of
transferring a copy, and you may at your option offer warranty transferring a copy, and you may at your option offer warranty
protection in exchange for a fee. protection in exchange for a fee.
3. You may copy and distribute this program or any portion of it in Mere aggregation of another unrelated program with this program (or its
compiled, executable or object code form under the terms of Paragraphs derivative) on a volume of a storage or distribution medium does not bring
1 and 2 above provided that you do the following: the other program under the scope of these terms.
a) cause each such copy to be accompanied by the 3. You may copy and distribute this program (or a portion or derivative
corresponding machine-readable source code, which must of it, under Paragraph 2) in object code or executable form under the terms
be distributed under the terms of Paragraphs 1 and 2 above; or, 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 a) accompany it with the complete corresponding machine-readable
written offer, with no time limit, to give any third party source code, which must be distributed under the terms of
free (except for a nominal shipping charge) a machine readable Paragraphs 1 and 2 above; or,
copy of the corresponding source code, to 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 b) accompany it with a written offer, valid for at least three
or object code form (without the corresponding source code) you years, to give any third party free (except for a nominal
shall cause copies you distribute to be accompanied by a copy shipping charge) a complete machine-readable copy of the
of the written offer of source code which you received along corresponding source code, to be distributed under the terms of
with the copy you received. 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 4. You may not copy, sublicense, distribute or transfer this program
except as expressly provided under this License Agreement. Any attempt 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 */ YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */ /* symbol */
int yynerr; /* number of parse errors so far */
#ifdef YYDEBUG
int yydebug = 0; /* nonzero means print parse trace */ int yydebug = 0; /* nonzero means print parse trace */
#endif
#endif /* YYIMPURE */ #endif /* YYIMPURE */
@ -523,7 +535,7 @@ int yydebug = 0; /* nonzero means print parse trace */
#endif #endif
#line 87 "bison.simple" #line 165 "bison.simple"
int int
yyparse() yyparse()
{ {
@ -551,7 +563,9 @@ yyparse()
YYSTYPE yylval; YYSTYPE yylval;
YYLTYPE yylloc; YYLTYPE yylloc;
#ifdef YYDEBUG
extern int yydebug; extern int yydebug;
#endif
#endif #endif
@ -562,11 +576,14 @@ yyparse()
int yylen; int yylen;
#ifdef YYDEBUG
if (yydebug) if (yydebug)
fprintf(stderr, "Starting parse\n"); fprintf(stderr, "Starting parse\n");
#endif
yystate = 0; yystate = 0;
yyerrstatus = 0; yyerrstatus = 0;
yynerr = 0;
yychar = YYEMPTY; /* Cause a token to be read. */ yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers. /* Initialize stack pointers.
@ -624,15 +641,19 @@ yynewstate:
yylsp = yyls + size - 1; yylsp = yyls + size - 1;
yyvsp = yyvs + size - 1; yyvsp = yyvs + size - 1;
#ifdef YYDEBUG
if (yydebug) if (yydebug)
fprintf(stderr, "Stack size increased to %d\n", yymaxdepth); fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);
#endif
if (yyssp >= yyss + yymaxdepth - 1) if (yyssp >= yyss + yymaxdepth - 1)
YYERROR; YYERROR;
} }
#ifdef YYDEBUG
if (yydebug) if (yydebug)
fprintf(stderr, "Entering state %d\n", yystate); fprintf(stderr, "Entering state %d\n", yystate);
#endif
/* Do appropriate processing given the current state. */ /* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */ /* Read a lookahead token if we need one and don't already have one. */
@ -651,6 +672,10 @@ yyresume:
if (yychar == YYEMPTY) if (yychar == YYEMPTY)
{ {
#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Reading a token: ");
#endif
yychar = YYLEX; yychar = YYLEX;
} }
@ -661,15 +686,19 @@ yyresume:
yychar1 = 0; yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */ yychar = YYEOF; /* Don't call YYLEX any more */
#ifdef YYDEBUG
if (yydebug) if (yydebug)
fprintf(stderr, "Now at end of input.\n"); fprintf(stderr, "Now at end of input.\n");
#endif
} }
else else
{ {
yychar1 = YYTRANSLATE(yychar); yychar1 = YYTRANSLATE(yychar);
#ifdef YYDEBUG
if (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; yyn += yychar1;
@ -700,8 +729,10 @@ yyresume:
/* Shift the lookahead token. */ /* Shift the lookahead token. */
#ifdef YYDEBUG
if (yydebug) if (yydebug)
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
#endif
/* Discard the token being shifted unless it is eof. */ /* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF) if (yychar != YYEOF)
@ -728,6 +759,7 @@ yyreduce:
yylen = yyr2[yyn]; yylen = yyr2[yyn];
yyval = yyvsp[1-yylen]; /* implement default value of the action */ yyval = yyvsp[1-yylen]; /* implement default value of the action */
#ifdef YYDEBUG
if (yydebug) if (yydebug)
{ {
if (yylen == 1) if (yylen == 1)
@ -737,6 +769,7 @@ yyreduce:
fprintf (stderr, "Reducing %d values via line %d, ", fprintf (stderr, "Reducing %d values via line %d, ",
yylen, yyrline[yyn]); yylen, yyrline[yyn]);
} }
#endif
switch (yyn) { switch (yyn) {
@ -1161,19 +1194,19 @@ case 67:
break;} break;}
case 68: case 68:
#line 581 "expread.y" #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;} break;}
case 69: case 69:
#line 583 "expread.y" #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;} break;}
case 70: case 70:
#line 585 "expread.y" #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;} break;}
case 71: case 71:
#line 587 "expread.y" #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); ; free (yyvsp[-1].tvec); ;
break;} break;}
case 72: case 72:
@ -1222,6 +1255,7 @@ case 78:
yylsp -= yylen; yylsp -= yylen;
yyssp -= yylen; yyssp -= yylen;
#ifdef YYDEBUG
if (yydebug) if (yydebug)
{ {
short *ssp1 = yyss - 1; short *ssp1 = yyss - 1;
@ -1230,6 +1264,7 @@ case 78:
fprintf (stderr, " %d", *++ssp1); fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }
#endif
*++yyvsp = yyval; *++yyvsp = yyval;
@ -1268,11 +1303,8 @@ yyerrlab: /* here on detecting error */
if (! yyerrstatus) if (! yyerrstatus)
/* If not already recovering from an error, report this error. */ /* If not already recovering from an error, report this error. */
{ {
#ifdef ESKIT ++yynerr;
db_yyerror("parse error", yyssp, yychar);
#else
yyerror("parse error"); yyerror("parse error");
#endif
} }
if (yyerrstatus == 3) if (yyerrstatus == 3)
@ -1283,8 +1315,10 @@ yyerrlab: /* here on detecting error */
if (yychar == YYEOF) if (yychar == YYEOF)
YYERROR; YYERROR;
#ifdef YYDEBUG
if (yydebug) if (yydebug)
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
#endif
yychar = YYEMPTY; yychar = YYEMPTY;
} }
@ -1312,6 +1346,7 @@ yyerrpop: /* pop the current state because it cannot handle the error token */
yylsp--; yylsp--;
yystate = *--yyssp; yystate = *--yyssp;
#ifdef YYDEBUG
if (yydebug) if (yydebug)
{ {
short *ssp1 = yyss - 1; 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, " %d", *++ssp1);
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }
#endif
yyerrhandle: yyerrhandle:
@ -1345,8 +1381,10 @@ yyerrhandle:
if (yyn == YYFINAL) if (yyn == YYFINAL)
YYACCEPT; YYACCEPT;
#ifdef YYDEBUG
if (yydebug) if (yydebug)
fprintf(stderr, "Shifting error token, "); fprintf(stderr, "Shifting error token, ");
#endif
*++yyvsp = yylval; *++yyvsp = yylval;
*++yylsp = yylloc; *++yylsp = yylloc;

View File

@ -578,13 +578,13 @@ type : typebase
| type '&' | type '&'
{ $$ = lookup_reference_type ($1); } { $$ = lookup_reference_type ($1); }
| typebase COLONCOLON '*' | typebase COLONCOLON '*'
{ $$ = lookup_member_pointer_type (builtin_type_int, $1); } { $$ = lookup_member_type (builtin_type_int, $1); }
| type '(' typebase COLONCOLON '*' ')' | type '(' typebase COLONCOLON '*' ')'
{ $$ = lookup_member_pointer_type ($1, $3); } { $$ = lookup_member_type ($1, $3); }
| type '(' typebase COLONCOLON '*' ')' '(' ')' | 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 ')' | 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); } free ($8); }
; ;

View File

@ -62,6 +62,8 @@ enum exp_opcode
BINOP_EXP, /* Exponentiation */ BINOP_EXP, /* Exponentiation */
/* C++. */ /* C++. */
BINOP_MIN, /* <? */
BINOP_MAX, /* >? */
BINOP_SCOPE, /* :: */ BINOP_SCOPE, /* :: */
/* STRUCTOP_MEMBER is used for pointer-to-member constructs. /* 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 @samp{core-file} with no argument specifies that no core file is
to be used. 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 @item kill
@kindex kill @kindex kill
Cancel running the program under GDB+. This could be used if you wish 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 */ TYPE_CODE_PASCAL_ARRAY, /* Array with explicit type of index */
/* C++ */ /* C++ */
TYPE_CODE_MPTR, /* Member pointer type */ TYPE_CODE_MEMBER, /* Member type */
TYPE_CODE_REF, /* C++ Reference types */ 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. 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 The TYPE is the type of the member. The DOMAIN is the type
of the aggregate that the member belongs to. */ of the aggregate that the member belongs to. */
struct type * struct type *
lookup_member_pointer_type (type, domain) lookup_member_type (type, domain)
struct 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; struct type *main_type;
if (ptype) main_type = mtype;
while (mtype)
{ {
ptype = TYPE_MAIN_VARIANT (ptype); if (TYPE_DOMAIN_TYPE (mtype) == domain)
main_type = ptype; return mtype;
while (ptype) mtype = TYPE_CHAIN (mtype);
{
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;
} }
/* 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) if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
ptype = (struct type *) xmalloc (sizeof (struct type)); mtype = (struct type *) xmalloc (sizeof (struct type));
else else
ptype = (struct type *) obstack_alloc (symbol_obstack, mtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type)); sizeof (struct type));
bzero (ptype, sizeof (struct type)); bzero (mtype, sizeof (struct type));
TYPE_MAIN_VARIANT (ptype) = main_type; TYPE_MAIN_VARIANT (mtype) = main_type;
TYPE_TARGET_TYPE (ptype) = type; TYPE_TARGET_TYPE (mtype) = type;
TYPE_DOMAIN_TYPE (ptype) = domain; TYPE_DOMAIN_TYPE (mtype) = domain;
TYPE_POINTER_TYPE (type) = ptype;
/* New type is permanent if type pointed to is permanent. */ /* New type is permanent if type pointed to is permanent. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM; TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
/* We assume the machine has only one representation for pointers! */
TYPE_LENGTH (ptype) = sizeof (char *); /* In practice, this is never used. */
TYPE_CODE (ptype) = TYPE_CODE_MPTR; TYPE_LENGTH (mtype) = 1;
TYPE_CODE (mtype) = TYPE_CODE_MEMBER;
/* Now splice in the new member pointer type. */ /* Now splice in the new member pointer type. */
if (main_type) if (main_type)
{ {
/* This type was not "smashed". */ /* This type was not "smashed". */
TYPE_CHAIN (ptype) = TYPE_CHAIN (main_type); TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
TYPE_CHAIN (main_type) = ptype; TYPE_CHAIN (main_type) = mtype;
} }
return ptype; return mtype;
} }
/* Given a type TYPE, return a type of functions that return that type. /* 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. /* Smash TYPE to be a type of members of DOMAIN with type 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. */
void void
smash_to_member_pointer_type (type, domain, to_type) smash_to_member_type (type, domain, to_type)
struct type *type, *domain, *to_type; struct type *type, *domain, *to_type;
{ {
bzero (type, sizeof (struct type)); bzero (type, sizeof (struct type));
TYPE_TARGET_TYPE (type) = to_type; TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain; 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_MAIN_VARIANT (type) = lookup_member_type (domain, to_type);
&& !(TYPE_FLAGS (type) & TYPE_FLAG_PERM))
{
TYPE_POINTER_TYPE (to_type) = type;
}
} }
/* Smash TYPE to be a type of reference to 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. */ /* C++ stuff. */
extern struct type *lookup_reference_type (); extern struct type *lookup_reference_type ();
extern struct type *lookup_member_pointer_type (); extern struct type *lookup_member_type ();
extern struct type *lookup_class (); extern struct type *lookup_class ();
/* end of C++ stuff. */ /* end of C++ stuff. */

View File

@ -27,6 +27,8 @@ anyone else from sharing it farther. Help stamp out software hoarding!
START_FILE START_FILE
value value_x_binop ();
value value
value_add (arg1, arg2) value_add (arg1, arg2)
value arg1, arg2; value arg1, arg2;
@ -63,7 +65,7 @@ value_add (arg1, arg2)
return val; return val;
} }
return value_binop (arg1, arg2, BINOP_ADD); return value_x_binop (arg1, arg2, BINOP_ADD);
} }
value value
@ -96,7 +98,7 @@ value_sub (arg1, arg2)
return val; return val;
} }
return value_binop (arg1, arg2, BINOP_SUB); return value_x_binop (arg1, arg2, BINOP_SUB);
} }
/* Return the value of ARRAY[IDX]. */ /* Return the value of ARRAY[IDX]. */
@ -107,7 +109,70 @@ value_subscript (array, idx)
{ {
return value_ind (value_add (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. /* Perform a binary operation on two integers or two floats.
Does not support addition and subtraction on pointers; Does not support addition and subtraction on pointers;
use value_add or value_sub if you want to handle those possibilities. */ 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; v = v1 || v2;
break; break;
case BINOP_MIN:
v = v1 < v2 ? v1 : v2;
break;
case BINOP_MAX:
v = v1 > v2 ? v1 : v2;
break;
default: default:
error ("Invalid binary operation on numbers."); 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)); return value_from_long (type, value_as_long (arg2));
else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (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; VALUE_TYPE (arg2) = type;
return arg2; return arg2;
} }
else if (VALUE_LVAL (arg2) == lval_memory) 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)); return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
} }
else else
@ -286,8 +280,8 @@ value_ind (arg1)
{ {
COERCE_ARRAY (arg1); COERCE_ARRAY (arg1);
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MPTR) if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MEMBER)
error ("not implemented: member pointers in value_ind"); error ("not implemented: member types in value_ind");
/* Allow * on an integer so we can cast it to whatever we want. */ /* Allow * on an integer so we can cast it to whatever we want. */
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT) 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 struct type *ftype = VALUE_TYPE (function);
register enum type_code code = TYPE_CODE (ftype); register enum type_code code = TYPE_CODE (ftype);
if (code == TYPE_CODE_MPTR) /* If it's a member function, just look at the function
error ("not implemented: member pointer to call_function"); part of it. */
if (code == TYPE_CODE_MEMBER)
{
ftype = TYPE_TARGET_TYPE (ftype);
code = TYPE_CODE (ftype);
}
/* Determine address to call. */ /* Determine address to call. */
if (code == TYPE_CODE_FUNC) if (code == TYPE_CODE_FUNC)
@ -601,8 +600,8 @@ value_struct_elt (arg1, args, name, err)
t = VALUE_TYPE (arg1); t = VALUE_TYPE (arg1);
} }
if (TYPE_CODE (t) == TYPE_CODE_MPTR) if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member pointers in value_struct_elt"); error ("not implemented: member type in value_struct_elt");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION) && TYPE_CODE (t) != TYPE_CODE_UNION)
@ -809,8 +808,8 @@ check_field (arg1, name)
t = VALUE_TYPE (arg1); t = VALUE_TYPE (arg1);
} }
if (TYPE_CODE (t) == TYPE_CODE_MPTR) if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member pointers in check_field"); error ("not implemented: member type in check_field");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION) && 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"); error ("pointers to bitfield members not allowed");
v = value_from_long (builtin_type_int, TYPE_FIELD_BITPOS (t, i) >> 3); 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; return v;
} }
} }
@ -936,7 +935,7 @@ value_struct_elt_for_address (domain, intype, name)
0, VAR_NAMESPACE); 0, VAR_NAMESPACE);
v = locate_var_value (s, 0); 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; return v;
} }
} }

View File

@ -168,147 +168,151 @@ val_print (type, valaddr, address, stream)
/* Array of unspecified length: treat like pointer. */ /* Array of unspecified length: treat like pointer. */
case TYPE_CODE_PTR: case TYPE_CODE_PTR:
fprintf (stream, "0x%x", * (int *) valaddr); if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
/* 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); struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
fputc ('"', stream); struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type));
for (i = 0; i < print_max; i++) struct fn_field *f;
int j, len2;
char *kind = "";
val = unpack_long (builtin_type_int, valaddr);
if (TYPE_CODE (target) == TYPE_CODE_FUNC)
{ {
QUIT; if (val < 128)
read_memory (unpack_long (type, valaddr) + i, &c, 1); {
if (c == 0) len = TYPE_NFN_FIELDS (domain);
break; for (i = 0; i < len; i++)
printchar (c, stream); {
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; break;
case TYPE_CODE_MPTR: case TYPE_CODE_MEMBER:
{ error ("not implemented: member type in val_print");
struct type *domain = TYPE_DOMAIN_TYPE (type); break;
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_REF: case TYPE_CODE_REF:
fprintf (stream, "(0x%x &) = ", * (int *) valaddr); 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_PTR || code == TYPE_CODE_FUNC
|| code == TYPE_CODE_ARRAY || code == TYPE_CODE_ARRAY
|| code == TYPE_CODE_MPTR || code == TYPE_CODE_MEMBER
|| code == TYPE_CODE_REF))) || code == TYPE_CODE_REF)))
fprintf (stream, " "); fprintf (stream, " ");
type_print_varspec_prefix (type, stream, show, 0); type_print_varspec_prefix (type, stream, show, 0);
@ -550,12 +554,11 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr)
fputc ('*', stream); fputc ('*', stream);
break; break;
case TYPE_CODE_MPTR: case TYPE_CODE_MEMBER:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
if (passed_a_ptr) type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0,
fputc ('(', stream); passed_a_ptr);
type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, 1); fprintf (stream, "::");
fprintf (stream, "::*");
break; break;
case TYPE_CODE_REF: case TYPE_CODE_REF:
@ -604,10 +607,12 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr)
fprintf (stream, "]"); fprintf (stream, "]");
break; break;
case TYPE_CODE_MPTR: case TYPE_CODE_MEMBER:
if (passed_a_ptr) if (passed_a_ptr)
fputc (')', stream); fputc (')', stream);
/* Fall through. */ type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
break;
case TYPE_CODE_PTR: case TYPE_CODE_PTR:
case TYPE_CODE_REF: case TYPE_CODE_REF:
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1); 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_ARRAY:
case TYPE_CODE_PTR: case TYPE_CODE_PTR:
case TYPE_CODE_MPTR: case TYPE_CODE_MEMBER:
case TYPE_CODE_REF: case TYPE_CODE_REF:
case TYPE_CODE_FUNC: case TYPE_CODE_FUNC:
type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);

View File

@ -464,8 +464,7 @@ unpack_long (type, valaddr)
if (len == sizeof (long)) if (len == sizeof (long))
return * (unsigned long *) valaddr; return * (unsigned long *) valaddr;
} }
else if (code == TYPE_CODE_INT else if (code == TYPE_CODE_INT)
|| code == TYPE_CODE_MPTR)
{ {
if (len == sizeof (char)) if (len == sizeof (char))
return * (char *) valaddr; return * (char *) valaddr;
@ -485,6 +484,9 @@ unpack_long (type, valaddr)
if (len == sizeof (char *)) if (len == sizeof (char *))
return (CORE_ADDR) * (char **) valaddr; 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."); error ("Value not integer or pointer.");
} }

View File

@ -1,3 +1,3 @@
/* Define the current version number of GDB. */ /* 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)";