* ch-exp.y: Replaced by ...
* ch-exp.c: New file. Use recursive-descent. Recognize labelled array tuples and powerset ranges. * Makefile.in: Update for no longer using yacc for ch-exp. * c-lang.c: Make various functions non-static. * c-lang.h: Add bunches of prototypes. * cp-valprint.c (cp_print_value_fields): Also take address. (cp_print_value): Likewise. Use baselcass_offset. * stabsread.c (current_symbol): New static variable. (type_synonym_name): Remove. (read_type): If copying, make copy be a TYPE_CODE_TYPEDEF. (read_array_type): Don't need to handle undefined element type here. (cleanup_undefined_types): Ditto. (read_range_type): Look for Chill ranges. * valops.c (value_assign): Fix case lval_internalvar - don't try to assign into old value (which might be too small!). (value_coerce_array): No longer need special VALUE_REPEATED handling. (value_arg_coerce): Cleaner array->pointer decay mechanism. (search_struct_field): Use baseclass_offset rather than baseclass_addr. (value_slice): Use get_discrete_bounds. * value.h (COERCE_VARYING_ARRAY): Take type argumnt as well. * values.c (baseclass_offset): Change parameter interface. (baseclass_addr): Removed. * c-typeprint.c, c-valprint.c, ch-valprint.c, values.c, valops.c: Add check_typedef/CHECK_TYPEDEF as needed.
This commit is contained in:
parent
dcdba37e2d
commit
5e54886116
13 changed files with 2388 additions and 2165 deletions
|
@ -26,6 +26,34 @@ Wed Nov 29 13:35:18 1995 Per Bothner <bothner@kalessin.cygnus.com>
|
|||
* gdbtypes.c, ch-lang.c, ch-typeprint.c (numerous places):
|
||||
Add check_typedef/CHECK_TYPEDEF as needed.
|
||||
|
||||
* ch-exp.y: Replaced by ...
|
||||
* ch-exp.c: New file. Use recursive-descent.
|
||||
Recognize labelled array tuples and powerset ranges.
|
||||
* Makefile.in: Update for no longer using yacc for ch-exp.
|
||||
|
||||
* c-lang.c: Make various functions non-static.
|
||||
* c-lang.h: Add bunches of prototypes.
|
||||
* cp-valprint.c (cp_print_value_fields): Also take address.
|
||||
(cp_print_value): Likewise. Use baselcass_offset.
|
||||
* stabsread.c (current_symbol): New static variable.
|
||||
(type_synonym_name): Remove.
|
||||
(read_type): If copying, make copy be a TYPE_CODE_TYPEDEF.
|
||||
(read_array_type): Don't need to handle undefined element type here.
|
||||
(cleanup_undefined_types): Ditto.
|
||||
(read_range_type): Look for Chill ranges.
|
||||
* valops.c (value_assign): Fix case lval_internalvar - don't try
|
||||
to assign into old value (which might be too small!).
|
||||
(value_coerce_array): No longer need special VALUE_REPEATED handling.
|
||||
(value_arg_coerce): Cleaner array->pointer decay mechanism.
|
||||
(search_struct_field): Use baseclass_offset rather than
|
||||
baseclass_addr.
|
||||
(value_slice): Use get_discrete_bounds.
|
||||
* value.h (COERCE_VARYING_ARRAY): Take type argumnt as well.
|
||||
* values.c (baseclass_offset): Change parameter interface.
|
||||
(baseclass_addr): Removed.
|
||||
* c-typeprint.c, c-valprint.c, ch-valprint.c, values.c, valops.c:
|
||||
Add check_typedef/CHECK_TYPEDEF as needed.
|
||||
|
||||
* alpha-tdep.c, c-exp.y, h8500-tdep.c, f-exp.y, f-valprint.c,
|
||||
findvar.c, hppa-tdep.c, infcmd.c, language.c, printcmd.c,
|
||||
rs6000-tdep.c, symmisc.c, symtab.c, mdebugread.c:
|
||||
|
|
|
@ -347,7 +347,7 @@ TARGET_FLAGS_TO_PASS = \
|
|||
# SFILES is used in building the distribution archive.
|
||||
|
||||
SFILES = blockframe.c breakpoint.c buildsym.c callback.c c-exp.y c-lang.c \
|
||||
c-typeprint.c c-valprint.c ch-exp.y ch-lang.c ch-typeprint.c \
|
||||
c-typeprint.c c-valprint.c ch-exp.c ch-lang.c ch-typeprint.c \
|
||||
ch-valprint.c coffread.c command.c complaints.c corefile.c cp-valprint.c \
|
||||
dbxread.c demangle.c dwarfread.c \
|
||||
elfread.c environ.c eval.c expprint.c \
|
||||
|
@ -466,7 +466,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o stack.o thread.o \
|
|||
exec.o objfiles.o minsyms.o maint.o demangle.o \
|
||||
dbxread.o coffread.o elfread.o \
|
||||
dwarfread.o mipsread.o stabsread.o corefile.o \
|
||||
c-lang.o ch-lang.o f-lang.o m2-lang.o \
|
||||
c-lang.o ch-exp.o ch-lang.o f-lang.o m2-lang.o \
|
||||
scm-exp.o scm-lang.o scm-valprint.o complaints.o typeprint.o \
|
||||
c-typeprint.o ch-typeprint.o f-typeprint.o m2-typeprint.o \
|
||||
c-valprint.o cp-valprint.o ch-valprint.o f-valprint.o m2-valprint.o \
|
||||
|
@ -485,8 +485,8 @@ NTSSTART = kdb-start.o
|
|||
SUBDIRS = doc testsuite nlm
|
||||
|
||||
# For now, shortcut the "configure GDB for fewer languages" stuff.
|
||||
YYFILES = c-exp.tab.c f-exp.tab.c m2-exp.tab.c ch-exp.tab.c
|
||||
YYOBJ = c-exp.tab.o f-exp.tab.o m2-exp.tab.o ch-exp.tab.o
|
||||
YYFILES = c-exp.tab.c f-exp.tab.c m2-exp.tab.c
|
||||
YYOBJ = c-exp.tab.o f-exp.tab.o m2-exp.tab.o
|
||||
|
||||
# Things which need to be built when making a distribution.
|
||||
|
||||
|
@ -630,10 +630,10 @@ libgdb-files: $(LIBGDBDEPS) Makefile.in
|
|||
saber_gdb: $(SFILES) $(DEPFILES) copying.c version.c
|
||||
#setopt load_flags $(CFLAGS) $(BFD_CFLAGS) -DHOST_SYS=SUN4_SYS
|
||||
#load ./init.c $(SFILES)
|
||||
#unload $(srcdir)/c-exp.y $(srcdir)/m2-exp.y $(srcdir)/ch-exp.y
|
||||
#unload $(srcdir)/c-exp.y $(srcdir)/m2-exp.y
|
||||
#unload vx-share/*.h
|
||||
#unload nindy-share/[A-Z]*
|
||||
#load c-exp.tab.c m2-exp.tab.c ch-exp.tab.c
|
||||
#load c-exp.tab.c m2-exp.tab.c
|
||||
#load copying.c version.c
|
||||
#load ../opcodes/libopcodes.a
|
||||
#load ../libiberty/libiberty.a
|
||||
|
@ -722,7 +722,7 @@ clean mostlyclean:
|
|||
rm -f gdb core make.log libgdb-files
|
||||
rm -f gdb[0-9]
|
||||
|
||||
# This used to depend on c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS
|
||||
# This used to depend on c-exp.tab.c m2-exp.tab.c TAGS
|
||||
# I believe this is wrong; the makefile standards for distclean just
|
||||
# describe removing files; the only sort of "re-create a distribution"
|
||||
# functionality described is if the distributed files are unmodified.
|
||||
|
@ -737,7 +737,7 @@ maintainer-clean realclean: clean
|
|||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
@$(MAKE) $(FLAGS_TO_PASS) DO=maintainer-clean "DODIRS=$(SUBDIRS)" subdir_do
|
||||
rm -f c-exp.tab.c f-exp.tab.c m2-exp.tab.c ch-exp.tab.c
|
||||
rm -f c-exp.tab.c f-exp.tab.c m2-exp.tab.c
|
||||
rm -f TAGS $(INFOFILES)
|
||||
rm -f nm.h tm.h xm.h config.status
|
||||
rm -f y.output yacc.acts yacc.tmp
|
||||
|
@ -825,35 +825,12 @@ f-exp.tab.c: f-exp.y c-exp.tab.c
|
|||
-rm y.tab.c
|
||||
mv f-exp.new ./f-exp.tab.c
|
||||
|
||||
# ch-exp.tab.c is generated in objdir from ch-exp.y if it doesn't exist
|
||||
# in srcdir, then compiled in objdir to ch-exp.tab.o.
|
||||
# Remove bogus decls for malloc/realloc/free which conflict with everything
|
||||
# else.
|
||||
ch-exp.tab.o: ch-exp.tab.c
|
||||
# the dependency here on f-exp.tab.c is artificial. Without this
|
||||
# dependency, a parallel make will attempt to build both at the same
|
||||
# time and the second yacc will pollute the first y.tab.c file.
|
||||
ch-exp.tab.c: ch-exp.y f-exp.tab.c
|
||||
$(YACC) $(YFLAGS) $(srcdir)/ch-exp.y
|
||||
-sed -e '/extern.*malloc/d' \
|
||||
-e '/extern.*realloc/d' \
|
||||
-e '/extern.*free/d' \
|
||||
-e '/include.*malloc.h/d' \
|
||||
-e 's/malloc/xmalloc/g' \
|
||||
-e 's/realloc/xrealloc/g' \
|
||||
< y.tab.c > ch-exp.new
|
||||
-rm y.tab.c
|
||||
mv ch-exp.new ./ch-exp.tab.c
|
||||
|
||||
# m2-exp.tab.c is generated in objdir from m2-exp.y if it doesn't exist
|
||||
# in srcdir, then compiled in objdir to m2-exp.tab.o.
|
||||
# Remove bogus decls for malloc/realloc/free which conflict with everything
|
||||
# else.
|
||||
m2-exp.tab.o: m2-exp.tab.c
|
||||
# the dependency here on ch-exp.tab.c is artificial. Without this
|
||||
# dependency, a parallel make will attempt to build both at the same
|
||||
# time and the second yacc will pollute the first y.tab.c file.
|
||||
m2-exp.tab.c: m2-exp.y ch-exp.tab.c
|
||||
m2-exp.tab.c: m2-exp.y
|
||||
$(YACC) $(YFLAGS) $(srcdir)/m2-exp.y
|
||||
-sed -e '/extern.*malloc/d' \
|
||||
-e '/extern.*realloc/d' \
|
||||
|
@ -866,7 +843,7 @@ m2-exp.tab.c: m2-exp.y ch-exp.tab.c
|
|||
mv m2-exp.new ./m2-exp.tab.c
|
||||
|
||||
# These files are updated atomically, so make never has to remove them
|
||||
.PRECIOUS: m2-exp.tab.c ch-exp.tab.c f-exp.tab.c c-exp.tab.c
|
||||
.PRECIOUS: m2-exp.tab.c f-exp.tab.c c-exp.tab.c
|
||||
|
||||
lint: $(LINTFILES)
|
||||
$(LINT) $(INCLUDE_CFLAGS) $(LINTFLAGS) $(LINTFILES) \
|
||||
|
@ -1525,10 +1502,6 @@ c-exp.tab.o: c-exp.tab.c c-lang.h $(defs_h) $(expression_h) \
|
|||
$(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
|
||||
$(bfd_h) objfiles.h symfile.h
|
||||
|
||||
ch-exp.tab.o: ch-exp.tab.c ch-lang.h $(defs_h) $(expression_h) \
|
||||
$(gdbtypes_h) language.h parser-defs.h $(symtab_h) $(value_h) \
|
||||
$(bfd_h) objfiles.h symfile.h
|
||||
|
||||
f-exp.tab.o: f-exp.tab.c f-lang.h $(defs_h) $(expression_h) \
|
||||
language.h parser-defs.h $(value_h) $(bfd_h) objfiles.h symfile.h
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ emit_char (c, stream, quoter)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
c_printchar (c, stream)
|
||||
int c;
|
||||
GDB_FILE *stream;
|
||||
|
@ -93,7 +93,7 @@ c_printchar (c, stream)
|
|||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
|
||||
|
||||
static void
|
||||
void
|
||||
c_printstr (stream, string, length, force_ellipses)
|
||||
GDB_FILE *stream;
|
||||
char *string;
|
||||
|
@ -211,7 +211,7 @@ c_printstr (stream, string, length, force_ellipses)
|
|||
starts taking it's fundamental type information directly from the
|
||||
debugging information supplied by the compiler. fnf@cygnus.com */
|
||||
|
||||
static struct type *
|
||||
struct type *
|
||||
c_create_fundamental_type (objfile, typeid)
|
||||
struct objfile *objfile;
|
||||
int typeid;
|
||||
|
@ -333,7 +333,7 @@ c_create_fundamental_type (objfile, typeid)
|
|||
/* Table mapping opcodes into strings for printing operators
|
||||
and precedences of the operators. */
|
||||
|
||||
static const struct op_print c_op_print_tab[] =
|
||||
const struct op_print c_op_print_tab[] =
|
||||
{
|
||||
{",", BINOP_COMMA, PREC_COMMA, 0},
|
||||
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
|
||||
|
|
48
gdb/c-lang.h
48
gdb/c-lang.h
|
@ -36,3 +36,51 @@ c_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
|
|||
|
||||
extern int
|
||||
c_value_print PARAMS ((struct value *, GDB_FILE *, int, enum val_prettyprint));
|
||||
|
||||
/* These are in c-lang.c: */
|
||||
|
||||
extern void c_printchar PARAMS ((int, GDB_FILE*));
|
||||
|
||||
extern void c_printstr PARAMS ((GDB_FILE *, char *, unsigned int, int));
|
||||
|
||||
extern struct type * c_create_fundamental_type PARAMS ((struct objfile*, int));
|
||||
|
||||
extern const struct op_print c_op_print_tab[];
|
||||
|
||||
extern struct type ** const (c_builtin_types[]);
|
||||
|
||||
/* These are in c-typeprint.c: */
|
||||
|
||||
extern void
|
||||
c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
|
||||
|
||||
extern void
|
||||
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
|
||||
|
||||
extern void
|
||||
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
|
||||
GDB_FILE *));
|
||||
/* These are in cp-valprint.c */
|
||||
|
||||
extern void
|
||||
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
|
||||
GDB_FILE *));
|
||||
|
||||
extern int vtblprint; /* Controls printing of vtbl's */
|
||||
|
||||
extern void
|
||||
cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *));
|
||||
|
||||
extern void
|
||||
cp_print_class_method PARAMS ((char *, struct type *, GDB_FILE *));
|
||||
|
||||
extern void
|
||||
cp_print_value_fields PARAMS ((struct type *, char *, CORE_ADDR,
|
||||
GDB_FILE *, int, int, enum val_prettyprint,
|
||||
struct type**, int));
|
||||
|
||||
extern int
|
||||
cp_is_vtbl_ptr_type PARAMS ((struct type *));
|
||||
|
||||
extern int
|
||||
cp_is_vtbl_member PARAMS ((struct type *));
|
||||
|
|
|
@ -50,9 +50,6 @@ cp_type_print_derivation_info PARAMS ((GDB_FILE *, struct type *));
|
|||
void
|
||||
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
|
||||
|
||||
void
|
||||
c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
|
||||
|
||||
|
||||
/* Print a description of a type in the format of a
|
||||
typedef for the current language.
|
||||
|
@ -64,6 +61,7 @@ c_typedef_print (type, new, stream)
|
|||
struct symbol *new;
|
||||
GDB_FILE *stream;
|
||||
{
|
||||
CHECK_TYPEDEF (type);
|
||||
switch (current_language->la_language)
|
||||
{
|
||||
#ifdef _LANG_c
|
||||
|
@ -118,6 +116,9 @@ c_print_type (type, varstring, stream, show, level)
|
|||
register enum type_code code;
|
||||
int demangled_args;
|
||||
|
||||
if (show > 0)
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
c_type_print_base (type, stream, show, level);
|
||||
code = TYPE_CODE (type);
|
||||
if ((varstring != NULL && *varstring != '\0')
|
||||
|
@ -315,6 +316,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
|
|||
case TYPE_CODE_STRING:
|
||||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
/* These types need no prefix. They are listed here so that
|
||||
gcc -Wall will reveal any types that haven't been handled. */
|
||||
break;
|
||||
|
@ -453,6 +455,7 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
|
|||
case TYPE_CODE_STRING:
|
||||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
/* These types do not need a suffix. They are listed so that
|
||||
gcc -Wall will report types that may not have been considered. */
|
||||
break;
|
||||
|
@ -510,10 +513,11 @@ c_type_print_base (type, stream, show, level)
|
|||
return;
|
||||
}
|
||||
|
||||
check_stub_type (type);
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
case TYPE_CODE_ARRAY:
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_MEMBER:
|
||||
|
|
|
@ -26,40 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "demangle.h"
|
||||
#include "valprint.h"
|
||||
#include "language.h"
|
||||
|
||||
/* BEGIN-FIXME */
|
||||
|
||||
extern int vtblprint; /* Controls printing of vtbl's */
|
||||
|
||||
extern void
|
||||
cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *));
|
||||
|
||||
extern void
|
||||
cp_print_class_method PARAMS ((char *, struct type *, GDB_FILE *));
|
||||
|
||||
extern void
|
||||
cp_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int,
|
||||
enum val_prettyprint, struct type **, int));
|
||||
|
||||
extern int
|
||||
cp_is_vtbl_ptr_type PARAMS ((struct type *));
|
||||
|
||||
extern int
|
||||
cp_is_vtbl_member PARAMS ((struct type *));
|
||||
|
||||
/* END-FIXME */
|
||||
|
||||
|
||||
/* BEGIN-FIXME: Hooks into c-typeprint.c */
|
||||
|
||||
extern void
|
||||
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
|
||||
|
||||
extern void
|
||||
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
|
||||
GDB_FILE *));
|
||||
/* END-FIXME */
|
||||
|
||||
#include "c-lang.h"
|
||||
|
||||
|
||||
/* Print data of type TYPE located at VALADDR (within GDB), which came from
|
||||
|
@ -94,12 +61,13 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
LONGEST val;
|
||||
CORE_ADDR addr;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
|
||||
{
|
||||
elttype = TYPE_TARGET_TYPE (type);
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
eltlen = TYPE_LENGTH (elttype);
|
||||
len = TYPE_LENGTH (type) / eltlen;
|
||||
if (prettyprint_arrays)
|
||||
|
@ -169,11 +137,12 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
stream, demangle);
|
||||
break;
|
||||
}
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
|
||||
{
|
||||
cp_print_class_method (valaddr, type, stream);
|
||||
}
|
||||
else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
|
||||
else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
|
||||
{
|
||||
cp_print_class_member (valaddr,
|
||||
TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
|
||||
|
@ -183,7 +152,6 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
{
|
||||
addr = unpack_pointer (type, valaddr);
|
||||
print_unpacked_pointer:
|
||||
elttype = TYPE_TARGET_TYPE (type);
|
||||
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
|
||||
{
|
||||
|
@ -266,10 +234,11 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
break;
|
||||
|
||||
case TYPE_CODE_REF:
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
|
||||
{
|
||||
cp_print_class_member (valaddr,
|
||||
TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
|
||||
TYPE_DOMAIN_TYPE (elttype),
|
||||
stream, "");
|
||||
break;
|
||||
}
|
||||
|
@ -285,7 +254,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
/* De-reference the reference. */
|
||||
if (deref_ref)
|
||||
{
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
|
||||
if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
|
||||
{
|
||||
value_ptr deref_val =
|
||||
value_at
|
||||
|
@ -318,10 +287,10 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */
|
||||
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)),
|
||||
stream, demangle);
|
||||
break;
|
||||
}
|
||||
cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
|
||||
NULL, 0);
|
||||
else
|
||||
cp_print_value_fields (type, valaddr, address, stream, format,
|
||||
recurse, pretty, NULL, 0);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ENUM:
|
||||
|
|
1974
gdb/ch-exp.c
Normal file
1974
gdb/ch-exp.c
Normal file
File diff suppressed because it is too large
Load diff
1664
gdb/ch-exp.y
1664
gdb/ch-exp.y
File diff suppressed because it is too large
Load diff
|
@ -78,6 +78,7 @@ chill_print_type_scalar (type, val, stream)
|
|||
case TYPE_CODE_CHAR:
|
||||
case TYPE_CODE_BOOL:
|
||||
case TYPE_CODE_COMPLEX:
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ chill_val_print_array_elements (type, valaddr, address, stream,
|
|||
unsigned int reps;
|
||||
LONGEST low_bound = TYPE_FIELD_BITPOS (range_type, 0);
|
||||
|
||||
elttype = TYPE_TARGET_TYPE (type);
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
eltlen = TYPE_LENGTH (elttype);
|
||||
len = TYPE_LENGTH (type) / eltlen;
|
||||
|
||||
|
@ -205,6 +206,8 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
struct type *elttype;
|
||||
CORE_ADDR addr;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
|
@ -289,7 +292,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
break;
|
||||
}
|
||||
addr = unpack_pointer (type, valaddr);
|
||||
elttype = TYPE_TARGET_TYPE (type);
|
||||
elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
|
||||
/* We assume a NULL pointer is all zeros ... */
|
||||
if (addr == 0)
|
||||
|
@ -338,7 +341,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
case TYPE_CODE_BITSTRING:
|
||||
case TYPE_CODE_SET:
|
||||
elttype = TYPE_INDEX_TYPE (type);
|
||||
check_stub_type (elttype);
|
||||
CHECK_TYPEDEF (elttype);
|
||||
if (TYPE_FLAGS (elttype) & TYPE_FLAG_STUB)
|
||||
{
|
||||
fprintf_filtered (stream, "<incomplete type>");
|
||||
|
@ -405,7 +408,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||
case TYPE_CODE_STRUCT:
|
||||
if (chill_varying_type (type))
|
||||
{
|
||||
struct type *inner = TYPE_FIELD_TYPE (type, 1);
|
||||
struct type *inner = check_typedef (TYPE_FIELD_TYPE (type, 1));
|
||||
long length = unpack_long (TYPE_FIELD_TYPE (type, 0), valaddr);
|
||||
char *data_addr = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8;
|
||||
|
||||
|
@ -509,7 +512,7 @@ chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
|
|||
int i, len;
|
||||
int fields_seen = 0;
|
||||
|
||||
check_stub_type (type);
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
fprintf_filtered (stream, "[");
|
||||
len = TYPE_NFIELDS (type);
|
||||
|
@ -575,15 +578,14 @@ chill_value_print (val, stream, format, pretty)
|
|||
enum val_prettyprint pretty;
|
||||
{
|
||||
struct type *type = VALUE_TYPE (val);
|
||||
struct type *real_type = check_typedef (type);
|
||||
|
||||
/* If it is a pointer, indicate what it points to.
|
||||
|
||||
Print type also if it is a reference.
|
||||
Print type also if it is a reference. */
|
||||
|
||||
C++: if it is a member pointer, we will take care
|
||||
of that when we print it. */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_PTR ||
|
||||
TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
if (TYPE_CODE (real_type) == TYPE_CODE_PTR ||
|
||||
TYPE_CODE (real_type) == TYPE_CODE_REF)
|
||||
{
|
||||
char *valaddr = VALUE_CONTENTS (val);
|
||||
CORE_ADDR addr = unpack_pointer (type, valaddr);
|
||||
|
|
|
@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "demangle.h"
|
||||
#include "annotate.h"
|
||||
#include "gdb_string.h"
|
||||
#include "c-lang.h"
|
||||
|
||||
int vtblprint; /* Controls printing of vtbl's */
|
||||
int objectprint; /* Controls looking up an object's derived type
|
||||
|
@ -43,22 +44,8 @@ cp_print_static_field PARAMS ((struct type *, value_ptr, GDB_FILE *, int, int,
|
|||
enum val_prettyprint));
|
||||
|
||||
static void
|
||||
cplus_print_value PARAMS ((struct type *, char *, GDB_FILE *, int, int,
|
||||
enum val_prettyprint, struct type **));
|
||||
|
||||
/* BEGIN-FIXME: Hooks into typeprint.c, find a better home for prototypes. */
|
||||
|
||||
extern void
|
||||
c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
|
||||
|
||||
extern void
|
||||
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
|
||||
|
||||
extern void
|
||||
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
|
||||
GDB_FILE *));
|
||||
|
||||
/* END-FIXME */
|
||||
cp_print_value PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *,
|
||||
int, int, enum val_prettyprint, struct type **));
|
||||
|
||||
void
|
||||
cp_print_class_method (valaddr, type, stream)
|
||||
|
@ -76,9 +63,9 @@ cp_print_class_method (valaddr, type, stream)
|
|||
struct symbol *sym;
|
||||
unsigned len;
|
||||
unsigned int i;
|
||||
struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
|
||||
check_stub_type (TYPE_TARGET_TYPE (type));
|
||||
domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
|
||||
domain = TYPE_DOMAIN_TYPE (target_type);
|
||||
if (domain == (struct type *)NULL)
|
||||
{
|
||||
fprintf_filtered (stream, "<unknown>");
|
||||
|
@ -204,20 +191,21 @@ cp_is_vtbl_member(type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Mutually recursive subroutines of cplus_print_value and c_val_print to
|
||||
print out a structure's fields: cp_print_value_fields and cplus_print_value.
|
||||
|
||||
TYPE, VALADDR, STREAM, RECURSE, and PRETTY have the
|
||||
same meanings as in cplus_print_value and c_val_print.
|
||||
/* Mutually recursive subroutines of cp_print_value and c_val_print to
|
||||
print out a structure's fields: cp_print_value_fields and cp_print_value.
|
||||
|
||||
TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
|
||||
same meanings as in cp_print_value and c_val_print.
|
||||
|
||||
DONT_PRINT is an array of baseclass types that we
|
||||
should not print, or zero if called from top level. */
|
||||
|
||||
void
|
||||
cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
|
||||
cp_print_value_fields (type, valaddr, address, stream, format, recurse, pretty,
|
||||
dont_print_vb, dont_print_statmem)
|
||||
struct type *type;
|
||||
char *valaddr;
|
||||
CORE_ADDR address;
|
||||
GDB_FILE *stream;
|
||||
int format;
|
||||
int recurse;
|
||||
|
@ -229,7 +217,7 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
|
|||
struct obstack tmp_obstack;
|
||||
char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack);
|
||||
|
||||
check_stub_type (type);
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
fprintf_filtered (stream, "{");
|
||||
len = TYPE_NFIELDS (type);
|
||||
|
@ -238,8 +226,8 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
|
|||
/* Print out baseclasses such that we don't print
|
||||
duplicates of virtual baseclasses. */
|
||||
if (n_baseclasses > 0)
|
||||
cplus_print_value (type, valaddr, stream, format, recurse+1, pretty,
|
||||
dont_print_vb);
|
||||
cp_print_value (type, valaddr, address, stream,
|
||||
format, recurse+1, pretty, dont_print_vb);
|
||||
|
||||
if (!len && n_baseclasses == 1)
|
||||
fprintf_filtered (stream, "<No data fields>");
|
||||
|
@ -390,10 +378,11 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
|
|||
baseclasses. */
|
||||
|
||||
static void
|
||||
cplus_print_value (type, valaddr, stream, format, recurse, pretty,
|
||||
dont_print_vb)
|
||||
cp_print_value (type, valaddr, address, stream, format, recurse, pretty,
|
||||
dont_print_vb)
|
||||
struct type *type;
|
||||
char *valaddr;
|
||||
CORE_ADDR address;
|
||||
GDB_FILE *stream;
|
||||
int format;
|
||||
int recurse;
|
||||
|
@ -417,14 +406,9 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty,
|
|||
|
||||
for (i = 0; i < n_baseclasses; i++)
|
||||
{
|
||||
/* FIXME-32x64--assumes that a target pointer can fit in a char *.
|
||||
Fix it by nuking baseclass_addr. */
|
||||
char *baddr;
|
||||
int err;
|
||||
char *basename;
|
||||
|
||||
check_stub_type (TYPE_BASECLASS (type, i));
|
||||
basename = TYPE_NAME (TYPE_BASECLASS (type, i));
|
||||
int boffset;
|
||||
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
|
||||
char *basename = TYPE_NAME (baseclass);
|
||||
|
||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||
{
|
||||
|
@ -435,17 +419,13 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty,
|
|||
- first_dont_print;
|
||||
|
||||
while (--j >= 0)
|
||||
if (TYPE_BASECLASS (type, i) == first_dont_print[j])
|
||||
if (baseclass == first_dont_print[j])
|
||||
goto flush_it;
|
||||
|
||||
obstack_ptr_grow (&dont_print_vb_obstack, TYPE_BASECLASS (type, i));
|
||||
obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
|
||||
}
|
||||
|
||||
/* Fix to use baseclass_offset instead. FIXME */
|
||||
baddr = baseclass_addr (type, i, valaddr, 0, &err);
|
||||
if (err == 0 && baddr == 0)
|
||||
error ("could not find virtual baseclass %s\n",
|
||||
basename ? basename : "");
|
||||
boffset = baseclass_offset (type, i , valaddr, address);
|
||||
|
||||
if (pretty)
|
||||
{
|
||||
|
@ -457,15 +437,11 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty,
|
|||
baseclass name. */
|
||||
fputs_filtered (basename ? basename : "", stream);
|
||||
fputs_filtered ("> = ", stream);
|
||||
if (err != 0)
|
||||
{
|
||||
fprintf_filtered (stream, "<invalid address ");
|
||||
print_address_numeric ((CORE_ADDR) baddr, 1, stream);
|
||||
fprintf_filtered (stream, ">");
|
||||
}
|
||||
if (boffset == -1)
|
||||
fprintf_filtered (stream, "<invalid address>");
|
||||
else
|
||||
cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format,
|
||||
recurse, pretty,
|
||||
cp_print_value_fields (baseclass, valaddr + boffset, address + boffset,
|
||||
stream, format, recurse, pretty,
|
||||
(struct type **) obstack_base (&dont_print_vb_obstack),
|
||||
0);
|
||||
fputs_filtered (", ", stream);
|
||||
|
@ -526,10 +502,9 @@ cp_print_static_field (type, val, stream, format, recurse, pretty)
|
|||
obstack_grow (&dont_print_statmem_obstack, &VALUE_ADDRESS (val),
|
||||
sizeof (CORE_ADDR));
|
||||
|
||||
check_stub_type (type);
|
||||
cp_print_value_fields (type, VALUE_CONTENTS (val),
|
||||
stream, format, recurse, pretty,
|
||||
NULL, 1);
|
||||
CHECK_TYPEDEF (type);
|
||||
cp_print_value_fields (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val),
|
||||
stream, format, recurse, pretty, NULL, 1);
|
||||
return;
|
||||
}
|
||||
val_print (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val),
|
||||
|
|
110
gdb/stabsread.c
110
gdb/stabsread.c
|
@ -199,6 +199,7 @@ struct complaint stabs_general_complaint =
|
|||
static struct type **undef_types;
|
||||
static int undef_types_allocated;
|
||||
static int undef_types_length;
|
||||
static struct symbol *current_symbol = NULL;
|
||||
|
||||
/* Check for and handle cretinous stabs symbol name continuation! */
|
||||
#define STABS_CONTINUE(pp) \
|
||||
|
@ -492,14 +493,6 @@ read_type_number (pp, typenums)
|
|||
}
|
||||
|
||||
|
||||
/* To handle GNU C++ typename abbreviation, we need to be able to
|
||||
fill in a type's name as soon as space for that type is allocated.
|
||||
`type_synonym_name' is the name of the type being allocated.
|
||||
It is cleared as soon as it is used (lest all allocated types
|
||||
get this name). */
|
||||
|
||||
static char *type_synonym_name;
|
||||
|
||||
#if !defined (REG_STRUCT_HAS_ADDR)
|
||||
#define REG_STRUCT_HAS_ADDR(gcc_p,type) 0
|
||||
#endif
|
||||
|
@ -544,7 +537,7 @@ define_symbol (valu, string, desc, type, objfile)
|
|||
e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */
|
||||
nameless = (p == string || ((string[0] == ' ') && (string[1] == ':')));
|
||||
|
||||
sym = (struct symbol *)
|
||||
current_symbol = sym = (struct symbol *)
|
||||
obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
|
||||
memset (sym, 0, sizeof (struct symbol));
|
||||
|
||||
|
@ -1120,23 +1113,13 @@ define_symbol (valu, string, desc, type, objfile)
|
|||
synonym = *p == 't';
|
||||
|
||||
if (synonym)
|
||||
{
|
||||
p++;
|
||||
type_synonym_name = obsavestring (SYMBOL_NAME (sym),
|
||||
strlen (SYMBOL_NAME (sym)),
|
||||
&objfile -> symbol_obstack);
|
||||
}
|
||||
p++;
|
||||
/* The semantics of C++ state that "struct foo { ... }" also defines
|
||||
a typedef for "foo". Unfortunately, cfront never makes the typedef
|
||||
when translating C++ into C. We make the typedef here so that
|
||||
"ptype foo" works as expected for cfront translated code. */
|
||||
else if (current_subfile->language == language_cplus)
|
||||
{
|
||||
synonym = 1;
|
||||
type_synonym_name = obsavestring (SYMBOL_NAME (sym),
|
||||
strlen (SYMBOL_NAME (sym)),
|
||||
&objfile -> symbol_obstack);
|
||||
}
|
||||
synonym = 1;
|
||||
|
||||
SYMBOL_TYPE (sym) = read_type (&p, objfile);
|
||||
|
||||
|
@ -1562,15 +1545,23 @@ read_type (pp, objfile)
|
|||
now anyway). */
|
||||
|
||||
type = alloc_type (objfile);
|
||||
memcpy (type, xtype, sizeof (struct type));
|
||||
|
||||
/* The idea behind clearing the names is that the only purpose
|
||||
for defining a type to another type is so that the name of
|
||||
one can be different. So we probably don't need to worry much
|
||||
about the case where the compiler doesn't give a name to the
|
||||
new type. */
|
||||
TYPE_NAME (type) = NULL;
|
||||
TYPE_TAG_NAME (type) = NULL;
|
||||
if (SYMBOL_LINE (current_symbol) == 0)
|
||||
{
|
||||
*type = *xtype;
|
||||
/* The idea behind clearing the names is that the only purpose
|
||||
for defining a type to another type is so that the name of
|
||||
one can be different. So we probably don't need to worry
|
||||
much about the case where the compiler doesn't give a name
|
||||
to the new type. */
|
||||
TYPE_NAME (type) = NULL;
|
||||
TYPE_TAG_NAME (type) = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
|
||||
TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
|
||||
TYPE_TARGET_TYPE (type) = xtype;
|
||||
}
|
||||
}
|
||||
if (typenums[0] != -1)
|
||||
*dbx_lookup_type (typenums) = type;
|
||||
|
@ -1718,11 +1709,6 @@ read_type (pp, objfile)
|
|||
case 's': /* Struct type */
|
||||
case 'u': /* Union type */
|
||||
type = dbx_alloc_type (typenums, objfile);
|
||||
if (!TYPE_NAME (type))
|
||||
{
|
||||
TYPE_NAME (type) = type_synonym_name;
|
||||
}
|
||||
type_synonym_name = NULL;
|
||||
switch (type_descriptor)
|
||||
{
|
||||
case 's':
|
||||
|
@ -3049,15 +3035,6 @@ read_array_type (pp, type, objfile)
|
|||
create_range_type ((struct type *) NULL, index_type, lower, upper);
|
||||
type = create_array_type (type, element_type, range_type);
|
||||
|
||||
/* If we have an array whose element type is not yet known, but whose
|
||||
bounds *are* known, record it to be adjusted at the end of the file. */
|
||||
|
||||
if ((TYPE_FLAGS (element_type) & TYPE_FLAG_STUB) && !adjustable)
|
||||
{
|
||||
TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
|
||||
add_undefined_type (type);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -3497,7 +3474,7 @@ read_range_type (pp, typenums, objfile)
|
|||
if (self_subrange && n2 == 0 && n3 == 0)
|
||||
return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
|
||||
|
||||
/* If n3 is zero and n2 is not, we want a floating type,
|
||||
/* If n3 is zero and n2 is positive, we want a floating type,
|
||||
and n2 is the width in bytes.
|
||||
|
||||
Fortran programs appear to use this for complex types also,
|
||||
|
@ -3529,6 +3506,10 @@ read_range_type (pp, typenums, objfile)
|
|||
else if (self_subrange && n2 == 0 && n3 == 127)
|
||||
return init_type (TYPE_CODE_INT, 1, 0, NULL, objfile);
|
||||
|
||||
else if (current_symbol && SYMBOL_LANGUAGE (current_symbol) == language_chill
|
||||
&& SYMBOL_LINE (current_symbol) > 0)
|
||||
goto handle_true_range;
|
||||
|
||||
/* We used to do this only for subrange of self or subrange of int. */
|
||||
else if (n2 == 0)
|
||||
{
|
||||
|
@ -3794,7 +3775,7 @@ cleanup_undefined_types ()
|
|||
case TYPE_CODE_ENUM:
|
||||
{
|
||||
/* Check if it has been defined since. Need to do this here
|
||||
as well as in check_stub_type to deal with the (legitimate in
|
||||
as well as in check_typedef to deal with the (legitimate in
|
||||
C though not C++) case of several types with the same name
|
||||
in different source files. */
|
||||
if (TYPE_FLAGS (*type) & TYPE_FLAG_STUB)
|
||||
|
@ -3831,43 +3812,6 @@ cleanup_undefined_types ()
|
|||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_ARRAY:
|
||||
{
|
||||
/* This is a kludge which is here for historical reasons
|
||||
because I suspect that check_stub_type does not get
|
||||
called everywhere it needs to be called for arrays. Even
|
||||
with this kludge, those places are broken for the case
|
||||
where the stub type is defined in another compilation
|
||||
unit, but this kludge at least deals with it for the case
|
||||
in which it is the same compilation unit.
|
||||
|
||||
Don't try to do this by calling check_stub_type; it might
|
||||
cause symbols to be read in lookup_symbol, and the symbol
|
||||
reader is not reentrant. */
|
||||
|
||||
struct type *range_type;
|
||||
int lower, upper;
|
||||
|
||||
if (TYPE_LENGTH (*type) != 0) /* Better be unknown */
|
||||
goto badtype;
|
||||
if (TYPE_NFIELDS (*type) != 1)
|
||||
goto badtype;
|
||||
range_type = TYPE_FIELD_TYPE (*type, 0);
|
||||
if (TYPE_CODE (range_type) != TYPE_CODE_RANGE)
|
||||
goto badtype;
|
||||
|
||||
/* Now recompute the length of the array type, based on its
|
||||
number of elements and the target type's length. */
|
||||
lower = TYPE_FIELD_BITPOS (range_type, 0);
|
||||
upper = TYPE_FIELD_BITPOS (range_type, 1);
|
||||
TYPE_LENGTH (*type) = (upper - lower + 1)
|
||||
* TYPE_LENGTH (TYPE_TARGET_TYPE (*type));
|
||||
|
||||
/* If the target type is not a stub, we could be clearing
|
||||
TYPE_FLAG_TARGET_STUB for *type. */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
badtype:
|
||||
{
|
||||
|
|
332
gdb/valops.c
332
gdb/valops.c
|
@ -55,6 +55,10 @@ static value_ptr cast_into_complex PARAMS ((struct type *, value_ptr));
|
|||
|
||||
#define VALUE_SUBSTRING_START(VAL) VALUE_FRAME(VAL)
|
||||
|
||||
/* Flag for whether we want to abandon failed expression evals by default. */
|
||||
|
||||
static int auto_abandon = 0;
|
||||
|
||||
|
||||
/* Find the address of function name NAME in the inferior. */
|
||||
|
||||
|
@ -129,49 +133,59 @@ value_cast (type, arg2)
|
|||
struct type *type;
|
||||
register value_ptr arg2;
|
||||
{
|
||||
register enum type_code code1 = TYPE_CODE (type);
|
||||
register enum type_code code1;
|
||||
register enum type_code code2;
|
||||
register int scalar;
|
||||
struct type *type2;
|
||||
|
||||
if (VALUE_TYPE (arg2) == type)
|
||||
return arg2;
|
||||
|
||||
CHECK_TYPEDEF (type);
|
||||
code1 = TYPE_CODE (type);
|
||||
COERCE_REF(arg2);
|
||||
type2 = check_typedef (VALUE_TYPE (arg2));
|
||||
|
||||
/* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
|
||||
is treated like a cast to (TYPE [N])OBJECT,
|
||||
where N is sizeof(OBJECT)/sizeof(TYPE). */
|
||||
if (code1 == TYPE_CODE_ARRAY
|
||||
&& TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0
|
||||
&& TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED)
|
||||
if (code1 == TYPE_CODE_ARRAY)
|
||||
{
|
||||
struct type *element_type = TYPE_TARGET_TYPE (type);
|
||||
struct type *range_type = TYPE_INDEX_TYPE (type);
|
||||
int low_bound = TYPE_LOW_BOUND (range_type);
|
||||
int val_length = TYPE_LENGTH (VALUE_TYPE (arg2));
|
||||
int new_length = val_length / TYPE_LENGTH (element_type);
|
||||
if (val_length % TYPE_LENGTH (element_type) != 0)
|
||||
warning("array element type size does not divide object size in cast");
|
||||
/* FIXME-type-allocation: need a way to free this type when we are
|
||||
done with it. */
|
||||
range_type = create_range_type ((struct type *) NULL,
|
||||
TYPE_TARGET_TYPE (range_type),
|
||||
low_bound, new_length + low_bound - 1);
|
||||
VALUE_TYPE (arg2) = create_array_type ((struct type *) NULL,
|
||||
element_type, range_type);
|
||||
return arg2;
|
||||
unsigned element_length = TYPE_LENGTH (check_typedef (element_type));
|
||||
if (element_length > 0
|
||||
&& TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED)
|
||||
{
|
||||
struct type *range_type = TYPE_INDEX_TYPE (type);
|
||||
int val_length = TYPE_LENGTH (type2);
|
||||
LONGEST low_bound, high_bound, new_length;
|
||||
if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
|
||||
low_bound = 0, high_bound = 0;
|
||||
new_length = val_length / element_length;
|
||||
if (val_length % element_length != 0)
|
||||
warning("array element type size does not divide object size in cast");
|
||||
/* FIXME-type-allocation: need a way to free this type when we are
|
||||
done with it. */
|
||||
range_type = create_range_type ((struct type *) NULL,
|
||||
TYPE_TARGET_TYPE (range_type),
|
||||
low_bound,
|
||||
new_length + low_bound - 1);
|
||||
VALUE_TYPE (arg2) = create_array_type ((struct type *) NULL,
|
||||
element_type, range_type);
|
||||
return arg2;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_language->c_style_arrays
|
||||
&& TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_ARRAY)
|
||||
&& TYPE_CODE (type2) == TYPE_CODE_ARRAY)
|
||||
arg2 = value_coerce_array (arg2);
|
||||
|
||||
if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FUNC)
|
||||
if (TYPE_CODE (type2) == TYPE_CODE_FUNC)
|
||||
arg2 = value_coerce_function (arg2);
|
||||
|
||||
COERCE_VARYING_ARRAY (arg2);
|
||||
|
||||
code2 = TYPE_CODE (VALUE_TYPE (arg2));
|
||||
type2 = check_typedef (VALUE_TYPE (arg2));
|
||||
COERCE_VARYING_ARRAY (arg2, type2);
|
||||
code2 = TYPE_CODE (type2);
|
||||
|
||||
if (code1 == TYPE_CODE_COMPLEX)
|
||||
return cast_into_complex (type, arg2);
|
||||
|
@ -191,7 +205,7 @@ value_cast (type, arg2)
|
|||
type of the target as a superclass. If so, we'll need to
|
||||
offset the object in addition to changing its type. */
|
||||
value_ptr v = search_struct_field (type_name_no_tag (type),
|
||||
arg2, 0, VALUE_TYPE (arg2), 1);
|
||||
arg2, 0, type2, 1);
|
||||
if (v)
|
||||
{
|
||||
VALUE_TYPE (v) = type;
|
||||
|
@ -204,15 +218,15 @@ value_cast (type, arg2)
|
|||
|| code1 == TYPE_CODE_RANGE)
|
||||
&& (scalar || code2 == TYPE_CODE_PTR))
|
||||
return value_from_longest (type, value_as_long (arg2));
|
||||
else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2)))
|
||||
else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
|
||||
{
|
||||
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
|
||||
{
|
||||
/* Look in the type of the source to see if it contains the
|
||||
type of the target as a superclass. If so, we'll need to
|
||||
offset the pointer rather than just change its type. */
|
||||
struct type *t1 = TYPE_TARGET_TYPE (type);
|
||||
struct type *t2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
|
||||
struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
|
||||
if ( TYPE_CODE (t1) == TYPE_CODE_STRUCT
|
||||
&& TYPE_CODE (t2) == TYPE_CODE_STRUCT
|
||||
&& TYPE_NAME (t1) != 0) /* if name unknown, can't have supercl */
|
||||
|
@ -236,19 +250,26 @@ value_cast (type, arg2)
|
|||
struct type *range1, *range2, *eltype1, *eltype2;
|
||||
value_ptr val;
|
||||
int count1, count2;
|
||||
LONGEST low_bound, high_bound;
|
||||
char *valaddr, *valaddr_data;
|
||||
if (code2 == TYPE_CODE_BITSTRING)
|
||||
error ("not implemented: converting bitstring to varying type");
|
||||
if ((code2 != TYPE_CODE_ARRAY && code2 != TYPE_CODE_STRING)
|
||||
|| (eltype1 = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1)),
|
||||
eltype2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)),
|
||||
|| (eltype1 = check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1))),
|
||||
eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)),
|
||||
(TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
|
||||
/* || TYPE_CODE (eltype1) != TYPE_CODE (eltype2) */ )))
|
||||
error ("Invalid conversion to varying type");
|
||||
range1 = TYPE_FIELD_TYPE (TYPE_FIELD_TYPE (type, 1), 0);
|
||||
range2 = TYPE_FIELD_TYPE (VALUE_TYPE (arg2), 0);
|
||||
count1 = TYPE_HIGH_BOUND (range1) - TYPE_LOW_BOUND (range1) + 1;
|
||||
count2 = TYPE_HIGH_BOUND (range2) - TYPE_LOW_BOUND (range2) + 1;
|
||||
range2 = TYPE_FIELD_TYPE (type2, 0);
|
||||
if (get_discrete_bounds (range1, &low_bound, &high_bound) < 0)
|
||||
count1 = -1;
|
||||
else
|
||||
count1 = high_bound - low_bound + 1;
|
||||
if (get_discrete_bounds (range2, &low_bound, &high_bound) < 0)
|
||||
count1 = -1, count2 = 0; /* To force error before */
|
||||
else
|
||||
count2 = high_bound - low_bound + 1;
|
||||
if (count2 > count1)
|
||||
error ("target varying type is too small");
|
||||
val = allocate_value (type);
|
||||
|
@ -289,7 +310,7 @@ value_zero (type, lv)
|
|||
{
|
||||
register value_ptr val = allocate_value (type);
|
||||
|
||||
memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (type));
|
||||
memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (check_typedef (type)));
|
||||
VALUE_LVAL (val) = lv;
|
||||
|
||||
return val;
|
||||
|
@ -311,7 +332,7 @@ value_at (type, addr)
|
|||
{
|
||||
register value_ptr val;
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_VOID)
|
||||
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
|
||||
error ("Attempt to dereference a generic pointer.");
|
||||
|
||||
val = allocate_value (type);
|
||||
|
@ -333,7 +354,7 @@ value_at_lazy (type, addr)
|
|||
{
|
||||
register value_ptr val;
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_VOID)
|
||||
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
|
||||
error ("Attempt to dereference a generic pointer.");
|
||||
|
||||
val = allocate_value (type);
|
||||
|
@ -362,10 +383,10 @@ value_fetch_lazy (val)
|
|||
register value_ptr val;
|
||||
{
|
||||
CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val);
|
||||
int length = TYPE_LENGTH (VALUE_TYPE (val));
|
||||
|
||||
if (TYPE_LENGTH (VALUE_TYPE (val)))
|
||||
read_memory (addr, VALUE_CONTENTS_RAW (val),
|
||||
TYPE_LENGTH (VALUE_TYPE (val)));
|
||||
if (length)
|
||||
read_memory (addr, VALUE_CONTENTS_RAW (val), length);
|
||||
VALUE_LAZY (val) = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -392,6 +413,7 @@ value_assign (toval, fromval)
|
|||
type = VALUE_TYPE (toval);
|
||||
if (VALUE_LVAL (toval) != lval_internalvar)
|
||||
fromval = value_cast (type, fromval);
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
/* If TOVAL is a special machine register requiring conversion
|
||||
of program values to a special raw format,
|
||||
|
@ -405,7 +427,8 @@ value_assign (toval, fromval)
|
|||
int regno = VALUE_REGNO (toval);
|
||||
if (REGISTER_CONVERTIBLE (regno))
|
||||
{
|
||||
REGISTER_CONVERT_TO_RAW (VALUE_TYPE (fromval), regno,
|
||||
struct type *fromtype = check_typedef (VALUE_TYPE (fromval));
|
||||
REGISTER_CONVERT_TO_RAW (fromtype, regno,
|
||||
VALUE_CONTENTS (fromval), raw_buffer);
|
||||
use_buffer = REGISTER_RAW_SIZE (regno);
|
||||
}
|
||||
|
@ -416,7 +439,7 @@ value_assign (toval, fromval)
|
|||
{
|
||||
case lval_internalvar:
|
||||
set_internalvar (VALUE_INTERNALVAR (toval), fromval);
|
||||
break;
|
||||
return VALUE_INTERNALVAR (toval)->value;
|
||||
|
||||
case lval_internalvar_component:
|
||||
set_internalvar_component (VALUE_INTERNALVAR (toval),
|
||||
|
@ -603,15 +626,6 @@ Can't handle bitfield which doesn't fit in a single register.");
|
|||
fromval = value_from_longest (type, fieldval);
|
||||
}
|
||||
|
||||
/* Return a value just like TOVAL except with the contents of FROMVAL
|
||||
(except in the case of the type if TOVAL is an internalvar). */
|
||||
|
||||
if (VALUE_LVAL (toval) == lval_internalvar
|
||||
|| VALUE_LVAL (toval) == lval_internalvar_component)
|
||||
{
|
||||
type = VALUE_TYPE (fromval);
|
||||
}
|
||||
|
||||
val = value_copy (toval);
|
||||
memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval),
|
||||
TYPE_LENGTH (type));
|
||||
|
@ -702,21 +716,12 @@ value_ptr
|
|||
value_coerce_array (arg1)
|
||||
value_ptr arg1;
|
||||
{
|
||||
register struct type *type;
|
||||
register struct type *type = check_typedef (VALUE_TYPE (arg1));
|
||||
|
||||
if (VALUE_LVAL (arg1) != lval_memory)
|
||||
error ("Attempt to take address of value not located in memory.");
|
||||
|
||||
/* Get type of elements. */
|
||||
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_ARRAY
|
||||
|| TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRING)
|
||||
type = TYPE_TARGET_TYPE (VALUE_TYPE (arg1));
|
||||
else
|
||||
/* A phony array made by value_repeat.
|
||||
Its type is the type of the elements, not an array type. */
|
||||
type = VALUE_TYPE (arg1);
|
||||
|
||||
return value_from_longest (lookup_pointer_type (type),
|
||||
return value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
|
||||
(LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
|
||||
}
|
||||
|
||||
|
@ -741,7 +746,7 @@ value_ptr
|
|||
value_addr (arg1)
|
||||
value_ptr arg1;
|
||||
{
|
||||
struct type *type = VALUE_TYPE (arg1);
|
||||
struct type *type = check_typedef (VALUE_TYPE (arg1));
|
||||
if (TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
{
|
||||
/* Copy the value, but change the type from (T&) to (T*).
|
||||
|
@ -757,7 +762,7 @@ value_addr (arg1)
|
|||
if (VALUE_LVAL (arg1) != lval_memory)
|
||||
error ("Attempt to take address of value not located in memory.");
|
||||
|
||||
return value_from_longest (lookup_pointer_type (type),
|
||||
return value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)),
|
||||
(LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1)));
|
||||
}
|
||||
|
||||
|
@ -767,21 +772,22 @@ value_ptr
|
|||
value_ind (arg1)
|
||||
value_ptr arg1;
|
||||
{
|
||||
struct type *type1;
|
||||
COERCE_ARRAY (arg1);
|
||||
type1 = check_typedef (VALUE_TYPE (arg1));
|
||||
|
||||
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MEMBER)
|
||||
if (TYPE_CODE (type1) == TYPE_CODE_MEMBER)
|
||||
error ("not implemented: member types in value_ind");
|
||||
|
||||
/* Allow * on an integer so we can cast it to whatever we want.
|
||||
This returns an int, which seems like the most C-like thing
|
||||
to do. "long long" variables are rare enough that
|
||||
BUILTIN_TYPE_LONGEST would seem to be a mistake. */
|
||||
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT)
|
||||
if (TYPE_CODE (type1) == TYPE_CODE_INT)
|
||||
return value_at (builtin_type_int,
|
||||
(CORE_ADDR) value_as_long (arg1));
|
||||
else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
|
||||
return value_at_lazy (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
|
||||
value_as_pointer (arg1));
|
||||
else if (TYPE_CODE (type1) == TYPE_CODE_PTR)
|
||||
return value_at_lazy (TYPE_TARGET_TYPE (type1), value_as_pointer (arg1));
|
||||
error ("Attempt to take contents of a non-pointer value.");
|
||||
return 0; /* For lint -- never reached */
|
||||
}
|
||||
|
@ -859,20 +865,14 @@ value_arg_coerce (arg, param_type)
|
|||
value_ptr arg;
|
||||
struct type *param_type;
|
||||
{
|
||||
register struct type *type;
|
||||
|
||||
#if 1 /* FIXME: This is only a temporary patch. -fnf */
|
||||
if (current_language->c_style_arrays
|
||||
&& TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY)
|
||||
arg = value_coerce_array (arg);
|
||||
#endif
|
||||
|
||||
type = param_type ? param_type : VALUE_TYPE (arg);
|
||||
register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
|
||||
register struct type *type
|
||||
= param_type ? check_typedef (param_type) : arg_type;
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_REF:
|
||||
if (TYPE_CODE (VALUE_TYPE (arg)) != TYPE_CODE_REF)
|
||||
if (TYPE_CODE (arg_type) != TYPE_CODE_REF)
|
||||
{
|
||||
arg = value_addr (arg);
|
||||
VALUE_TYPE (arg) = param_type;
|
||||
|
@ -893,9 +893,12 @@ value_arg_coerce (arg, param_type)
|
|||
case TYPE_CODE_FUNC:
|
||||
type = lookup_pointer_type (type);
|
||||
break;
|
||||
case TYPE_CODE_ARRAY:
|
||||
if (current_language->c_style_arrays)
|
||||
type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
|
||||
break;
|
||||
case TYPE_CODE_UNDEF:
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_ARRAY:
|
||||
case TYPE_CODE_STRUCT:
|
||||
case TYPE_CODE_UNION:
|
||||
case TYPE_CODE_VOID:
|
||||
|
@ -922,7 +925,7 @@ find_function_addr (function, retval_type)
|
|||
value_ptr function;
|
||||
struct type **retval_type;
|
||||
{
|
||||
register struct type *ftype = VALUE_TYPE (function);
|
||||
register struct type *ftype = check_typedef (VALUE_TYPE (function));
|
||||
register enum type_code code = TYPE_CODE (ftype);
|
||||
struct type *value_type;
|
||||
CORE_ADDR funaddr;
|
||||
|
@ -939,8 +942,9 @@ find_function_addr (function, retval_type)
|
|||
else if (code == TYPE_CODE_PTR)
|
||||
{
|
||||
funaddr = value_as_pointer (function);
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_FUNC
|
||||
|| TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_METHOD)
|
||||
ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
|
||||
if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
|
||||
|| TYPE_CODE (ftype) == TYPE_CODE_METHOD)
|
||||
{
|
||||
#ifdef CONVERT_FROM_FUNC_PTR_ADDR
|
||||
/* FIXME: This is a workaround for the unusual function
|
||||
|
@ -948,7 +952,7 @@ find_function_addr (function, retval_type)
|
|||
in config/rs6000/tm-rs6000.h */
|
||||
funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
|
||||
#endif
|
||||
value_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype));
|
||||
value_type = TYPE_TARGET_TYPE (ftype);
|
||||
}
|
||||
else
|
||||
value_type = builtin_type_int;
|
||||
|
@ -1015,7 +1019,7 @@ call_function_by_hand (function, nargs, args)
|
|||
CORE_ADDR funaddr;
|
||||
int using_gcc;
|
||||
CORE_ADDR real_pc;
|
||||
struct type *ftype = SYMBOL_TYPE (function);
|
||||
struct type *ftype = check_typedef (SYMBOL_TYPE (function));
|
||||
|
||||
if (!target_has_execution)
|
||||
noprocess();
|
||||
|
@ -1039,6 +1043,7 @@ call_function_by_hand (function, nargs, args)
|
|||
#endif
|
||||
|
||||
funaddr = find_function_addr (function, &value_type);
|
||||
CHECK_TYPEDEF (value_type);
|
||||
|
||||
{
|
||||
struct block *b = block_for_pc (funaddr);
|
||||
|
@ -1127,40 +1132,43 @@ call_function_by_hand (function, nargs, args)
|
|||
/* This is a machine like the sparc, where we may need to pass a pointer
|
||||
to the structure, not the structure itself. */
|
||||
for (i = nargs - 1; i >= 0; i--)
|
||||
if ((TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_UNION
|
||||
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_ARRAY
|
||||
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRING)
|
||||
&& REG_STRUCT_HAS_ADDR (using_gcc, VALUE_TYPE (args[i])))
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
int len = TYPE_LENGTH (VALUE_TYPE (args[i]));
|
||||
{
|
||||
struct type *arg_type = check_typedef (VALUE_TYPE (args[i]));
|
||||
if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (arg_type) == TYPE_CODE_UNION
|
||||
|| TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
|
||||
|| TYPE_CODE (arg_type) == TYPE_CODE_STRING)
|
||||
&& REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
int len = TYPE_LENGTH (arg_type);
|
||||
#ifdef STACK_ALIGN
|
||||
int aligned_len = STACK_ALIGN (len);
|
||||
int aligned_len = STACK_ALIGN (len);
|
||||
#else
|
||||
int aligned_len = len;
|
||||
int aligned_len = len;
|
||||
#endif
|
||||
#if !(1 INNER_THAN 2)
|
||||
/* The stack grows up, so the address of the thing we push
|
||||
is the stack pointer before we push it. */
|
||||
addr = sp;
|
||||
/* The stack grows up, so the address of the thing we push
|
||||
is the stack pointer before we push it. */
|
||||
addr = sp;
|
||||
#else
|
||||
sp -= aligned_len;
|
||||
sp -= aligned_len;
|
||||
#endif
|
||||
/* Push the structure. */
|
||||
write_memory (sp, VALUE_CONTENTS (args[i]), len);
|
||||
/* Push the structure. */
|
||||
write_memory (sp, VALUE_CONTENTS (args[i]), len);
|
||||
#if 1 INNER_THAN 2
|
||||
/* The stack grows down, so the address of the thing we push
|
||||
is the stack pointer after we push it. */
|
||||
addr = sp;
|
||||
/* The stack grows down, so the address of the thing we push
|
||||
is the stack pointer after we push it. */
|
||||
addr = sp;
|
||||
#else
|
||||
sp += aligned_len;
|
||||
sp += aligned_len;
|
||||
#endif
|
||||
/* The value we're going to pass is the address of the thing
|
||||
we just pushed. */
|
||||
args[i] = value_from_longest (lookup_pointer_type (value_type),
|
||||
(LONGEST) addr);
|
||||
}
|
||||
/* The value we're going to pass is the address of the thing
|
||||
we just pushed. */
|
||||
args[i] = value_from_longest (lookup_pointer_type (value_type),
|
||||
(LONGEST) addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* REG_STRUCT_HAS_ADDR. */
|
||||
|
||||
|
@ -1345,7 +1353,7 @@ value_array (lowbound, highbound, elemvec)
|
|||
error ("bad array bounds (%d, %d)", lowbound, highbound);
|
||||
}
|
||||
typelength = TYPE_LENGTH (VALUE_TYPE (elemvec[0]));
|
||||
for (idx = 0; idx < nelem; idx++)
|
||||
for (idx = 1; idx < nelem; idx++)
|
||||
{
|
||||
if (TYPE_LENGTH (VALUE_TYPE (elemvec[idx])) != typelength)
|
||||
{
|
||||
|
@ -1466,11 +1474,11 @@ typecmp (staticp, t1, t2)
|
|||
struct type *tt1, *tt2;
|
||||
if (! t2[i])
|
||||
return i+1;
|
||||
tt1 = t1[i];
|
||||
tt2 = VALUE_TYPE(t2[i]);
|
||||
tt1 = check_typedef (t1[i]);
|
||||
tt2 = check_typedef (VALUE_TYPE(t2[i]));
|
||||
if (TYPE_CODE (tt1) == TYPE_CODE_REF
|
||||
/* We should be doing hairy argument matching, as below. */
|
||||
&& (TYPE_CODE (TYPE_TARGET_TYPE (tt1)) == TYPE_CODE (tt2)))
|
||||
&& (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1))) == TYPE_CODE (tt2)))
|
||||
{
|
||||
if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
|
||||
t2[i] = value_coerce_array (t2[i]);
|
||||
|
@ -1480,10 +1488,11 @@ typecmp (staticp, t1, t2)
|
|||
}
|
||||
|
||||
while (TYPE_CODE (tt1) == TYPE_CODE_PTR
|
||||
&& (TYPE_CODE(tt2)==TYPE_CODE_ARRAY || TYPE_CODE(tt2)==TYPE_CODE_PTR))
|
||||
&& ( TYPE_CODE (tt2) == TYPE_CODE_ARRAY
|
||||
|| TYPE_CODE (tt2) == TYPE_CODE_PTR))
|
||||
{
|
||||
tt1 = TYPE_TARGET_TYPE(tt1);
|
||||
tt2 = TYPE_TARGET_TYPE(tt2);
|
||||
tt1 = check_typedef (TYPE_TARGET_TYPE(tt1));
|
||||
tt2 = check_typedef (TYPE_TARGET_TYPE(tt2));
|
||||
}
|
||||
if (TYPE_CODE(tt1) == TYPE_CODE(tt2)) continue;
|
||||
/* Array to pointer is a `trivial conversion' according to the ARM. */
|
||||
|
@ -1516,7 +1525,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||
{
|
||||
int i;
|
||||
|
||||
check_stub_type (type);
|
||||
CHECK_TYPEDEF (type);
|
||||
|
||||
if (! looking_for_baseclass)
|
||||
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
|
||||
|
@ -1586,6 +1595,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||
for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
|
||||
{
|
||||
value_ptr v;
|
||||
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
|
||||
/* If we are looking for baseclasses, this is what we get when we
|
||||
hit them. But it could happen that the base part's member name
|
||||
is not yet filled in. */
|
||||
|
@ -1595,15 +1605,28 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||
|
||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||
{
|
||||
value_ptr v2;
|
||||
/* Fix to use baseclass_offset instead. FIXME */
|
||||
baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset,
|
||||
&v2, (int *)NULL);
|
||||
if (v2 == 0)
|
||||
int boffset = VALUE_OFFSET (arg1) + offset;
|
||||
boffset = baseclass_offset (type, i,
|
||||
VALUE_CONTENTS (arg1) + boffset,
|
||||
VALUE_ADDRESS (arg1) + boffset);
|
||||
if (boffset == -1)
|
||||
error ("virtual baseclass botch");
|
||||
if (found_baseclass)
|
||||
return v2;
|
||||
v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
|
||||
{
|
||||
value_ptr v2 = allocate_value (basetype);
|
||||
VALUE_LVAL (v2) = VALUE_LVAL (arg1);
|
||||
VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
|
||||
VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + offset + boffset;
|
||||
if (VALUE_LAZY (arg1))
|
||||
VALUE_LAZY (v2) = 1;
|
||||
else
|
||||
memcpy (VALUE_CONTENTS_RAW (v2),
|
||||
VALUE_CONTENTS_RAW (arg1) + offset + boffset,
|
||||
TYPE_LENGTH (basetype));
|
||||
return v2;
|
||||
}
|
||||
v = search_struct_field (name, arg1, offset + boffset,
|
||||
TYPE_BASECLASS (type, i),
|
||||
looking_for_baseclass);
|
||||
}
|
||||
else if (found_baseclass)
|
||||
|
@ -1611,8 +1634,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass)
|
|||
else
|
||||
v = search_struct_field (name, arg1,
|
||||
offset + TYPE_BASECLASS_BITPOS (type, i) / 8,
|
||||
TYPE_BASECLASS (type, i),
|
||||
looking_for_baseclass);
|
||||
basetype, looking_for_baseclass);
|
||||
if (v) return v;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1636,7 +1658,7 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
|
|||
int name_matched = 0;
|
||||
char dem_opname[64];
|
||||
|
||||
check_stub_type (type);
|
||||
CHECK_TYPEDEF (type);
|
||||
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
|
||||
{
|
||||
char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
|
||||
|
@ -1682,7 +1704,11 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type)
|
|||
|
||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||
{
|
||||
base_offset = baseclass_offset (type, i, *arg1p, offset);
|
||||
base_offset = VALUE_OFFSET (*arg1p) + offset;
|
||||
base_offset =
|
||||
baseclass_offset (type, i,
|
||||
VALUE_CONTENTS (*arg1p) + base_offset,
|
||||
VALUE_ADDRESS (*arg1p) + base_offset);
|
||||
if (base_offset == -1)
|
||||
error ("virtual baseclass botch");
|
||||
}
|
||||
|
@ -1733,7 +1759,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
|
|||
|
||||
COERCE_ARRAY (*argp);
|
||||
|
||||
t = VALUE_TYPE (*argp);
|
||||
t = check_typedef (VALUE_TYPE (*argp));
|
||||
|
||||
/* Follow pointers until we get to a non-pointer. */
|
||||
|
||||
|
@ -1743,7 +1769,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
|
|||
/* Don't coerce fn pointer to fn and then back again! */
|
||||
if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC)
|
||||
COERCE_ARRAY (*argp);
|
||||
t = VALUE_TYPE (*argp);
|
||||
t = check_typedef (VALUE_TYPE (*argp));
|
||||
}
|
||||
|
||||
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
|
||||
|
@ -1907,8 +1933,13 @@ check_field (arg1, name)
|
|||
|
||||
/* Follow pointers until we get to a non-pointer. */
|
||||
|
||||
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
|
||||
t = TYPE_TARGET_TYPE (t);
|
||||
for (;;)
|
||||
{
|
||||
CHECK_TYPEDEF (t);
|
||||
if (TYPE_CODE (t) != TYPE_CODE_PTR && TYPE_CODE (t) != TYPE_CODE_REF)
|
||||
break;
|
||||
t = TYPE_TARGET_TYPE (t);
|
||||
}
|
||||
|
||||
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
|
||||
error ("not implemented: member type in check_field");
|
||||
|
@ -2124,21 +2155,26 @@ value_slice (array, lowbound, length)
|
|||
value_ptr array;
|
||||
int lowbound, length;
|
||||
{
|
||||
COERCE_VARYING_ARRAY (array);
|
||||
if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_BITSTRING)
|
||||
struct type *array_type;
|
||||
array_type = check_typedef (VALUE_TYPE (array));
|
||||
COERCE_VARYING_ARRAY (array, array_type);
|
||||
if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
|
||||
error ("not implemented - bitstring slice");
|
||||
if (TYPE_CODE (VALUE_TYPE (array)) != TYPE_CODE_ARRAY
|
||||
&& TYPE_CODE (VALUE_TYPE (array)) != TYPE_CODE_STRING)
|
||||
if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY
|
||||
&& TYPE_CODE (array_type) != TYPE_CODE_STRING)
|
||||
error ("cannot take slice of non-array");
|
||||
else
|
||||
{
|
||||
struct type *slice_range_type, *slice_type;
|
||||
value_ptr slice;
|
||||
struct type *range_type = TYPE_FIELD_TYPE (VALUE_TYPE (array), 0);
|
||||
struct type *element_type = TYPE_TARGET_TYPE (VALUE_TYPE (array));
|
||||
int lowerbound = TYPE_LOW_BOUND (range_type);
|
||||
int upperbound = TYPE_HIGH_BOUND (range_type);
|
||||
int offset = (lowbound - lowerbound) * TYPE_LENGTH (element_type);
|
||||
struct type *range_type = TYPE_FIELD_TYPE (array_type,0);
|
||||
struct type *element_type = TYPE_TARGET_TYPE (array_type);
|
||||
LONGEST lowerbound, upperbound, offset;
|
||||
|
||||
if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
|
||||
error ("slice from bad array");
|
||||
offset
|
||||
= (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
|
||||
if (lowbound < lowerbound || length < 0
|
||||
|| lowbound + length - 1 > upperbound)
|
||||
error ("slice out of range");
|
||||
|
@ -2150,7 +2186,7 @@ value_slice (array, lowbound, length)
|
|||
lowerbound + length - 1);
|
||||
slice_type = create_array_type ((struct type*) NULL, element_type,
|
||||
slice_range_type);
|
||||
TYPE_CODE (slice_type) = TYPE_CODE (VALUE_TYPE (array));
|
||||
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
|
||||
slice = allocate_value (slice_type);
|
||||
if (VALUE_LAZY (array))
|
||||
VALUE_LAZY (slice) = 1;
|
||||
|
@ -2174,7 +2210,7 @@ value_ptr
|
|||
varying_to_slice (varray)
|
||||
value_ptr varray;
|
||||
{
|
||||
struct type *vtype = VALUE_TYPE (varray);
|
||||
struct type *vtype = check_typedef (VALUE_TYPE (varray));
|
||||
LONGEST length = unpack_long (TYPE_FIELD_TYPE (vtype, 0),
|
||||
VALUE_CONTENTS (varray)
|
||||
+ TYPE_FIELD_BITPOS (vtype, 0) / 8);
|
||||
|
@ -2235,3 +2271,15 @@ cast_into_complex (type, val)
|
|||
else
|
||||
error ("cannot cast non-number to complex");
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_valops ()
|
||||
{
|
||||
#if 0
|
||||
add_show_from_set
|
||||
(add_set_cmd ("abandon", class_support, var_boolean, (char *)&auto_abandon,
|
||||
"Set automatic abandonment of expressions upon failure.",
|
||||
&setlist),
|
||||
&showlist);
|
||||
#endif
|
||||
}
|
||||
|
|
164
gdb/values.c
164
gdb/values.c
|
@ -73,10 +73,9 @@ allocate_value (type)
|
|||
struct type *type;
|
||||
{
|
||||
register value_ptr val;
|
||||
struct type *atype = check_typedef (type);
|
||||
|
||||
check_stub_type (type);
|
||||
|
||||
val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (type));
|
||||
val = (struct value *) xmalloc (sizeof (struct value) + TYPE_LENGTH (atype));
|
||||
VALUE_NEXT (val) = all_values;
|
||||
all_values = val;
|
||||
VALUE_TYPE (val) = type;
|
||||
|
@ -621,6 +620,8 @@ unpack_long (type, valaddr)
|
|||
|
||||
switch (code)
|
||||
{
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
return unpack_long (check_typedef (type), valaddr);
|
||||
case TYPE_CODE_ENUM:
|
||||
case TYPE_CODE_BOOL:
|
||||
case TYPE_CODE_INT:
|
||||
|
@ -666,6 +667,7 @@ unpack_double (type, valaddr, invp)
|
|||
register int nosign = TYPE_UNSIGNED (type);
|
||||
|
||||
*invp = 0; /* Assume valid. */
|
||||
CHECK_TYPEDEF (type);
|
||||
if (code == TYPE_CODE_FLT)
|
||||
{
|
||||
#ifdef INVALID_FLOAT
|
||||
|
@ -729,7 +731,7 @@ value_primitive_field (arg1, offset, fieldno, arg_type)
|
|||
register value_ptr v;
|
||||
register struct type *type;
|
||||
|
||||
check_stub_type (arg_type);
|
||||
CHECK_TYPEDEF (arg_type);
|
||||
type = TYPE_FIELD_TYPE (arg_type, fieldno);
|
||||
|
||||
/* Handle packed fields */
|
||||
|
@ -835,6 +837,8 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
|
|||
int offset;
|
||||
{
|
||||
value_ptr arg1 = *arg1p;
|
||||
struct type *type1 = check_typedef (VALUE_TYPE (arg1));
|
||||
struct type *entry_type;
|
||||
/* First, get the virtual function table pointer. That comes
|
||||
with a strange type, so cast it to type `pointer to long' (which
|
||||
should serve just fine as a function type). Then, index into
|
||||
|
@ -852,10 +856,13 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
|
|||
fcontext = TYPE_VPTR_BASETYPE (type);
|
||||
context = lookup_pointer_type (fcontext);
|
||||
/* Now context is a pointer to the basetype containing the vtbl. */
|
||||
if (TYPE_TARGET_TYPE (context) != VALUE_TYPE (arg1))
|
||||
arg1 = value_ind (value_cast (context, value_addr (arg1)));
|
||||
if (TYPE_TARGET_TYPE (context) != type1)
|
||||
{
|
||||
arg1 = value_ind (value_cast (context, value_addr (arg1)));
|
||||
type1 = check_typedef (VALUE_TYPE (arg1));
|
||||
}
|
||||
|
||||
context = VALUE_TYPE (arg1);
|
||||
context = type1;
|
||||
/* Now context is the basetype containing the vtbl. */
|
||||
|
||||
/* This type may have been defined before its virtual function table
|
||||
|
@ -875,8 +882,9 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
|
|||
time, e.g. if the user has set a conditional breakpoint calling
|
||||
a virtual function. */
|
||||
entry = value_subscript (vtbl, vi);
|
||||
entry_type = check_typedef (VALUE_TYPE (entry));
|
||||
|
||||
if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_STRUCT)
|
||||
if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
|
||||
{
|
||||
/* Move the `this' pointer according to the virtual function table. */
|
||||
VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
|
||||
|
@ -889,7 +897,7 @@ value_virtual_fn_field (arg1p, f, j, type, offset)
|
|||
|
||||
vfn = value_field (entry, 2);
|
||||
}
|
||||
else if (TYPE_CODE (VALUE_TYPE (entry)) == TYPE_CODE_PTR)
|
||||
else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
|
||||
vfn = entry;
|
||||
else
|
||||
error ("I'm confused: virtual function table has bad type");
|
||||
|
@ -925,7 +933,7 @@ value_headof (in_arg, btype, dtype)
|
|||
struct minimal_symbol *msymbol;
|
||||
|
||||
btype = TYPE_VPTR_BASETYPE (dtype);
|
||||
check_stub_type (btype);
|
||||
CHECK_TYPEDEF (btype);
|
||||
arg = in_arg;
|
||||
if (btype != dtype)
|
||||
arg = value_cast (lookup_pointer_type (btype), arg);
|
||||
|
@ -955,7 +963,7 @@ value_headof (in_arg, btype, dtype)
|
|||
entry = value_subscript (vtbl, value_from_longest (builtin_type_int,
|
||||
(LONGEST) i));
|
||||
/* This won't work if we're using thunks. */
|
||||
if (TYPE_CODE (VALUE_TYPE (entry)) != TYPE_CODE_STRUCT)
|
||||
if (TYPE_CODE (check_typedef (VALUE_TYPE (entry))) != TYPE_CODE_STRUCT)
|
||||
break;
|
||||
offset = longest_to_int (value_as_long (value_field (entry, 0)));
|
||||
/* If we use '<=' we can handle single inheritance
|
||||
|
@ -1066,19 +1074,19 @@ vb_match (type, index, basetype)
|
|||
}
|
||||
|
||||
/* Compute the offset of the baseclass which is
|
||||
the INDEXth baseclass of class TYPE, for a value ARG,
|
||||
wih extra offset of OFFSET.
|
||||
The result is the offste of the baseclass value relative
|
||||
the INDEXth baseclass of class TYPE,
|
||||
for value at VALADDR (in host) at ADDRESS (in target).
|
||||
The result is the offset of the baseclass value relative
|
||||
to (the address of)(ARG) + OFFSET.
|
||||
|
||||
-1 is returned on error. */
|
||||
|
||||
int
|
||||
baseclass_offset (type, index, arg, offset)
|
||||
baseclass_offset (type, index, valaddr, address)
|
||||
struct type *type;
|
||||
int index;
|
||||
value_ptr arg;
|
||||
int offset;
|
||||
char *valaddr;
|
||||
CORE_ADDR address;
|
||||
{
|
||||
struct type *basetype = TYPE_BASECLASS (type, index);
|
||||
|
||||
|
@ -1096,22 +1104,16 @@ baseclass_offset (type, index, arg, offset)
|
|||
{
|
||||
CORE_ADDR addr
|
||||
= unpack_pointer (TYPE_FIELD_TYPE (type, i),
|
||||
VALUE_CONTENTS (arg) + VALUE_OFFSET (arg)
|
||||
+ offset
|
||||
+ (TYPE_FIELD_BITPOS (type, i) / 8));
|
||||
valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
|
||||
|
||||
if (VALUE_LVAL (arg) != lval_memory)
|
||||
return -1;
|
||||
|
||||
return addr -
|
||||
(LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset);
|
||||
return addr - (LONGEST) address;
|
||||
}
|
||||
}
|
||||
/* Not in the fields, so try looking through the baseclasses. */
|
||||
for (i = index+1; i < n_baseclasses; i++)
|
||||
{
|
||||
int boffset =
|
||||
baseclass_offset (type, i, arg, offset);
|
||||
baseclass_offset (type, i, valaddr, address);
|
||||
if (boffset)
|
||||
return boffset;
|
||||
}
|
||||
|
@ -1122,95 +1124,6 @@ baseclass_offset (type, index, arg, offset)
|
|||
/* Baseclass is easily computed. */
|
||||
return TYPE_BASECLASS_BITPOS (type, index) / 8;
|
||||
}
|
||||
|
||||
/* Compute the address of the baseclass which is
|
||||
the INDEXth baseclass of class TYPE. The TYPE base
|
||||
of the object is at VALADDR.
|
||||
|
||||
If ERRP is non-NULL, set *ERRP to be the errno code of any error,
|
||||
or 0 if no error. In that case the return value is not the address
|
||||
of the baseclasss, but the address which could not be read
|
||||
successfully. */
|
||||
|
||||
/* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */
|
||||
|
||||
char *
|
||||
baseclass_addr (type, index, valaddr, valuep, errp)
|
||||
struct type *type;
|
||||
int index;
|
||||
char *valaddr;
|
||||
value_ptr *valuep;
|
||||
int *errp;
|
||||
{
|
||||
struct type *basetype = TYPE_BASECLASS (type, index);
|
||||
|
||||
if (errp)
|
||||
*errp = 0;
|
||||
|
||||
if (BASETYPE_VIA_VIRTUAL (type, index))
|
||||
{
|
||||
/* Must hunt for the pointer to this virtual baseclass. */
|
||||
register int i, len = TYPE_NFIELDS (type);
|
||||
register int n_baseclasses = TYPE_N_BASECLASSES (type);
|
||||
|
||||
/* First look for the virtual baseclass pointer
|
||||
in the fields. */
|
||||
for (i = n_baseclasses; i < len; i++)
|
||||
{
|
||||
if (vb_match (type, i, basetype))
|
||||
{
|
||||
value_ptr val = allocate_value (basetype);
|
||||
CORE_ADDR addr;
|
||||
int status;
|
||||
|
||||
addr
|
||||
= unpack_pointer (TYPE_FIELD_TYPE (type, i),
|
||||
valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
|
||||
|
||||
status = target_read_memory (addr,
|
||||
VALUE_CONTENTS_RAW (val),
|
||||
TYPE_LENGTH (basetype));
|
||||
VALUE_LVAL (val) = lval_memory;
|
||||
VALUE_ADDRESS (val) = addr;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
if (valuep)
|
||||
*valuep = NULL;
|
||||
release_value (val);
|
||||
value_free (val);
|
||||
if (errp)
|
||||
*errp = status;
|
||||
return (char *)addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (valuep)
|
||||
*valuep = val;
|
||||
return (char *) VALUE_CONTENTS (val);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Not in the fields, so try looking through the baseclasses. */
|
||||
for (i = index+1; i < n_baseclasses; i++)
|
||||
{
|
||||
char *baddr;
|
||||
|
||||
baddr = baseclass_addr (type, i, valaddr, valuep, errp);
|
||||
if (baddr)
|
||||
return baddr;
|
||||
}
|
||||
/* Not found. */
|
||||
if (valuep)
|
||||
*valuep = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Baseclass is easily computed. */
|
||||
if (valuep)
|
||||
*valuep = 0;
|
||||
return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8;
|
||||
}
|
||||
|
||||
/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at
|
||||
VALADDR.
|
||||
|
@ -1321,11 +1234,17 @@ value_from_longest (type, num)
|
|||
register LONGEST num;
|
||||
{
|
||||
register value_ptr val = allocate_value (type);
|
||||
register enum type_code code = TYPE_CODE (type);
|
||||
register int len = TYPE_LENGTH (type);
|
||||
register enum type_code code;
|
||||
register int len;
|
||||
retry:
|
||||
code = TYPE_CODE (type);
|
||||
len = TYPE_LENGTH (type);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
type = check_typedef (type);
|
||||
goto retry;
|
||||
case TYPE_CODE_INT:
|
||||
case TYPE_CODE_CHAR:
|
||||
case TYPE_CODE_ENUM:
|
||||
|
@ -1353,8 +1272,9 @@ value_from_double (type, num)
|
|||
double num;
|
||||
{
|
||||
register value_ptr val = allocate_value (type);
|
||||
register enum type_code code = TYPE_CODE (type);
|
||||
register int len = TYPE_LENGTH (type);
|
||||
struct type *base_type = check_typedef (type);
|
||||
register enum type_code code = TYPE_CODE (base_type);
|
||||
register int len = TYPE_LENGTH (base_type);
|
||||
|
||||
if (code == TYPE_CODE_FLT)
|
||||
{
|
||||
|
@ -1401,6 +1321,7 @@ value_being_returned (valtype, retbuf, struct_return)
|
|||
#endif
|
||||
|
||||
val = allocate_value (valtype);
|
||||
CHECK_TYPEDEF (valtype);
|
||||
EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));
|
||||
|
||||
return val;
|
||||
|
@ -1466,7 +1387,8 @@ void
|
|||
set_return_value (val)
|
||||
value_ptr val;
|
||||
{
|
||||
register enum type_code code = TYPE_CODE (VALUE_TYPE (val));
|
||||
struct type *type = check_typedef (VALUE_TYPE (val));
|
||||
register enum type_code code = TYPE_CODE (type);
|
||||
|
||||
if (code == TYPE_CODE_ERROR)
|
||||
error ("Function return type unknown.");
|
||||
|
@ -1475,7 +1397,7 @@ set_return_value (val)
|
|||
|| code == TYPE_CODE_UNION) /* FIXME, implement struct return. */
|
||||
error ("GDB does not support specifying a struct or union return value.");
|
||||
|
||||
STORE_RETURN_VALUE (VALUE_TYPE (val), VALUE_CONTENTS (val));
|
||||
STORE_RETURN_VALUE (type, VALUE_CONTENTS (val));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Reference in a new issue