}
\f
/**************************** 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)
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.");
}
\f
static struct symbol *
{
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;
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
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 */
#endif
-#line 87 "bison.simple"
+#line 165 "bison.simple"
int
yyparse()
{
YYSTYPE yylval;
YYLTYPE yylloc;
+#ifdef YYDEBUG
extern int yydebug;
+#endif
#endif
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.
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. */
if (yychar == YYEMPTY)
{
+#ifdef YYDEBUG
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
yychar = YYLEX;
}
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;
/* 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)
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen]; /* implement default value of the action */
+#ifdef YYDEBUG
if (yydebug)
{
if (yylen == 1)
fprintf (stderr, "Reducing %d values via line %d, ",
yylen, yyrline[yyn]);
}
+#endif
switch (yyn) {
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:
yylsp -= yylen;
yyssp -= yylen;
+#ifdef YYDEBUG
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
+#endif
*++yyvsp = yyval;
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)
if (yychar == YYEOF)
YYERROR;
+#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
yychar = YYEMPTY;
}
yylsp--;
yystate = *--yyssp;
+#ifdef YYDEBUG
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
+#endif
yyerrhandle:
if (yyn == YYFINAL)
YYACCEPT;
+#ifdef YYDEBUG
if (yydebug)
fprintf(stderr, "Shifting error token, ");
+#endif
*++yyvsp = yylval;
*++yylsp = yylloc;
| 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); }
;
BINOP_EXP, /* Exponentiation */
/* C++. */
+ BINOP_MIN, /* <? */
+ BINOP_MAX, /* >? */
BINOP_SCOPE, /* :: */
/* STRUCTOP_MEMBER is used for pointer-to-member constructs.
@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
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 */
};
}
-/* 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.
}
}
-/* 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.
/* 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. */
START_FILE
\f
+value value_x_binop ();
+
value
value_add (arg1, arg2)
value arg1, arg2;
return val;
}
- return value_binop (arg1, arg2, BINOP_ADD);
+ return value_x_binop (arg1, arg2, BINOP_ADD);
}
value
return val;
}
- return value_binop (arg1, arg2, BINOP_SUB);
+ return value_x_binop (arg1, arg2, BINOP_SUB);
}
/* Return the value of ARRAY[IDX]. */
{
return value_ind (value_add (array, idx));
}
+\f
+/* 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);
+}
+\f
/* 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. */
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.");
}
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
{
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)
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)
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)
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)
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;
}
}
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;
}
}
/* 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);
&&
(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);
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:
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);
{
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);
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;
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.");
}
/* 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)";