aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/dbxread.c166
-rw-r--r--gdb/expread.tab.c94
-rw-r--r--gdb/expread.y8
-rw-r--r--gdb/expression.h2
-rw-r--r--gdb/gdb+.texinfo7
-rw-r--r--gdb/symseg.h2
-rw-r--r--gdb/symtab.c77
-rw-r--r--gdb/symtab.h2
-rw-r--r--gdb/valarith.c77
-rw-r--r--gdb/valops.c31
-rw-r--r--gdb/valprint.c295
-rw-r--r--gdb/values.c6
-rw-r--r--gdb/version.c2
13 files changed, 433 insertions, 336 deletions
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index c1c4acc..05326cf 100644
--- a/gdb/dbxread.c
+++ b/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);
- 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. */
+ 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) ;
- /* 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);
+ /* Sort symbols alphabetically within each block. */
- printf ("Reading symbol data from %s...", name);
- fflush (stdout);
+ sort_syms ();
- init_misc_functions ();
- make_cleanup (discard_misc_bunches, 0);
- init_header_files ();
- make_cleanup (free_header_files, 0);
+ /* Go over the all misc functions and install them in vector. */
- read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist)
- ,text_addr, hdr.a_text) ;
+ condense_addl_misc_bunches ();
- /* Sort symbols alphabetically within each block. */
+ /* Don't allow char * to have a typename (else would get caddr_t.) */
- sort_syms ();
+ TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
- /* Go over the all misc functions and install them in vector. */
+ /* Make a default for file to list. */
- condense_addl_misc_bunches ();
+ select_source_symtab (symtab_list);
- /* Don't allow char * to have a typename (else would get caddr_t.) */
+ do_cleanups (old_chain);
- 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;
+ }
- /* 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);
}
-
- 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;
diff --git a/gdb/expread.tab.c b/gdb/expread.tab.c
index e676cf8..8974bd5 100644
--- a/gdb/expread.tab.c
+++ b/gdb/expread.tab.c
@@ -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;
diff --git a/gdb/expread.y b/gdb/expread.y
index d9a18ea..996ca21 100644
--- a/gdb/expread.y
+++ b/gdb/expread.y
@@ -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); }
;
diff --git a/gdb/expression.h b/gdb/expression.h
index ee3791f..0fac7be 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -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.
diff --git a/gdb/gdb+.texinfo b/gdb/gdb+.texinfo
index 627f7ad..0591073 100644
--- a/gdb/gdb+.texinfo
+++ b/gdb/gdb+.texinfo
@@ -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
diff --git a/gdb/symseg.h b/gdb/symseg.h
index f5ad8ea..7b16f8f 100644
--- a/gdb/symseg.h
+++ b/gdb/symseg.h
@@ -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 */
};
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 5540954..ec6f0d6 100644
--- a/gdb/symtab.c
+++ b/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)
- {
- 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 = mtype;
+ while (mtype)
{
- 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.
diff --git a/gdb/symtab.h b/gdb/symtab.h
index d184766..d888dc1 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -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. */
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 03bc1e1..6ce7c6a 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -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.");
}
diff --git a/gdb/valops.c b/gdb/valops.c
index c962932..8992c0f 100644
--- a/gdb/valops.c
+++ b/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;
}
}
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 619c970..32601a6 100644
--- a/gdb/valprint.c
+++ b/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);
diff --git a/gdb/values.c b/gdb/values.c
index 93d9482..8fa5af9 100644
--- a/gdb/values.c
+++ b/gdb/values.c
@@ -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.");
}
diff --git a/gdb/version.c b/gdb/version.c
index 244d065..5e1f907 100644
--- a/gdb/version.c
+++ b/gdb/version.c
@@ -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)";