2010-12-31 Michael Snyder <msnyder@vmware.com>

* charset.c: Comment cleanup and long line wrapping.
	* charset.h: Ditto.
	* c-lang.c: Ditto.
	* c-lang.h: Ditto.
	* coff-pe-read.c: Ditto.
	* coff-pe-read.h: Ditto.
	* coffread.c: Ditto.
	* command.h: Ditto.
	* complaints.c: Ditto.
	* complaints.h: Ditto.
	* completer.c: Ditto.
	* completer.h: Ditto.
	* corefile.c: Ditto.
	* corelow.c: Ditto.
	* core-regset.c: Ditto.
	* cp-abi.c: Ditto.
	* cp-abi.h: Ditto.
	* cp-namespace.c: Ditto.
	* cp-support.c: Ditto.
	* cp-support.h: Ditto.
	* cp-valprint.c: Ditto.
	* cp-typeprint.c: Ditto.
	* c-valprint.c: Ditto.
This commit is contained in:
Michael Snyder 2010-12-31 22:59:52 +00:00
parent db09a73fa4
commit aff410f180
24 changed files with 1489 additions and 1076 deletions

View file

@ -11,6 +11,30 @@
* breakpoint.h: Ditto. * breakpoint.h: Ditto.
* buildsym.h: Ditto. * buildsym.h: Ditto.
* charset.c: Ditto.
* charset.h: Ditto.
* c-lang.c: Ditto.
* c-lang.h: Ditto.
* coff-pe-read.c: Ditto.
* coff-pe-read.h: Ditto.
* coffread.c: Ditto.
* command.h: Ditto.
* complaints.c: Ditto.
* complaints.h: Ditto.
* completer.c: Ditto.
* completer.h: Ditto.
* corefile.c: Ditto.
* corelow.c: Ditto.
* core-regset.c: Ditto.
* cp-abi.c: Ditto.
* cp-abi.h: Ditto.
* cp-namespace.c: Ditto.
* cp-support.c: Ditto.
* cp-support.h: Ditto.
* cp-valprint.c: Ditto.
* cp-typeprint.c: Ditto.
* c-valprint.c: Ditto.
2010-12-30 Mike Frysinger <vapier@gentoo.org> 2010-12-30 Mike Frysinger <vapier@gentoo.org>
* bfin-tdep.c (bfin_register_type): Move || to start of line. * bfin-tdep.c (bfin_register_type): Move || to start of line.

View file

@ -71,7 +71,8 @@ charset_for_string_type (enum c_string_type str_type,
/* Classify ELTTYPE according to what kind of character it is. Return /* Classify ELTTYPE according to what kind of character it is. Return
the enum constant representing the character type. Also set the enum constant representing the character type. Also set
*ENCODING to the name of the character set to use when converting *ENCODING to the name of the character set to use when converting
characters of this type in target BYTE_ORDER to the host character set. */ characters of this type in target BYTE_ORDER to the host character
set. */
static enum c_string_type static enum c_string_type
classify_type (struct type *elttype, struct gdbarch *gdbarch, classify_type (struct type *elttype, struct gdbarch *gdbarch,
@ -156,7 +157,8 @@ wchar_printable (gdb_wchar_t w)
characters and then appends them to OUTPUT. */ characters and then appends them to OUTPUT. */
static void static void
append_string_as_wide (const char *string, struct obstack *output) append_string_as_wide (const char *string,
struct obstack *output)
{ {
for (; *string; ++string) for (; *string; ++string)
{ {
@ -175,8 +177,10 @@ append_string_as_wide (const char *string, struct obstack *output)
escapes across calls. */ escapes across calls. */
static void static void
print_wchar (gdb_wint_t w, const gdb_byte *orig, int orig_len, print_wchar (gdb_wint_t w, const gdb_byte *orig,
int width, enum bfd_endian byte_order, struct obstack *output, int orig_len, int width,
enum bfd_endian byte_order,
struct obstack *output,
int quoter, int *need_escapep) int quoter, int *need_escapep)
{ {
int need_escape = *need_escapep; int need_escape = *need_escapep;
@ -226,7 +230,8 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig, int orig_len,
char octal[30]; char octal[30];
ULONGEST value; ULONGEST value;
value = extract_unsigned_integer (&orig[i], width, byte_order); value = extract_unsigned_integer (&orig[i], width,
byte_order);
/* If the value fits in 3 octal digits, print it that /* If the value fits in 3 octal digits, print it that
way. Otherwise, print it as a hex escape. */ way. Otherwise, print it as a hex escape. */
if (value <= 0777) if (value <= 0777)
@ -252,15 +257,16 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig, int orig_len,
} }
} }
/* Print the character C on STREAM as part of the contents of a literal /* Print the character C on STREAM as part of the contents of a
string whose delimiter is QUOTER. Note that that format for printing literal string whose delimiter is QUOTER. Note that that format
characters and strings is language specific. */ for printing characters and strings is language specific. */
void void
c_emit_char (int c, struct type *type, c_emit_char (int c, struct type *type,
struct ui_file *stream, int quoter) struct ui_file *stream, int quoter)
{ {
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); enum bfd_endian byte_order
= gdbarch_byte_order (get_type_arch (type));
struct obstack wchar_buf, output; struct obstack wchar_buf, output;
struct cleanup *cleanups; struct cleanup *cleanups;
const char *encoding; const char *encoding;
@ -273,8 +279,8 @@ c_emit_char (int c, struct type *type,
buf = alloca (TYPE_LENGTH (type)); buf = alloca (TYPE_LENGTH (type));
pack_long (buf, type, c); pack_long (buf, type, c);
iter = make_wchar_iterator (buf, TYPE_LENGTH (type), encoding, iter = make_wchar_iterator (buf, TYPE_LENGTH (type),
TYPE_LENGTH (type)); encoding, TYPE_LENGTH (type));
cleanups = make_cleanup_wchar_iterator (iter); cleanups = make_cleanup_wchar_iterator (iter);
/* This holds the printable form of the wchar_t data. */ /* This holds the printable form of the wchar_t data. */
@ -313,15 +319,16 @@ c_emit_char (int c, struct type *type,
if (!print_escape) if (!print_escape)
{ {
for (i = 0; i < num_chars; ++i) for (i = 0; i < num_chars; ++i)
print_wchar (chars[i], buf, buflen, TYPE_LENGTH (type), print_wchar (chars[i], buf, buflen,
byte_order, &wchar_buf, quoter, &need_escape); TYPE_LENGTH (type), byte_order,
&wchar_buf, quoter, &need_escape);
} }
} }
/* This handles the NUM_CHARS == 0 case as well. */ /* This handles the NUM_CHARS == 0 case as well. */
if (print_escape) if (print_escape)
print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type), byte_order, print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type),
&wchar_buf, quoter, &need_escape); byte_order, &wchar_buf, quoter, &need_escape);
} }
/* The output in the host encoding. */ /* The output in the host encoding. */
@ -365,15 +372,17 @@ c_printchar (int c, struct type *type, struct ui_file *stream)
fputc_filtered ('\'', stream); fputc_filtered ('\'', stream);
} }
/* Print the character string STRING, printing at most LENGTH characters. /* Print the character string STRING, printing at most LENGTH
LENGTH is -1 if the string is nul terminated. Each character is WIDTH bytes characters. LENGTH is -1 if the string is nul terminated. Each
long. Printing stops early if the number hits print_max; repeat counts are character is WIDTH bytes long. Printing stops early if the number
printed as appropriate. Print ellipses at the end if we had to stop before hits print_max; repeat counts are printed as appropriate. Print
printing LENGTH characters, or if FORCE_ELLIPSES. */ ellipses at the end if we had to stop before printing LENGTH
characters, or if FORCE_ELLIPSES. */
void void
c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, c_printstr (struct ui_file *stream, struct type *type,
unsigned int length, const char *user_encoding, int force_ellipses, const gdb_byte *string, unsigned int length,
const char *user_encoding, int force_ellipses,
const struct value_print_options *options) const struct value_print_options *options)
{ {
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
@ -405,8 +414,8 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
} }
/* If the string was not truncated due to `set print elements', and /* If the string was not truncated due to `set print elements', and
the last byte of it is a null, we don't print that, in traditional C the last byte of it is a null, we don't print that, in
style. */ traditional C style. */
if (!force_ellipses if (!force_ellipses
&& length > 0 && length > 0
&& (extract_unsigned_integer (string + (length - 1) * width, && (extract_unsigned_integer (string + (length - 1) * width,
@ -430,7 +439,8 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
break; break;
} }
encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding; encoding = (user_encoding && *user_encoding)
? user_encoding : type_encoding;
if (length == 0) if (length == 0)
{ {
@ -484,7 +494,8 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
while (num_chars == 1 && current_char == chars[0]) while (num_chars == 1 && current_char == chars[0])
{ {
num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen); num_chars = wchar_iterate (iter, &result, &chars,
&buf, &buflen);
++reps; ++reps;
} }
@ -536,8 +547,10 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
while (reps-- > 0) while (reps-- > 0)
{ {
print_wchar (current_char, orig_buf, orig_len, width, print_wchar (current_char, orig_buf,
byte_order, &wchar_buf, '"', &need_escape); orig_len, width,
byte_order, &wchar_buf,
'"', &need_escape);
++things_printed; ++things_printed;
} }
} }
@ -564,8 +577,8 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
in_quotes = 1; in_quotes = 1;
} }
need_escape = 0; need_escape = 0;
print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf, print_wchar (gdb_WEOF, buf, buflen, width, byte_order,
'"', &need_escape); &wchar_buf, '"', &need_escape);
break; break;
case wchar_iterate_incomplete: case wchar_iterate_incomplete:
@ -577,8 +590,10 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
obstack_grow_wstr (&wchar_buf, LCST ("\",")); obstack_grow_wstr (&wchar_buf, LCST ("\","));
in_quotes = 0; in_quotes = 0;
} }
obstack_grow_wstr (&wchar_buf, LCST (" <incomplete sequence ")); obstack_grow_wstr (&wchar_buf,
print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf, LCST (" <incomplete sequence "));
print_wchar (gdb_WEOF, buf, buflen, width,
byte_order, &wchar_buf,
0, &need_escape); 0, &need_escape);
obstack_grow_wstr (&wchar_buf, LCST (">")); obstack_grow_wstr (&wchar_buf, LCST (">"));
finished = 1; finished = 1;
@ -614,28 +629,30 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
} }
/* Obtain a C string from the inferior storing it in a newly allocated /* Obtain a C string from the inferior storing it in a newly allocated
buffer in BUFFER, which should be freed by the caller. If the buffer in BUFFER, which should be freed by the caller. If the in-
in- and out-parameter *LENGTH is specified at -1, the string is read and out-parameter *LENGTH is specified at -1, the string is read
until a null character of the appropriate width is found, otherwise until a null character of the appropriate width is found, otherwise
the string is read to the length of characters specified. the string is read to the length of characters specified. The size
The size of a character is determined by the length of the target of a character is determined by the length of the target type of
type of the pointer or array. If VALUE is an array with a known the pointer or array. If VALUE is an array with a known length,
length, the function will not read past the end of the array. the function will not read past the end of the array. On
On completion, *LENGTH will be set to the size of the string read in completion, *LENGTH will be set to the size of the string read in
characters. (If a length of -1 is specified, the length returned characters. (If a length of -1 is specified, the length returned
will not include the null character). CHARSET is always set to the will not include the null character). CHARSET is always set to the
target charset. */ target charset. */
void void
c_get_string (struct value *value, gdb_byte **buffer, int *length, c_get_string (struct value *value, gdb_byte **buffer,
struct type **char_type, const char **charset) int *length, struct type **char_type,
const char **charset)
{ {
int err, width; int err, width;
unsigned int fetchlimit; unsigned int fetchlimit;
struct type *type = check_typedef (value_type (value)); struct type *type = check_typedef (value_type (value));
struct type *element_type = TYPE_TARGET_TYPE (type); struct type *element_type = TYPE_TARGET_TYPE (type);
int req_length = *length; int req_length = *length;
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); enum bfd_endian byte_order
= gdbarch_byte_order (get_type_arch (type));
enum c_string_type kind; enum c_string_type kind;
if (element_type == NULL) if (element_type == NULL)
@ -643,8 +660,8 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
if (TYPE_CODE (type) == TYPE_CODE_ARRAY) if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
{ {
/* If we know the size of the array, we can use it as a limit on the /* If we know the size of the array, we can use it as a limit on
number of characters to be fetched. */ the number of characters to be fetched. */
if (TYPE_NFIELDS (type) == 1 if (TYPE_NFIELDS (type) == 1
&& TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE) && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE)
{ {
@ -670,9 +687,10 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
charset); charset);
width = TYPE_LENGTH (element_type); width = TYPE_LENGTH (element_type);
/* If the string lives in GDB's memory instead of the inferior's, then we /* If the string lives in GDB's memory instead of the inferior's,
just need to copy it to BUFFER. Also, since such strings are arrays then we just need to copy it to BUFFER. Also, since such strings
with known size, FETCHLIMIT will hold the size of the array. */ are arrays with known size, FETCHLIMIT will hold the size of the
array. */
if ((VALUE_LVAL (value) == not_lval if ((VALUE_LVAL (value) == not_lval
|| VALUE_LVAL (value) == lval_internalvar) || VALUE_LVAL (value) == lval_internalvar)
&& fetchlimit != UINT_MAX) && fetchlimit != UINT_MAX)
@ -686,8 +704,8 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
else else
/* Otherwise, look for a null character. */ /* Otherwise, look for a null character. */
for (i = 0; i < fetchlimit; i++) for (i = 0; i < fetchlimit; i++)
if (extract_unsigned_integer (contents + i * width, width, if (extract_unsigned_integer (contents + i * width,
byte_order) == 0) width, byte_order) == 0)
break; break;
/* I is now either a user-defined length, the number of non-null /* I is now either a user-defined length, the number of non-null
@ -722,8 +740,8 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
if (req_length == -1) if (req_length == -1)
/* If the last character is null, subtract it from LENGTH. */ /* If the last character is null, subtract it from LENGTH. */
if (*length > 0 if (*length > 0
&& extract_unsigned_integer (*buffer + *length - width, width, && extract_unsigned_integer (*buffer + *length - width,
byte_order) == 0) width, byte_order) == 0)
*length -= width; *length -= width;
/* The read_string function will return the number of bytes read. /* The read_string function will return the number of bytes read.
@ -778,8 +796,8 @@ convert_ucn (char *p, char *limit, const char *dest_charset,
result >>= 8; result >>= 8;
} }
convert_between_encodings ("UTF-32BE", dest_charset, data, 4, 4, output, convert_between_encodings ("UTF-32BE", dest_charset, data,
translit_none); 4, 4, output, translit_none);
return p; return p;
} }
@ -804,7 +822,8 @@ emit_numeric_character (struct type *type, unsigned long value,
pointer to just after the final digit of the escape sequence. */ pointer to just after the final digit of the escape sequence. */
static char * static char *
convert_octal (struct type *type, char *p, char *limit, struct obstack *output) convert_octal (struct type *type, char *p,
char *limit, struct obstack *output)
{ {
int i; int i;
unsigned long value = 0; unsigned long value = 0;
@ -828,7 +847,8 @@ convert_octal (struct type *type, char *p, char *limit, struct obstack *output)
just after the final digit of the escape sequence. */ just after the final digit of the escape sequence. */
static char * static char *
convert_hex (struct type *type, char *p, char *limit, struct obstack *output) convert_hex (struct type *type, char *p,
char *limit, struct obstack *output)
{ {
unsigned long value = 0; unsigned long value = 0;
@ -928,7 +948,8 @@ parse_one_string (struct obstack *output, char *data, int len,
/* If we saw a run of characters, convert them all. */ /* If we saw a run of characters, convert them all. */
if (p > data) if (p > data)
convert_between_encodings (host_charset (), dest_charset, convert_between_encodings (host_charset (), dest_charset,
data, p - data, 1, output, translit_none); data, p - data, 1,
output, translit_none);
/* If we saw an escape, convert it. */ /* If we saw an escape, convert it. */
if (p < limit) if (p < limit)
p = convert_escape (type, dest_charset, p, limit, output); p = convert_escape (type, dest_charset, p, limit, output);
@ -1186,7 +1207,8 @@ const struct language_defn c_language_defn =
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */ basic_lookup_transparent_type,/* lookup_transparent_type */
NULL, /* Language specific symbol demangler */ NULL, /* Language specific symbol demangler */
NULL, /* Language specific class_name_from_physname */ NULL, /* Language specific
class_name_from_physname */
c_op_print_tab, /* expression operators for printing */ c_op_print_tab, /* expression operators for printing */
1, /* c-style arrays */ 1, /* c-style arrays */
0, /* String lower bound */ 0, /* String lower bound */
@ -1306,7 +1328,8 @@ const struct language_defn cplus_language_defn =
cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
cp_lookup_transparent_type, /* lookup_transparent_type */ cp_lookup_transparent_type, /* lookup_transparent_type */
cplus_demangle, /* Language specific symbol demangler */ cplus_demangle, /* Language specific symbol demangler */
cp_class_name_from_physname, /* Language specific class_name_from_physname */ cp_class_name_from_physname, /* Language specific
class_name_from_physname */
c_op_print_tab, /* expression operators for printing */ c_op_print_tab, /* expression operators for printing */
1, /* c-style arrays */ 1, /* c-style arrays */
0, /* String lower bound */ 0, /* String lower bound */
@ -1344,7 +1367,8 @@ const struct language_defn asm_language_defn =
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */ basic_lookup_transparent_type,/* lookup_transparent_type */
NULL, /* Language specific symbol demangler */ NULL, /* Language specific symbol demangler */
NULL, /* Language specific class_name_from_physname */ NULL, /* Language specific
class_name_from_physname */
c_op_print_tab, /* expression operators for printing */ c_op_print_tab, /* expression operators for printing */
1, /* c-style arrays */ 1, /* c-style arrays */
0, /* String lower bound */ 0, /* String lower bound */
@ -1387,7 +1411,8 @@ const struct language_defn minimal_language_defn =
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */ basic_lookup_transparent_type,/* lookup_transparent_type */
NULL, /* Language specific symbol demangler */ NULL, /* Language specific symbol demangler */
NULL, /* Language specific class_name_from_physname */ NULL, /* Language specific
class_name_from_physname */
c_op_print_tab, /* expression operators for printing */ c_op_print_tab, /* expression operators for printing */
1, /* c-style arrays */ 1, /* c-style arrays */
0, /* String lower bound */ 0, /* String lower bound */

View file

@ -64,12 +64,15 @@ extern void c_error (char *);
extern int c_parse_escape (char **, struct obstack *); extern int c_parse_escape (char **, struct obstack *);
/* Defined in c-typeprint.c */ /* Defined in c-typeprint.c */
extern void c_print_type (struct type *, const char *, struct ui_file *, int, extern void c_print_type (struct type *, const char *,
int); struct ui_file *, int, int);
extern void c_print_typedef (struct type *, struct symbol *, struct ui_file *); extern void c_print_typedef (struct type *,
struct symbol *,
struct ui_file *);
extern int c_val_print (struct type *, const gdb_byte *, int, CORE_ADDR, extern int c_val_print (struct type *, const gdb_byte *,
int, CORE_ADDR,
struct ui_file *, int, struct ui_file *, int,
const struct value *, const struct value *,
const struct value_print_options *); const struct value_print_options *);
@ -80,14 +83,18 @@ extern int c_value_print (struct value *, struct ui_file *,
/* These are in c-lang.c: */ /* These are in c-lang.c: */
extern struct value *evaluate_subexp_c (struct type *expect_type, extern struct value *evaluate_subexp_c (struct type *expect_type,
struct expression *exp, int *pos, struct expression *exp,
int *pos,
enum noside noside); enum noside noside);
extern void c_printchar (int, struct type *, struct ui_file *); extern void c_printchar (int, struct type *, struct ui_file *);
extern void c_printstr (struct ui_file * stream, struct type *elttype, extern void c_printstr (struct ui_file * stream,
const gdb_byte *string, unsigned int length, struct type *elttype,
const char *user_encoding, int force_ellipses, const gdb_byte *string,
unsigned int length,
const char *user_encoding,
int force_ellipses,
const struct value_print_options *options); const struct value_print_options *options);
extern void c_language_arch_info (struct gdbarch *gdbarch, extern void c_language_arch_info (struct gdbarch *gdbarch,
@ -102,7 +109,8 @@ extern const struct op_print c_op_print_tab[];
/* These are in c-typeprint.c: */ /* These are in c-typeprint.c: */
extern void c_type_print_base (struct type *, struct ui_file *, int, int); extern void c_type_print_base (struct type *, struct ui_file *,
int, int);
/* These are in cp-valprint.c */ /* These are in cp-valprint.c */

View file

@ -20,7 +20,7 @@
#include "defs.h" #include "defs.h"
#include "gdb_obstack.h" #include "gdb_obstack.h"
#include "bfd.h" /* Binary File Description */ #include "bfd.h" /* Binary File Description. */
#include "symtab.h" #include "symtab.h"
#include "gdbtypes.h" #include "gdbtypes.h"
#include "expression.h" #include "expression.h"
@ -36,17 +36,21 @@
#include "gdb_string.h" #include "gdb_string.h"
#include <errno.h> #include <errno.h>
static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int, static void c_type_print_varspec_prefix (struct type *,
int, int); struct ui_file *,
int, int, int);
/* Print "const", "volatile", or address space modifiers. */ /* Print "const", "volatile", or address space modifiers. */
static void c_type_print_modifier (struct type *, struct ui_file *, static void c_type_print_modifier (struct type *,
struct ui_file *,
int, int); int, int);
/* LEVEL is the depth to indent lines by. */ /* LEVEL is the depth to indent lines by. */
void void
c_print_type (struct type *type, const char *varstring, struct ui_file *stream, c_print_type (struct type *type,
const char *varstring,
struct ui_file *stream,
int show, int level) int show, int level)
{ {
enum type_code code; enum type_code code;
@ -76,11 +80,12 @@ c_print_type (struct type *type, const char *varstring, struct ui_file *stream,
{ {
fputs_filtered (varstring, stream); fputs_filtered (varstring, stream);
/* For demangled function names, we have the arglist as part of the name, /* For demangled function names, we have the arglist as part of
so don't print an additional pair of ()'s */ the name, so don't print an additional pair of ()'s */
demangled_args = strchr (varstring, '(') != NULL; demangled_args = strchr (varstring, '(') != NULL;
c_type_print_varspec_suffix (type, stream, show, 0, demangled_args); c_type_print_varspec_suffix (type, stream, show,
0, demangled_args);
} }
} }
@ -89,7 +94,8 @@ c_print_type (struct type *type, const char *varstring, struct ui_file *stream,
which to print. */ which to print. */
void void
c_print_typedef (struct type *type, struct symbol *new_symbol, c_print_typedef (struct type *type,
struct symbol *new_symbol,
struct ui_file *stream) struct ui_file *stream)
{ {
CHECK_TYPEDEF (type); CHECK_TYPEDEF (type);
@ -104,8 +110,8 @@ c_print_typedef (struct type *type, struct symbol *new_symbol,
} }
/* If TYPE is a derived type, then print out derivation information. /* If TYPE is a derived type, then print out derivation information.
Print only the actual base classes of this type, not the base classes Print only the actual base classes of this type, not the base
of the base classes. I.E. for the derivation hierarchy: classes of the base classes. I.e. for the derivation hierarchy:
class A { int a; }; class A { int a; };
class B : public A {int b; }; class B : public A {int b; };
@ -117,21 +123,25 @@ c_print_typedef (struct type *type, struct symbol *new_symbol,
int c; int c;
} }
Not as the following (like gdb used to), which is not legal C++ syntax for Not as the following (like gdb used to), which is not legal C++
derived types and may be confused with the multiple inheritance form: syntax for derived types and may be confused with the multiple
inheritance form:
class C : public B : public A { class C : public B : public A {
int c; int c;
} }
In general, gdb should try to print the types as closely as possible to In general, gdb should try to print the types as closely as
the form that they appear in the source code. possible to the form that they appear in the source code.
Note that in case of protected derivation gcc will not say 'protected'
but 'private'. The HP's aCC compiler emits specific information for Note that in case of protected derivation gcc will not say
derivation via protected inheritance, so gdb can print it out */ 'protected' but 'private'. The HP's aCC compiler emits specific
information for derivation via protected inheritance, so gdb can
print it out */
static void static void
cp_type_print_derivation_info (struct ui_file *stream, struct type *type) cp_type_print_derivation_info (struct ui_file *stream,
struct type *type)
{ {
char *name; char *name;
int i; int i;
@ -140,8 +150,9 @@ cp_type_print_derivation_info (struct ui_file *stream, struct type *type)
{ {
fputs_filtered (i == 0 ? ": " : ", ", stream); fputs_filtered (i == 0 ? ": " : ", ", stream);
fprintf_filtered (stream, "%s%s ", fprintf_filtered (stream, "%s%s ",
BASETYPE_VIA_PUBLIC (type, i) ? "public" BASETYPE_VIA_PUBLIC (type, i)
: (TYPE_FIELD_PROTECTED (type, i) ? "protected" : "private"), ? "public" : (TYPE_FIELD_PROTECTED (type, i)
? "protected" : "private"),
BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : ""); BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : "");
name = type_name_no_tag (TYPE_BASECLASS (type, i)); name = type_name_no_tag (TYPE_BASECLASS (type, i));
fprintf_filtered (stream, "%s", name ? name : "(null)"); fprintf_filtered (stream, "%s", name ? name : "(null)");
@ -155,16 +166,19 @@ cp_type_print_derivation_info (struct ui_file *stream, struct type *type)
/* Print the C++ method arguments ARGS to the file STREAM. */ /* Print the C++ method arguments ARGS to the file STREAM. */
static void static void
cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring, cp_type_print_method_args (struct type *mtype, char *prefix,
int staticp, struct ui_file *stream) char *varstring, int staticp,
struct ui_file *stream)
{ {
struct field *args = TYPE_FIELDS (mtype); struct field *args = TYPE_FIELDS (mtype);
int nargs = TYPE_NFIELDS (mtype); int nargs = TYPE_NFIELDS (mtype);
int varargs = TYPE_VARARGS (mtype); int varargs = TYPE_VARARGS (mtype);
int i; int i;
fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI); fprintf_symbol_filtered (stream, prefix,
fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI); language_cplus, DMGL_ANSI);
fprintf_symbol_filtered (stream, varstring,
language_cplus, DMGL_ANSI);
fputs_filtered ("(", stream); fputs_filtered ("(", stream);
/* Skip the class variable. */ /* Skip the class variable. */
@ -220,8 +234,10 @@ cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring,
name. */ name. */
static void static void
c_type_print_varspec_prefix (struct type *type, struct ui_file *stream, c_type_print_varspec_prefix (struct type *type,
int show, int passed_a_ptr, int need_post_space) struct ui_file *stream,
int show, int passed_a_ptr,
int need_post_space)
{ {
char *name; char *name;
@ -236,53 +252,62 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
switch (TYPE_CODE (type)) switch (TYPE_CODE (type))
{ {
case TYPE_CODE_PTR: case TYPE_CODE_PTR:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 1, 1); c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, show, 1, 1);
fprintf_filtered (stream, "*"); fprintf_filtered (stream, "*");
c_type_print_modifier (type, stream, 1, need_post_space); c_type_print_modifier (type, stream, 1, need_post_space);
break; break;
case TYPE_CODE_MEMBERPTR: case TYPE_CODE_MEMBERPTR:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, show, 0, 0);
name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
if (name) if (name)
fputs_filtered (name, stream); fputs_filtered (name, stream);
else else
c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); c_type_print_base (TYPE_DOMAIN_TYPE (type),
stream, 0, passed_a_ptr);
fprintf_filtered (stream, "::*"); fprintf_filtered (stream, "::*");
break; break;
case TYPE_CODE_METHODPTR: case TYPE_CODE_METHODPTR:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, show, 0, 0);
fprintf_filtered (stream, "("); fprintf_filtered (stream, "(");
name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
if (name) if (name)
fputs_filtered (name, stream); fputs_filtered (name, stream);
else else
c_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); c_type_print_base (TYPE_DOMAIN_TYPE (type),
stream, 0, passed_a_ptr);
fprintf_filtered (stream, "::*"); fprintf_filtered (stream, "::*");
break; break;
case TYPE_CODE_REF: case TYPE_CODE_REF:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 1, 0); c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, show, 1, 0);
fprintf_filtered (stream, "&"); fprintf_filtered (stream, "&");
c_type_print_modifier (type, stream, 1, need_post_space); c_type_print_modifier (type, stream, 1, need_post_space);
break; break;
case TYPE_CODE_METHOD: case TYPE_CODE_METHOD:
case TYPE_CODE_FUNC: case TYPE_CODE_FUNC:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, show, 0, 0);
if (passed_a_ptr) if (passed_a_ptr)
fprintf_filtered (stream, "("); fprintf_filtered (stream, "(");
break; break;
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, show, 0, 0);
if (passed_a_ptr) if (passed_a_ptr)
fprintf_filtered (stream, "("); fprintf_filtered (stream, "(");
break; break;
case TYPE_CODE_TYPEDEF: case TYPE_CODE_TYPEDEF:
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, show, 0, 0);
break; break;
case TYPE_CODE_UNDEF: case TYPE_CODE_UNDEF:
@ -363,9 +388,9 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
/* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD
or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this" or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this"
in non-static methods, are displayed if SHOW_ARTIFICIAL is in non-static methods, are displayed if SHOW_ARTIFICIAL is
non-zero. LANGUAGE is the language in which TYPE was defined. This is non-zero. LANGUAGE is the language in which TYPE was defined.
a necessary evil since this code is used by the C, C++, and Java This is a necessary evil since this code is used by the C, C++, and
backends. */ Java backends. */
void void
c_type_print_args (struct type *type, struct ui_file *stream, c_type_print_args (struct type *type, struct ui_file *stream,
@ -391,9 +416,11 @@ c_type_print_args (struct type *type, struct ui_file *stream,
} }
if (language == language_java) if (language == language_java)
java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); java_print_type (TYPE_FIELD_TYPE (type, i),
"", stream, -1, 0);
else else
c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); c_print_type (TYPE_FIELD_TYPE (type, i),
"", stream, -1, 0);
printed_any = 1; printed_any = 1;
} }
@ -466,7 +493,8 @@ is_type_conversion_operator (struct type *type, int i, int j)
return 1; return 1;
/* That was indeed the end of the name, so it was `operator new' or /* That was indeed the end of the name, so it was `operator new' or
`operator delete', neither of which are type conversion operators. */ `operator delete', neither of which are type conversion
operators. */
return 0; return 0;
} }
@ -504,8 +532,8 @@ remove_qualifiers (char *qid)
/* If we're inside parenthesis (i.e., an argument list) or /* If we're inside parenthesis (i.e., an argument list) or
angle brackets (i.e., a list of template arguments), then angle brackets (i.e., a list of template arguments), then
we don't record the position of this :: token, since it's we don't record the position of this :: token, since it's
not relevant to the top-level structure we're trying not relevant to the top-level structure we're trying to
to operate on. */ operate on. */
if (depth == 0) if (depth == 0)
{ {
last = scan + 2; last = scan + 2;
@ -529,10 +557,10 @@ remove_qualifiers (char *qid)
depth--; depth--;
else else
{ {
/* We're going to do a little error recovery here. If we /* We're going to do a little error recovery here. If
don't find a match for *scan on the paren stack, but we don't find a match for *scan on the paren stack,
there is something lower on the stack that does match, we but there is something lower on the stack that does
pop the stack to that point. */ match, we pop the stack to that point. */
int i; int i;
for (i = depth - 1; i >= 0; i--) for (i = depth - 1; i >= 0; i--)
@ -558,8 +586,10 @@ remove_qualifiers (char *qid)
Args work like c_type_print_varspec_prefix. */ Args work like c_type_print_varspec_prefix. */
void void
c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, c_type_print_varspec_suffix (struct type *type,
int show, int passed_a_ptr, int demangled_args) struct ui_file *stream,
int show, int passed_a_ptr,
int demangled_args)
{ {
if (type == 0) if (type == 0)
return; return;
@ -580,29 +610,30 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
fprintf_filtered (stream, "["); fprintf_filtered (stream, "[");
if (get_array_bounds (type, &low_bound, &high_bound)) if (get_array_bounds (type, &low_bound, &high_bound))
fprintf_filtered (stream, "%d", (int) (high_bound - low_bound + 1)); fprintf_filtered (stream, "%d",
(int) (high_bound - low_bound + 1));
fprintf_filtered (stream, "]"); fprintf_filtered (stream, "]");
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
0, 0); show, 0, 0);
} }
break; break;
case TYPE_CODE_MEMBERPTR: case TYPE_CODE_MEMBERPTR:
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
0, 0); show, 0, 0);
break; break;
case TYPE_CODE_METHODPTR: case TYPE_CODE_METHODPTR:
fprintf_filtered (stream, ")"); fprintf_filtered (stream, ")");
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
0, 0); show, 0, 0);
break; break;
case TYPE_CODE_PTR: case TYPE_CODE_PTR:
case TYPE_CODE_REF: case TYPE_CODE_REF:
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
1, 0); show, 1, 0);
break; break;
case TYPE_CODE_METHOD: case TYPE_CODE_METHOD:
@ -610,14 +641,15 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
if (passed_a_ptr) if (passed_a_ptr)
fprintf_filtered (stream, ")"); fprintf_filtered (stream, ")");
if (!demangled_args) if (!demangled_args)
c_type_print_args (type, stream, 1, current_language->la_language); c_type_print_args (type, stream, 1,
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, current_language->la_language);
passed_a_ptr, 0); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
show, passed_a_ptr, 0);
break; break;
case TYPE_CODE_TYPEDEF: case TYPE_CODE_TYPEDEF:
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
passed_a_ptr, 0); show, passed_a_ptr, 0);
break; break;
case TYPE_CODE_UNDEF: case TYPE_CODE_UNDEF:
@ -638,7 +670,8 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
case TYPE_CODE_NAMESPACE: case TYPE_CODE_NAMESPACE:
case TYPE_CODE_DECFLOAT: case TYPE_CODE_DECFLOAT:
/* These types do not need a suffix. They are listed so that /* These types do not need a suffix. They are listed so that
gcc -Wall will report types that may not have been considered. */ gcc -Wall will report types that may not have been
considered. */
break; break;
default: default:
error (_("type not handled in c_type_print_varspec_suffix()")); error (_("type not handled in c_type_print_varspec_suffix()"));
@ -647,24 +680,26 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
} }
/* Print the name of the type (or the ultimate pointer target, /* Print the name of the type (or the ultimate pointer target,
function value or array element), or the description of a function value or array element), or the description of a structure
structure or union. or union.
SHOW positive means print details about the type (e.g. enum values), SHOW positive means print details about the type (e.g. enum
and print structure elements passing SHOW - 1 for show. values), and print structure elements passing SHOW - 1 for show.
SHOW negative means just print the type name or struct tag if there is one.
If there is no name, print something sensible but concise like SHOW negative means just print the type name or struct tag if there
"struct {...}". is one. If there is no name, print something sensible but concise
SHOW zero means just print the type name or struct tag if there is one. like "struct {...}".
If there is no name, print something sensible but not as concise like
"struct {int x; int y;}". SHOW zero means just print the type name or struct tag if there is
one. If there is no name, print something sensible but not as
concise like "struct {int x; int y;}".
LEVEL is the number of spaces to indent by. LEVEL is the number of spaces to indent by.
We increase it for some recursive calls. */ We increase it for some recursive calls. */
void void
c_type_print_base (struct type *type, struct ui_file *stream, int show, c_type_print_base (struct type *type, struct ui_file *stream,
int level) int show, int level)
{ {
int i; int i;
int len, real_len; int len, real_len;
@ -689,11 +724,12 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
return; return;
} }
/* When SHOW is zero or less, and there is a valid type name, then always /* When SHOW is zero or less, and there is a valid type name, then
just print the type name directly from the type. */ always just print the type name directly from the type. */
/* If we have "typedef struct foo {. . .} bar;" do we want to print it /* If we have "typedef struct foo {. . .} bar;" do we want to print
as "struct foo" or as "bar"? Pick the latter, because C++ folk tend it as "struct foo" or as "bar"? Pick the latter, because C++
to expect things like "class5 *foo" rather than "struct class5 *foo". */ folk tend to expect things like "class5 *foo" rather than "struct
class5 *foo". */
if (show <= 0 if (show <= 0
&& TYPE_NAME (type) != NULL) && TYPE_NAME (type) != NULL)
@ -708,8 +744,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
switch (TYPE_CODE (type)) switch (TYPE_CODE (type))
{ {
case TYPE_CODE_TYPEDEF: case TYPE_CODE_TYPEDEF:
/* If we get here, the typedef doesn't have a name, and we couldn't /* If we get here, the typedef doesn't have a name, and we
resolve TYPE_TARGET_TYPE. Not much we can do. */ couldn't resolve TYPE_TARGET_TYPE. Not much we can do. */
gdb_assert (TYPE_NAME (type) == NULL); gdb_assert (TYPE_NAME (type) == NULL);
gdb_assert (TYPE_TARGET_TYPE (type) == NULL); gdb_assert (TYPE_TARGET_TYPE (type) == NULL);
fprintf_filtered (stream, _("<unnamed typedef>")); fprintf_filtered (stream, _("<unnamed typedef>"));
@ -722,7 +758,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
case TYPE_CODE_FUNC: case TYPE_CODE_FUNC:
case TYPE_CODE_METHOD: case TYPE_CODE_METHOD:
case TYPE_CODE_METHODPTR: case TYPE_CODE_METHODPTR:
c_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); c_type_print_base (TYPE_TARGET_TYPE (type),
stream, show, level);
break; break;
case TYPE_CODE_STRUCT: case TYPE_CODE_STRUCT:
@ -739,12 +776,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
struct_union: struct_union:
/* Print the tag if it exists. /* Print the tag if it exists. The HP aCC compiler emits a
* The HP aCC compiler emits spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed
* a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}" enum}" tag for unnamed struct/union/enum's, which we don't
* tag for unnamed struct/union/enum's, which we don't want to print. */
* want to print.
*/
if (TYPE_TAG_NAME (type) != NULL if (TYPE_TAG_NAME (type) != NULL
&& strncmp (TYPE_TAG_NAME (type), "{unnamed", 8)) && strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
{ {
@ -755,7 +790,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
wrap_here (" "); wrap_here (" ");
if (show < 0) if (show < 0)
{ {
/* If we just printed a tag name, no need to print anything else. */ /* If we just printed a tag name, no need to print anything
else. */
if (TYPE_TAG_NAME (type) == NULL) if (TYPE_TAG_NAME (type) == NULL)
fprintf_filtered (stream, "{...}"); fprintf_filtered (stream, "{...}");
} }
@ -771,9 +807,11 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
&& TYPE_TYPEDEF_FIELD_COUNT (type) == 0) && TYPE_TYPEDEF_FIELD_COUNT (type) == 0)
{ {
if (TYPE_STUB (type)) if (TYPE_STUB (type))
fprintfi_filtered (level + 4, stream, _("<incomplete type>\n")); fprintfi_filtered (level + 4, stream,
_("<incomplete type>\n"));
else else
fprintfi_filtered (level + 4, stream, _("<no data fields>\n")); fprintfi_filtered (level + 4, stream,
_("<no data fields>\n"));
} }
/* Start off with no specific section type, so we can print /* Start off with no specific section type, so we can print
@ -820,7 +858,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
QUIT; QUIT;
len = TYPE_NFIELDS (type); len = TYPE_NFIELDS (type);
for (i = TYPE_N_BASECLASSES (type); i < len; i++) for (i = TYPE_N_BASECLASSES (type); i < len; i++)
if (TYPE_FIELD_PRIVATE (type, i) || TYPE_FIELD_PROTECTED (type, i)) if (TYPE_FIELD_PRIVATE (type, i)
|| TYPE_FIELD_PROTECTED (type, i))
{ {
need_access_label = 1; need_access_label = 1;
break; break;
@ -878,7 +917,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (section_type != s_private) if (section_type != s_private)
{ {
section_type = s_private; section_type = s_private;
fprintfi_filtered (level + 2, stream, "private:\n"); fprintfi_filtered (level + 2, stream,
"private:\n");
} }
} }
else else
@ -886,7 +926,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (section_type != s_public) if (section_type != s_public)
{ {
section_type = s_public; section_type = s_public;
fprintfi_filtered (level + 2, stream, "public:\n"); fprintfi_filtered (level + 2, stream,
"public:\n");
} }
} }
} }
@ -912,8 +953,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
} }
/* If there are both fields and methods, put a blank line /* If there are both fields and methods, put a blank line
between them. Make sure to count only method that we will between them. Make sure to count only method that we
display; artificial methods will be hidden. */ will display; artificial methods will be hidden. */
len = TYPE_NFN_FIELDS (type); len = TYPE_NFN_FIELDS (type);
real_len = 0; real_len = 0;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
@ -936,7 +977,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
char *method_name = TYPE_FN_FIELDLIST_NAME (type, i); char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
char *name = type_name_no_tag (type); char *name = type_name_no_tag (type);
int is_constructor = name && strcmp (method_name, name) == 0; int is_constructor = name && strcmp (method_name,
name) == 0;
for (j = 0; j < len2; j++) for (j = 0; j < len2; j++)
{ {
@ -965,7 +1007,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (section_type != s_private) if (section_type != s_private)
{ {
section_type = s_private; section_type = s_private;
fprintfi_filtered (level + 2, stream, "private:\n"); fprintfi_filtered (level + 2, stream,
"private:\n");
} }
} }
else else
@ -973,7 +1016,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (section_type != s_public) if (section_type != s_public)
{ {
section_type = s_public; section_type = s_public;
fprintfi_filtered (level + 2, stream, "public:\n"); fprintfi_filtered (level + 2, stream,
"public:\n");
} }
} }
@ -985,11 +1029,14 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
{ {
/* Keep GDB from crashing here. */ /* Keep GDB from crashing here. */
fprintf_filtered (stream, _("<undefined type> %s;\n"), fprintf_filtered (stream,
_("<undefined type> %s;\n"),
TYPE_FN_FIELD_PHYSNAME (f, j)); TYPE_FN_FIELD_PHYSNAME (f, j));
break; break;
} }
else if (!is_constructor /* constructors don't have declared types */ else if (!is_constructor /* Constructors don't
have declared
types. */
&& !is_full_physname_constructor /* " " */ && !is_full_physname_constructor /* " " */
&& !is_type_conversion_operator (type, i, j)) && !is_type_conversion_operator (type, i, j))
{ {
@ -1008,11 +1055,11 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
DMGL_ANSI | DMGL_PARAMS); DMGL_ANSI | DMGL_PARAMS);
if (demangled_name == NULL) if (demangled_name == NULL)
{ {
/* in some cases (for instance with the HP demangling), /* In some cases (for instance with the HP
if a function has more than 10 arguments, demangling), if a function has more than 10
the demangling will fail. arguments, the demangling will fail.
Let's try to reconstruct the function signature from Let's try to reconstruct the function
the symbol information */ signature from the symbol information. */
if (!TYPE_FN_FIELD_STUB (f, j)) if (!TYPE_FN_FIELD_STUB (f, j))
{ {
int staticp = TYPE_FN_FIELD_STATIC_P (f, j); int staticp = TYPE_FN_FIELD_STATIC_P (f, j);
@ -1025,7 +1072,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
stream); stream);
} }
else else
fprintf_filtered (stream, _("<badly mangled name '%s'>"), fprintf_filtered (stream,
_("<badly mangled name '%s'>"),
mangled_name); mangled_name);
} }
else else
@ -1034,14 +1082,17 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
char *demangled_no_class char *demangled_no_class
= remove_qualifiers (demangled_name); = remove_qualifiers (demangled_name);
/* get rid of the `static' appended by the demangler */ /* Get rid of the `static' appended by the
demangler. */
p = strstr (demangled_no_class, " static"); p = strstr (demangled_no_class, " static");
if (p != NULL) if (p != NULL)
{ {
int length = p - demangled_no_class; int length = p - demangled_no_class;
demangled_no_static = (char *) xmalloc (length + 1); demangled_no_static
strncpy (demangled_no_static, demangled_no_class, length); = (char *) xmalloc (length + 1);
strncpy (demangled_no_static,
demangled_no_class, length);
*(demangled_no_static + length) = '\0'; *(demangled_no_static + length) = '\0';
fputs_filtered (demangled_no_static, stream); fputs_filtered (demangled_no_static, stream);
xfree (demangled_no_static); xfree (demangled_no_static);
@ -1084,7 +1135,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
fprintfi_filtered (level, stream, "}"); fprintfi_filtered (level, stream, "}");
if (TYPE_LOCALTYPE_PTR (type) && show >= 0) if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
fprintfi_filtered (level, stream, _(" (Local at %s:%d)\n"), fprintfi_filtered (level,
stream, _(" (Local at %s:%d)\n"),
TYPE_LOCALTYPE_FILE (type), TYPE_LOCALTYPE_FILE (type),
TYPE_LOCALTYPE_LINE (type)); TYPE_LOCALTYPE_LINE (type));
} }
@ -1109,7 +1161,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
wrap_here (" "); wrap_here (" ");
if (show < 0) if (show < 0)
{ {
/* If we just printed a tag name, no need to print anything else. */ /* If we just printed a tag name, no need to print anything
else. */
if (TYPE_TAG_NAME (type) == NULL) if (TYPE_TAG_NAME (type) == NULL)
fprintf_filtered (stream, "{...}"); fprintf_filtered (stream, "{...}");
} }
@ -1127,7 +1180,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
fputs_filtered (TYPE_FIELD_NAME (type, i), stream); fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
if (lastval != TYPE_FIELD_BITPOS (type, i)) if (lastval != TYPE_FIELD_BITPOS (type, i))
{ {
fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i)); fprintf_filtered (stream, " = %d",
TYPE_FIELD_BITPOS (type, i));
lastval = TYPE_FIELD_BITPOS (type, i); lastval = TYPE_FIELD_BITPOS (type, i);
} }
lastval++; lastval++;
@ -1159,10 +1213,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
break; break;
default: default:
/* Handle types not explicitly handled by the other cases, /* Handle types not explicitly handled by the other cases, such
such as fundamental types. For these, just print whatever as fundamental types. For these, just print whatever the
the type name is, as recorded in the type itself. If there type name is, as recorded in the type itself. If there is no
is no type name, then complain. */ type name, then complain. */
if (TYPE_NAME (type) != NULL) if (TYPE_NAME (type) != NULL)
{ {
c_type_print_modifier (type, stream, 0, 1); c_type_print_modifier (type, stream, 0, 1);
@ -1170,8 +1224,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
} }
else else
{ {
/* At least for dump_symtab, it is important that this not be /* At least for dump_symtab, it is important that this not
an error (). */ be an error (). */
fprintf_filtered (stream, _("<invalid type code %d>"), fprintf_filtered (stream, _("<invalid type code %d>"),
TYPE_CODE (type)); TYPE_CODE (type));
} }

View file

@ -36,14 +36,17 @@
stream STREAM. */ stream STREAM. */
static void static void
print_function_pointer_address (struct gdbarch *gdbarch, CORE_ADDR address, print_function_pointer_address (struct gdbarch *gdbarch,
struct ui_file *stream, int addressprint) CORE_ADDR address,
struct ui_file *stream,
int addressprint)
{ {
CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, address, CORE_ADDR func_addr
= gdbarch_convert_from_func_ptr_addr (gdbarch, address,
&current_target); &current_target);
/* If the function pointer is represented by a description, print the /* If the function pointer is represented by a description, print
address of the description. */ the address of the description. */
if (addressprint && func_addr != address) if (addressprint && func_addr != address)
{ {
fputs_filtered ("@", stream); fputs_filtered ("@", stream);
@ -69,8 +72,8 @@ textual_name (const char *name)
/* Apply a heuristic to decide whether an array of TYPE or a pointer /* Apply a heuristic to decide whether an array of TYPE or a pointer
to TYPE should be printed as a textual string. Return non-zero if to TYPE should be printed as a textual string. Return non-zero if
it should, or zero if it should be treated as an array of integers it should, or zero if it should be treated as an array of integers
or pointer to integers. FORMAT is the current format letter, or pointer to integers. FORMAT is the current format letter, or 0
or 0 if none. if none.
We guess that "char" is a character. Explicitly signed and We guess that "char" is a character. Explicitly signed and
unsigned character types are also characters. Integer data from unsigned character types are also characters. Integer data from
@ -119,8 +122,8 @@ c_textual_element_type (struct type *type, char format)
if (format == 's') if (format == 's')
{ {
/* Print this as a string if we can manage it. For now, no /* Print this as a string if we can manage it. For now, no wide
wide character support. */ character support. */
if (TYPE_CODE (true_type) == TYPE_CODE_INT if (TYPE_CODE (true_type) == TYPE_CODE_INT
&& TYPE_LENGTH (true_type) == 1) && TYPE_LENGTH (true_type) == 1)
return 1; return 1;
@ -140,22 +143,23 @@ c_textual_element_type (struct type *type, char format)
} }
/* Print data of type TYPE located at VALADDR (within GDB), which came from /* Print data of type TYPE located at VALADDR (within GDB), which came
the inferior at address ADDRESS, onto stdio stream STREAM according to from the inferior at address ADDRESS, onto stdio stream STREAM
OPTIONS. The data at VALADDR is in target byte order. according to OPTIONS. The data at VALADDR is in target byte order.
If the data are a string pointer, returns the number of string characters If the data are a string pointer, returns the number of string
printed. */ characters printed. */
int int
c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, c_val_print (struct type *type, const gdb_byte *valaddr,
CORE_ADDR address, struct ui_file *stream, int recurse, int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int recurse,
const struct value *original_value, const struct value *original_value,
const struct value_print_options *options) const struct value_print_options *options)
{ {
struct gdbarch *gdbarch = get_type_arch (type); struct gdbarch *gdbarch = get_type_arch (type);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int i = 0; /* Number of characters printed */ unsigned int i = 0; /* Number of characters printed. */
unsigned len; unsigned len;
struct type *elttype, *unresolved_elttype; struct type *elttype, *unresolved_elttype;
struct type *unresolved_type = type; struct type *unresolved_type = type;
@ -185,13 +189,14 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
/* Print arrays of textual chars with a string syntax, as /* Print arrays of textual chars with a string syntax, as
long as the entire array is valid. */ long as the entire array is valid. */
if (c_textual_element_type (unresolved_elttype, options->format) if (c_textual_element_type (unresolved_elttype,
options->format)
&& value_bits_valid (original_value, && value_bits_valid (original_value,
TARGET_CHAR_BIT * embedded_offset, TARGET_CHAR_BIT * embedded_offset,
TARGET_CHAR_BIT * TYPE_LENGTH (type))) TARGET_CHAR_BIT * TYPE_LENGTH (type)))
{ {
/* If requested, look for the first null char and only print /* If requested, look for the first null char and only
elements up to it. */ print elements up to it. */
if (options->stop_print_at_null) if (options->stop_print_at_null)
{ {
unsigned int temp_len; unsigned int temp_len;
@ -216,24 +221,28 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
{ {
fprintf_filtered (stream, "{"); fprintf_filtered (stream, "{");
/* If this is a virtual function table, print the 0th /* If this is a virtual function table, print the 0th
entry specially, and the rest of the members normally. */ entry specially, and the rest of the members
normally. */
if (cp_is_vtbl_ptr_type (elttype)) if (cp_is_vtbl_ptr_type (elttype))
{ {
i = 1; i = 1;
fprintf_filtered (stream, _("%d vtable entries"), len - 1); fprintf_filtered (stream, _("%d vtable entries"),
len - 1);
} }
else else
{ {
i = 0; i = 0;
} }
val_print_array_elements (type, valaddr + embedded_offset, val_print_array_elements (type, valaddr + embedded_offset,
address + embedded_offset, stream, address + embedded_offset,
recurse, original_value, options, i); stream, recurse,
original_value, options, i);
fprintf_filtered (stream, "}"); fprintf_filtered (stream, "}");
} }
break; break;
} }
/* Array of unspecified length: treat like pointer to first elt. */ /* Array of unspecified length: treat like pointer to first
elt. */
addr = address; addr = address;
goto print_unpacked_pointer; goto print_unpacked_pointer;
@ -262,7 +271,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
{ {
/* Print the unmangled name if desired. */ /* Print the unmangled name if desired. */
/* Print vtable entry - we only get here if we ARE using /* Print vtable entry - we only get here if we ARE using
-fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ -fvtable_thunks. (Otherwise, look under
TYPE_CODE_STRUCT.) */
CORE_ADDR addr CORE_ADDR addr
= extract_typed_address (valaddr + embedded_offset, type); = extract_typed_address (valaddr + embedded_offset, type);
@ -281,7 +291,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
/* Try to print what function it points to. */ /* Try to print what function it points to. */
print_function_pointer_address (gdbarch, addr, stream, print_function_pointer_address (gdbarch, addr, stream,
options->addressprint); options->addressprint);
/* Return value is irrelevant except for string pointers. */ /* Return value is irrelevant except for string
pointers. */
return (0); return (0);
} }
@ -291,16 +302,20 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
/* For a pointer to a textual type, also print the string /* For a pointer to a textual type, also print the string
pointed to, unless pointer is null. */ pointed to, unless pointer is null. */
if (c_textual_element_type (unresolved_elttype, options->format) if (c_textual_element_type (unresolved_elttype,
options->format)
&& addr != 0) && addr != 0)
{ {
i = val_print_string (unresolved_elttype, NULL, addr, -1, stream, i = val_print_string (unresolved_elttype, NULL,
options); addr, -1,
stream, options);
} }
else if (cp_is_vtbl_member (type)) else if (cp_is_vtbl_member (type))
{ {
/* print vtbl's nicely */ /* Print vtbl's nicely. */
CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset); CORE_ADDR vt_address = unpack_pointer (type,
valaddr
+ embedded_offset);
struct minimal_symbol *msymbol = struct minimal_symbol *msymbol =
lookup_minimal_symbol_by_pc (vt_address); lookup_minimal_symbol_by_pc (vt_address);
@ -320,8 +335,9 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
int is_this_fld; int is_this_fld;
if (msymbol != NULL) if (msymbol != NULL)
wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), block, wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
VAR_DOMAIN, &is_this_fld); block, VAR_DOMAIN,
&is_this_fld);
if (wsym) if (wsym)
{ {
@ -332,8 +348,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
wtype = unresolved_elttype; wtype = unresolved_elttype;
} }
vt_val = value_at (wtype, vt_address); vt_val = value_at (wtype, vt_address);
common_val_print (vt_val, stream, recurse + 1, options, common_val_print (vt_val, stream, recurse + 1,
current_language); options, current_language);
if (options->pretty) if (options->pretty)
{ {
fprintf_filtered (stream, "\n"); fprintf_filtered (stream, "\n");
@ -342,9 +358,10 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
} }
} }
/* Return number of characters printed, including the terminating /* Return number of characters printed, including the
'\0' if we reached the end. val_print_string takes care including terminating '\0' if we reached the end. val_print_string
the terminating '\0' if necessary. */ takes care including the terminating '\0' if
necessary. */
return i; return i;
} }
break; break;
@ -392,10 +409,13 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
{ {
/* Print the unmangled name if desired. */ /* Print the unmangled name if desired. */
/* Print vtable entry - we only get here if NOT using /* Print vtable entry - we only get here if NOT using
-fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */ -fvtable_thunks. (Otherwise, look under
int offset = (embedded_offset + TYPE_CODE_PTR.) */
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8); int offset = (embedded_offset
struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET); + TYPE_FIELD_BITPOS (type,
VTBL_FNADDR_OFFSET) / 8);
struct type *field_type = TYPE_FIELD_TYPE (type,
VTBL_FNADDR_OFFSET);
CORE_ADDR addr CORE_ADDR addr
= extract_typed_address (valaddr + offset, field_type); = extract_typed_address (valaddr + offset, field_type);
@ -404,8 +424,10 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
} }
else else
cp_print_value_fields_rtti (type, valaddr, cp_print_value_fields_rtti (type, valaddr,
embedded_offset, address, stream, embedded_offset, address,
recurse, original_value, options, NULL, 0); stream, recurse,
original_value, options,
NULL, 0);
break; break;
case TYPE_CODE_ENUM: case TYPE_CODE_ENUM:
@ -440,7 +462,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
print_scalar_formatted (valaddr + embedded_offset, type, print_scalar_formatted (valaddr + embedded_offset, type,
options, 0, stream); options, 0, stream);
else else
val_print_type_code_flags (type, valaddr + embedded_offset, stream); val_print_type_code_flags (type, valaddr + embedded_offset,
stream);
break; break;
case TYPE_CODE_FUNC: case TYPE_CODE_FUNC:
@ -451,8 +474,9 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
options, 0, stream); options, 0, stream);
break; break;
} }
/* FIXME, we should consider, at least for ANSI C language, eliminating /* FIXME, we should consider, at least for ANSI C language,
the distinction made between FUNCs and POINTERs to FUNCs. */ eliminating the distinction made between FUNCs and POINTERs
to FUNCs. */
fprintf_filtered (stream, "{"); fprintf_filtered (stream, "{");
type_print (type, "", stream, -1); type_print (type, "", stream, -1);
fprintf_filtered (stream, "} "); fprintf_filtered (stream, "} ");
@ -483,12 +507,12 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
case TYPE_CODE_RANGE: case TYPE_CODE_RANGE:
/* FIXME: create_range_type does not set the unsigned bit in a /* FIXME: create_range_type does not set the unsigned bit in a
range type (I think it probably should copy it from the target range type (I think it probably should copy it from the
type), so we won't print values which are too large to target type), so we won't print values which are too large to
fit in a signed integer correctly. */ fit in a signed integer correctly. */
/* FIXME: Doesn't handle ranges of enums correctly. (Can't just /* FIXME: Doesn't handle ranges of enums correctly. (Can't just
print with the target type, though, because the size of our type print with the target type, though, because the size of our
and the target type might differ). */ type and the target type might differ). */
/* FALLTHROUGH */ /* FALLTHROUGH */
case TYPE_CODE_INT: case TYPE_CODE_INT:
@ -503,15 +527,18 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
} }
else else
{ {
val_print_type_code_int (type, valaddr + embedded_offset, stream); val_print_type_code_int (type, valaddr + embedded_offset,
/* C and C++ has no single byte int type, char is used instead. stream);
Since we don't know whether the value is really intended to /* C and C++ has no single byte int type, char is used
be used as an integer or a character, print the character instead. Since we don't know whether the value is really
equivalent as well. */ intended to be used as an integer or a character, print
the character equivalent as well. */
if (c_textual_element_type (unresolved_type, options->format)) if (c_textual_element_type (unresolved_type, options->format))
{ {
fputs_filtered (" ", stream); fputs_filtered (" ", stream);
LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset), LA_PRINT_CHAR ((unsigned char) unpack_long (type,
valaddr
+ embedded_offset),
unresolved_type, stream); unresolved_type, stream);
} }
} }
@ -555,7 +582,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
print_scalar_formatted (valaddr + embedded_offset, type, print_scalar_formatted (valaddr + embedded_offset, type,
options, 0, stream); options, 0, stream);
else else
print_decimal_floating (valaddr + embedded_offset, type, stream); print_decimal_floating (valaddr + embedded_offset,
type, stream);
break; break;
case TYPE_CODE_VOID: case TYPE_CODE_VOID:
@ -567,9 +595,10 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
break; break;
case TYPE_CODE_UNDEF: case TYPE_CODE_UNDEF:
/* This happens (without TYPE_FLAG_STUB set) on systems which don't use /* This happens (without TYPE_FLAG_STUB set) on systems which
dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a
and no complete type for struct foo in that file. */ "struct foo *bar" and no complete type for struct foo in that
file. */
fprintf_filtered (stream, _("<incomplete type>")); fprintf_filtered (stream, _("<incomplete type>"));
break; break;
@ -579,7 +608,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
TYPE_TARGET_TYPE (type), TYPE_TARGET_TYPE (type),
options, 0, stream); options, 0, stream);
else else
print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), print_floating (valaddr + embedded_offset,
TYPE_TARGET_TYPE (type),
stream); stream);
fprintf_filtered (stream, " + "); fprintf_filtered (stream, " + ");
if (options->format) if (options->format)
@ -596,7 +626,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
break; break;
default: default:
error (_("Invalid C/C++ type code %d in symbol table."), TYPE_CODE (type)); error (_("Invalid C/C++ type code %d in symbol table."),
TYPE_CODE (type));
} }
gdb_flush (stream); gdb_flush (stream);
return (0); return (0);
@ -635,10 +666,11 @@ c_value_print (struct value *val, struct ui_file *stream,
if (TYPE_CODE (val_type) == TYPE_CODE_PTR if (TYPE_CODE (val_type) == TYPE_CODE_PTR
&& TYPE_NAME (val_type) == NULL && TYPE_NAME (val_type) == NULL
&& TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL
&& (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)), "char") == 0 && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)),
"char") == 0
|| textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type))))) || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type)))))
{ {
/* Print nothing */ /* Print nothing. */
} }
else if (options->objectprint else if (options->objectprint
&& (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
@ -647,27 +679,31 @@ c_value_print (struct value *val, struct ui_file *stream,
if (TYPE_CODE(type) == TYPE_CODE_REF) if (TYPE_CODE(type) == TYPE_CODE_REF)
{ {
/* Copy value, change to pointer, so we don't get an /* Copy value, change to pointer, so we don't get an
* error about a non-pointer type in value_rtti_target_type error about a non-pointer type in
*/ value_rtti_target_type. */
struct value *temparg; struct value *temparg;
temparg=value_copy(val); temparg=value_copy(val);
deprecated_set_value_type (temparg, lookup_pointer_type (TYPE_TARGET_TYPE(type))); deprecated_set_value_type
val=temparg; (temparg, lookup_pointer_type (TYPE_TARGET_TYPE (type)));
val = temparg;
} }
/* Pointer to class, check real type of object */ /* Pointer to class, check real type of object. */
fprintf_filtered (stream, "("); fprintf_filtered (stream, "(");
real_type = value_rtti_target_type (val, &full, &top, &using_enc); real_type = value_rtti_target_type (val, &full,
&top, &using_enc);
if (real_type) if (real_type)
{ {
/* RTTI entry found */ /* RTTI entry found. */
if (TYPE_CODE (type) == TYPE_CODE_PTR) if (TYPE_CODE (type) == TYPE_CODE_PTR)
{ {
/* create a pointer type pointing to the real type */ /* Create a pointer type pointing to the real
type. */
type = lookup_pointer_type (real_type); type = lookup_pointer_type (real_type);
} }
else else
{ {
/* create a reference type referencing the real type */ /* Create a reference type referencing the real
type. */
type = lookup_reference_type (real_type); type = lookup_reference_type (real_type);
} }
/* JYG: Need to adjust pointer value. */ /* JYG: Need to adjust pointer value. */
@ -675,7 +711,7 @@ c_value_print (struct value *val, struct ui_file *stream,
value_contents_writeable (val)[0] -= top; value_contents_writeable (val)[0] -= top;
/* Note: When we look up RTTI entries, we don't get any /* Note: When we look up RTTI entries, we don't get any
information on const or volatile attributes */ information on const or volatile attributes. */
} }
type_print (type, "", stream, -1); type_print (type, "", stream, -1);
fprintf_filtered (stream, ") "); fprintf_filtered (stream, ") ");
@ -695,26 +731,28 @@ c_value_print (struct value *val, struct ui_file *stream,
if (options->objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS)) if (options->objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS))
{ {
/* Attempt to determine real type of object */ /* Attempt to determine real type of object. */
real_type = value_rtti_type (val, &full, &top, &using_enc); real_type = value_rtti_type (val, &full, &top, &using_enc);
if (real_type) if (real_type)
{ {
/* We have RTTI information, so use it */ /* We have RTTI information, so use it. */
val = value_full_object (val, real_type, full, top, using_enc); val = value_full_object (val, real_type,
full, top, using_enc);
fprintf_filtered (stream, "(%s%s) ", fprintf_filtered (stream, "(%s%s) ",
TYPE_NAME (real_type), TYPE_NAME (real_type),
full ? "" : _(" [incomplete object]")); full ? "" : _(" [incomplete object]"));
/* Print out object: enclosing type is same as real_type if full */ /* Print out object: enclosing type is same as real_type if
full. */
return val_print (value_enclosing_type (val), return val_print (value_enclosing_type (val),
value_contents_for_printing (val), 0, value_contents_for_printing (val), 0,
value_address (val), stream, 0, value_address (val), stream, 0,
val, &opts, current_language); val, &opts, current_language);
/* Note: When we look up RTTI entries, we don't get any information on /* Note: When we look up RTTI entries, we don't get any
const or volatile attributes */ information on const or volatile attributes. */
} }
else if (type != check_typedef (value_enclosing_type (val))) else if (type != check_typedef (value_enclosing_type (val)))
{ {
/* No RTTI information, so let's do our best */ /* No RTTI information, so let's do our best. */
fprintf_filtered (stream, "(%s ?) ", fprintf_filtered (stream, "(%s ?) ",
TYPE_NAME (value_enclosing_type (val))); TYPE_NAME (value_enclosing_type (val)));
return val_print (value_enclosing_type (val), return val_print (value_enclosing_type (val),
@ -722,7 +760,7 @@ c_value_print (struct value *val, struct ui_file *stream,
value_address (val), stream, 0, value_address (val), stream, 0,
val, &opts, current_language); val, &opts, current_language);
} }
/* Otherwise, we end up at the return outside this "if" */ /* Otherwise, we end up at the return outside this "if". */
} }
return val_print (val_type, value_contents_for_printing (val), return val_print (val_type, value_contents_for_printing (val),

View file

@ -238,8 +238,10 @@ show_target_charset_name (struct ui_file *file, int from_tty,
static const char *target_wide_charset_name = "auto"; static const char *target_wide_charset_name = "auto";
static void static void
show_target_wide_charset_name (struct ui_file *file, int from_tty, show_target_wide_charset_name (struct ui_file *file,
struct cmd_list_element *c, const char *value) int from_tty,
struct cmd_list_element *c,
const char *value)
{ {
if (!strcmp (value, "auto")) if (!strcmp (value, "auto"))
fprintf_filtered (file, fprintf_filtered (file,
@ -338,7 +340,8 @@ validate (struct gdbarch *gdbarch)
/* This is the sfunc for the 'set charset' command. */ /* This is the sfunc for the 'set charset' command. */
static void static void
set_charset_sfunc (char *charset, int from_tty, struct cmd_list_element *c) set_charset_sfunc (char *charset, int from_tty,
struct cmd_list_element *c)
{ {
/* CAREFUL: set the target charset here as well. */ /* CAREFUL: set the target charset here as well. */
target_charset_name = host_charset_name; target_charset_name = host_charset_name;
@ -372,12 +375,14 @@ set_target_wide_charset_sfunc (char *charset, int from_tty,
/* sfunc for the 'show charset' command. */ /* sfunc for the 'show charset' command. */
static void static void
show_charset (struct ui_file *file, int from_tty, struct cmd_list_element *c, show_charset (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *name) const char *name)
{ {
show_host_charset_name (file, from_tty, c, host_charset_name); show_host_charset_name (file, from_tty, c, host_charset_name);
show_target_charset_name (file, from_tty, c, target_charset_name); show_target_charset_name (file, from_tty, c, target_charset_name);
show_target_wide_charset_name (file, from_tty, c, target_wide_charset_name); show_target_wide_charset_name (file, from_tty, c,
target_wide_charset_name);
} }
@ -579,8 +584,8 @@ struct wchar_iterator
/* Create a new iterator. */ /* Create a new iterator. */
struct wchar_iterator * struct wchar_iterator *
make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset, make_wchar_iterator (const gdb_byte *input, size_t bytes,
size_t width) const char *charset, size_t width)
{ {
struct wchar_iterator *result; struct wchar_iterator *result;
iconv_t desc; iconv_t desc;
@ -640,21 +645,21 @@ wchar_iterate (struct wchar_iterator *iter,
size_t out_avail = out_request * sizeof (gdb_wchar_t); size_t out_avail = out_request * sizeof (gdb_wchar_t);
size_t num; size_t num;
size_t r = iconv (iter->desc, size_t r = iconv (iter->desc,
(ICONV_CONST char **) &iter->input, &iter->bytes, (ICONV_CONST char **) &iter->input,
&outptr, &out_avail); &iter->bytes, &outptr, &out_avail);
if (r == (size_t) -1) if (r == (size_t) -1)
{ {
switch (errno) switch (errno)
{ {
case EILSEQ: case EILSEQ:
/* Invalid input sequence. We still might have converted a /* Invalid input sequence. We still might have
character; if so, return it. */ converted a character; if so, return it. */
if (out_avail < out_request * sizeof (gdb_wchar_t)) if (out_avail < out_request * sizeof (gdb_wchar_t))
break; break;
/* Otherwise skip the first invalid character, and let the /* Otherwise skip the first invalid character, and let
caller know about it. */ the caller know about it. */
*out_result = wchar_iterate_invalid; *out_result = wchar_iterate_invalid;
*ptr = iter->input; *ptr = iter->input;
*len = iter->width; *len = iter->width;
@ -794,9 +799,9 @@ find_charset_names (void)
int fail = 1; int fail = 1;
struct gdb_environ *iconv_env; struct gdb_environ *iconv_env;
/* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is not /* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is
a tty. We need to recognize it and ignore it. This text is subject not a tty. We need to recognize it and ignore it. This text is
to translation, so force LANGUAGE=C. */ subject to translation, so force LANGUAGE=C. */
iconv_env = make_environ (); iconv_env = make_environ ();
init_environ (iconv_env); init_environ (iconv_env);
set_in_environ (iconv_env, "LANGUAGE", "C"); set_in_environ (iconv_env, "LANGUAGE", "C");
@ -845,8 +850,8 @@ find_charset_names (void)
buf[len] = '\0'; buf[len] = '\0';
/* libiconv will print multiple entries per line, separated /* libiconv will print multiple entries per line, separated
by spaces. Older iconvs will print multiple entries per line, by spaces. Older iconvs will print multiple entries per
indented by two spaces, and separated by ", " line, indented by two spaces, and separated by ", "
(i.e. the human readable form). */ (i.e. the human readable form). */
start = buf; start = buf;
while (1) while (1)
@ -933,8 +938,8 @@ _initialize_charset (void)
leak a little memory, if the user later changes the host charset, leak a little memory, if the user later changes the host charset,
but that doesn't matter much. */ but that doesn't matter much. */
auto_host_charset_name = xstrdup (nl_langinfo (CODESET)); auto_host_charset_name = xstrdup (nl_langinfo (CODESET));
/* Solaris will return `646' here -- but the Solaris iconv then /* Solaris will return `646' here -- but the Solaris iconv then does
does not accept this. Darwin (and maybe FreeBSD) may return "" here, not accept this. Darwin (and maybe FreeBSD) may return "" here,
which GNU libiconv doesn't like (infinite loop). */ which GNU libiconv doesn't like (infinite loop). */
if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name) if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name)
auto_host_charset_name = "ASCII"; auto_host_charset_name = "ASCII";

View file

@ -60,8 +60,10 @@ enum transliterations
caller is responsible for initializing the obstack, and for caller is responsible for initializing the obstack, and for
destroying the obstack should an error occur. destroying the obstack should an error occur.
TRANSLIT specifies how invalid conversions should be handled. */ TRANSLIT specifies how invalid conversions should be handled. */
void convert_between_encodings (const char *from, const char *to, void convert_between_encodings (const char *from, const char *to,
const gdb_byte *bytes, unsigned int num_bytes, const gdb_byte *bytes,
unsigned int num_bytes,
int width, struct obstack *output, int width, struct obstack *output,
enum transliterations translit); enum transliterations translit);
@ -91,7 +93,8 @@ struct wchar_iterator;
This function either returns a new character set iterator, or calls This function either returns a new character set iterator, or calls
error. The result can be freed using a cleanup; see error. The result can be freed using a cleanup; see
make_cleanup_wchar_iterator. */ make_cleanup_wchar_iterator. */
struct wchar_iterator *make_wchar_iterator (const gdb_byte *input, size_t bytes, struct wchar_iterator *make_wchar_iterator (const gdb_byte *input,
size_t bytes,
const char *charset, const char *charset,
size_t width); size_t width);

View file

@ -39,7 +39,8 @@ struct read_pe_section_data
CORE_ADDR vma_offset; /* Offset to loaded address of section. */ CORE_ADDR vma_offset; /* Offset to loaded address of section. */
unsigned long rva_start; /* Start offset within the pe. */ unsigned long rva_start; /* Start offset within the pe. */
unsigned long rva_end; /* End offset within the pe. */ unsigned long rva_end; /* End offset within the pe. */
enum minimal_symbol_type ms_type; /* Type to assign symbols in section. */ enum minimal_symbol_type ms_type; /* Type to assign symbols in
section. */
}; };
#define PE_SECTION_INDEX_TEXT 0 #define PE_SECTION_INDEX_TEXT 0
@ -125,7 +126,8 @@ add_pe_exported_sym (char *sym_name,
xfree (qualified_name); xfree (qualified_name);
/* Enter the plain name as well, which might not be unique. */ /* Enter the plain name as well, which might not be unique. */
prim_record_minimal_symbol (sym_name, vma, section_data->ms_type, objfile); prim_record_minimal_symbol (sym_name, vma,
section_data->ms_type, objfile);
} }
/* Truncate a dll_name at the first dot character. */ /* Truncate a dll_name at the first dot character. */
@ -276,7 +278,8 @@ read_pe_exported_syms (struct objfile *objfile)
return; return;
} }
/* Scan sections and store the base and size of the relevant sections. */ /* Scan sections and store the base and size of the relevant
sections. */
for (i = 0; i < nsections; i++) for (i = 0; i < nsections; i++)
{ {
unsigned long secptr1 = secptr + 40 * i; unsigned long secptr1 = secptr + 40 * i;
@ -354,6 +357,6 @@ read_pe_exported_syms (struct objfile *objfile)
} }
} }
/* discard expdata. */ /* Discard expdata. */
do_cleanups (back_to); do_cleanups (back_to);
} }

View file

@ -24,7 +24,8 @@
struct objfile; struct objfile;
/* Read the export table and convert it to minimal symbol table entries */ /* Read the export table and convert it to minimal symbol table
entries */
extern void read_pe_exported_syms (struct objfile *objfile); extern void read_pe_exported_syms (struct objfile *objfile);
#endif /* !defined (COFF_PE_READ_H) */ #endif /* !defined (COFF_PE_READ_H) */

View file

@ -51,19 +51,20 @@ extern void _initialize_coffread (void);
struct coff_symfile_info struct coff_symfile_info
{ {
file_ptr min_lineno_offset; /* Where in file lowest line#s are */ file_ptr min_lineno_offset; /* Where in file lowest line#s are. */
file_ptr max_lineno_offset; /* 1+last byte of line#s in file */ file_ptr max_lineno_offset; /* 1+last byte of line#s in file. */
CORE_ADDR textaddr; /* Addr of .text section. */ CORE_ADDR textaddr; /* Addr of .text section. */
unsigned int textsize; /* Size of .text section. */ unsigned int textsize; /* Size of .text section. */
struct stab_section_list *stabsects; /* .stab sections. */ struct stab_section_list *stabsects; /* .stab sections. */
asection *stabstrsect; /* Section pointer for .stab section */ asection *stabstrsect; /* Section pointer for .stab section. */
char *stabstrdata; char *stabstrdata;
}; };
/* Translate an external name string into a user-visible name. */ /* Translate an external name string into a user-visible name. */
#define EXTERNAL_NAME(string, abfd) \ #define EXTERNAL_NAME(string, abfd) \
(string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string) (string[0] == bfd_get_symbol_leading_char (abfd) \
? string + 1 : string)
/* To be an sdb debug type, type must have at least a basic or primary /* To be an sdb debug type, type must have at least a basic or primary
derived type. Using this rather than checking against T_NULL is derived type. Using this rather than checking against T_NULL is
@ -85,7 +86,8 @@ static bfd *nlist_bfd_global;
static int nlist_nsyms_global; static int nlist_nsyms_global;
/* Pointers to scratch storage, used for reading raw symbols and auxents. */ /* Pointers to scratch storage, used for reading raw symbols and
auxents. */
static char *temp_sym; static char *temp_sym;
static char *temp_aux; static char *temp_aux;
@ -106,10 +108,10 @@ static unsigned local_n_tshift;
#define N_TMASK local_n_tmask #define N_TMASK local_n_tmask
#define N_TSHIFT local_n_tshift #define N_TSHIFT local_n_tshift
/* Local variables that hold the sizes in the file of various COFF structures. /* Local variables that hold the sizes in the file of various COFF
(We only need to know this to read them from the file -- BFD will then structures. (We only need to know this to read them from the file
translate the data in them, into `internal_xxx' structs in the right -- BFD will then translate the data in them, into `internal_xxx'
byte order, alignment, etc.) */ structs in the right byte order, alignment, etc.) */
static unsigned local_linesz; static unsigned local_linesz;
static unsigned local_symesz; static unsigned local_symesz;
@ -124,13 +126,14 @@ static int pe_file;
static struct symbol *opaque_type_chain[HASHSIZE]; static struct symbol *opaque_type_chain[HASHSIZE];
/* Simplified internal version of coff symbol table information */ /* Simplified internal version of coff symbol table information. */
struct coff_symbol struct coff_symbol
{ {
char *c_name; char *c_name;
int c_symnum; /* symbol number of this entry */ int c_symnum; /* Symbol number of this entry. */
int c_naux; /* 0 if syment only, 1 if syment + auxent, etc */ int c_naux; /* 0 if syment only, 1 if syment +
auxent, etc. */
CORE_ADDR c_value; CORE_ADDR c_value;
int c_sclass; int c_sclass;
int c_secnum; int c_secnum;
@ -143,7 +146,8 @@ static struct type *coff_read_struct_type (int, int, int,
struct objfile *); struct objfile *);
static struct type *decode_base_type (struct coff_symbol *, static struct type *decode_base_type (struct coff_symbol *,
unsigned int, union internal_auxent *, unsigned int,
union internal_auxent *,
struct objfile *); struct objfile *);
static struct type *decode_type (struct coff_symbol *, unsigned int, static struct type *decode_type (struct coff_symbol *, unsigned int,
@ -183,7 +187,8 @@ static void free_stringtab_cleanup (void *ignore);
static int init_stringtab (bfd *, long); static int init_stringtab (bfd *, long);
static void read_one_sym (struct coff_symbol *, static void read_one_sym (struct coff_symbol *,
struct internal_syment *, union internal_auxent *); struct internal_syment *,
union internal_auxent *);
static void coff_symtab_read (long, unsigned int, struct objfile *); static void coff_symtab_read (long, unsigned int, struct objfile *);
@ -364,10 +369,9 @@ static void
coff_start_symtab (char *name) coff_start_symtab (char *name)
{ {
start_symtab ( start_symtab (
/* We fill in the filename later. start_symtab puts /* We fill in the filename later. start_symtab puts this pointer
this pointer into last_source_file and we put it in into last_source_file and we put it in subfiles->name, which
subfiles->name, which end_symtab frees; that's why end_symtab frees; that's why it must be malloc'd. */
it must be malloc'd. */
xstrdup (name), xstrdup (name),
/* We never know the directory name for COFF. */ /* We never know the directory name for COFF. */
NULL, NULL,
@ -379,8 +383,9 @@ coff_start_symtab (char *name)
/* Save the vital information from when starting to read a file, /* Save the vital information from when starting to read a file,
for use when closing off the current file. for use when closing off the current file.
NAME is the file name the symbols came from, START_ADDR is the first NAME is the file name the symbols came from, START_ADDR is the
text address for the file, and SIZE is the number of bytes of text. */ first text address for the file, and SIZE is the number of bytes of
text. */
static void static void
complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size) complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
@ -392,10 +397,10 @@ complete_symtab (char *name, CORE_ADDR start_addr, unsigned int size)
current_source_end_addr = start_addr + size; current_source_end_addr = start_addr + size;
} }
/* Finish the symbol definitions for one main source file, /* Finish the symbol definitions for one main source file, close off
close off all the lexical contexts for that file all the lexical contexts for that file (creating struct block's for
(creating struct block's for them), then make the them), then make the struct symtab for that file and put it in the
struct symtab for that file and put it in the list of all such. */ list of all such. */
static void static void
coff_end_symtab (struct objfile *objfile) coff_end_symtab (struct objfile *objfile)
@ -404,7 +409,8 @@ coff_end_symtab (struct objfile *objfile)
last_source_start_addr = current_source_start_addr; last_source_start_addr = current_source_start_addr;
symtab = end_symtab (current_source_end_addr, objfile, SECT_OFF_TEXT (objfile)); symtab = end_symtab (current_source_end_addr, objfile,
SECT_OFF_TEXT (objfile));
/* Reinitialize for beginning of new file. */ /* Reinitialize for beginning of new file. */
last_source_file = NULL; last_source_file = NULL;
@ -417,13 +423,14 @@ record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
{ {
struct bfd_section *bfd_section; struct bfd_section *bfd_section;
/* We don't want TDESC entry points in the minimal symbol table */ /* We don't want TDESC entry points in the minimal symbol table. */
if (cs->c_name[0] == '@') if (cs->c_name[0] == '@')
return NULL; return NULL;
bfd_section = cs_to_bfd_section (cs, objfile); bfd_section = cs_to_bfd_section (cs, objfile);
return prim_record_minimal_symbol_and_info (cs->c_name, address, type, return prim_record_minimal_symbol_and_info (cs->c_name, address,
section, bfd_section, objfile); type, section,
bfd_section, objfile);
} }
/* coff_symfile_init () /* coff_symfile_init ()
@ -433,11 +440,12 @@ record_minimal_symbol (struct coff_symbol *cs, CORE_ADDR address,
a pointer to "private data" which we fill with cookies and other a pointer to "private data" which we fill with cookies and other
treats for coff_symfile_read (). treats for coff_symfile_read ().
We will only be called if this is a COFF or COFF-like file. We will only be called if this is a COFF or COFF-like file. BFD
BFD handles figuring out the format of the file, and code in symtab.c handles figuring out the format of the file, and code in symtab.c
uses BFD's determination to vector to us. uses BFD's determination to vector to us.
The ultimate result is a new symtab (or, FIXME, eventually a psymtab). */ The ultimate result is a new symtab (or, FIXME, eventually a
psymtab). */
static void static void
coff_symfile_init (struct objfile *objfile) coff_symfile_init (struct objfile *objfile)
@ -449,10 +457,12 @@ coff_symfile_init (struct objfile *objfile)
memset (objfile->deprecated_sym_stab_info, 0, memset (objfile->deprecated_sym_stab_info, 0,
sizeof (struct dbx_symfile_info)); sizeof (struct dbx_symfile_info));
/* Allocate struct to keep track of the symfile */ /* Allocate struct to keep track of the symfile. */
objfile->deprecated_sym_private = xmalloc (sizeof (struct coff_symfile_info)); objfile->deprecated_sym_private
= xmalloc (sizeof (struct coff_symfile_info));
memset (objfile->deprecated_sym_private, 0, sizeof (struct coff_symfile_info)); memset (objfile->deprecated_sym_private, 0,
sizeof (struct coff_symfile_info));
/* COFF objects may be reordered, so set OBJF_REORDERED. If we /* COFF objects may be reordered, so set OBJF_REORDERED. If we
find this causes a significant slowdown in gdb then we could find this causes a significant slowdown in gdb then we could
@ -462,9 +472,9 @@ coff_symfile_init (struct objfile *objfile)
init_entry_point_info (objfile); init_entry_point_info (objfile);
} }
/* This function is called for every section; it finds the outer limits /* This function is called for every section; it finds the outer
of the line table (minimum and maximum file offset) so that the limits of the line table (minimum and maximum file offset) so that
mainline code can read the whole thing for efficiency. */ the mainline code can read the whole thing for efficiency. */
static void static void
find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo) find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
@ -473,18 +483,18 @@ find_linenos (bfd *abfd, struct bfd_section *asect, void *vpinfo)
int size, count; int size, count;
file_ptr offset, maxoff; file_ptr offset, maxoff;
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
count = asect->lineno_count; count = asect->lineno_count;
/* End of warning */ /* End of warning. */
if (count == 0) if (count == 0)
return; return;
size = count * local_linesz; size = count * local_linesz;
info = (struct coff_symfile_info *) vpinfo; info = (struct coff_symfile_info *) vpinfo;
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
offset = asect->line_filepos; offset = asect->line_filepos;
/* End of warning */ /* End of warning. */
if (offset < info->min_lineno_offset || info->min_lineno_offset == 0) if (offset < info->min_lineno_offset || info->min_lineno_offset == 0)
info->min_lineno_offset = offset; info->min_lineno_offset = offset;
@ -519,7 +529,7 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
info = (struct coff_symfile_info *) objfile->deprecated_sym_private; info = (struct coff_symfile_info *) objfile->deprecated_sym_private;
dbxinfo = objfile->deprecated_sym_stab_info; dbxinfo = objfile->deprecated_sym_stab_info;
symfile_bfd = abfd; /* Kludge for swap routines */ symfile_bfd = abfd; /* Kludge for swap routines. */
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */ /* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
num_symbols = bfd_get_symcount (abfd); /* How many syms */ num_symbols = bfd_get_symcount (abfd); /* How many syms */
@ -553,7 +563,7 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0 strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0
|| strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0; || strncmp (bfd_get_target (objfile->obfd), "epoc-pe", 7) == 0;
/* End of warning */ /* End of warning. */
info->min_lineno_offset = 0; info->min_lineno_offset = 0;
info->max_lineno_offset = 0; info->max_lineno_offset = 0;
@ -599,8 +609,8 @@ coff_symfile_read (struct objfile *objfile, int symfile_flags)
coff_symtab_read ((long) symtab_offset, num_symbols, objfile); coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
/* Install any minimal symbols that have been collected as the current /* Install any minimal symbols that have been collected as the
minimal symbols for this objfile. */ current minimal symbols for this objfile. */
install_minimal_symbols (objfile); install_minimal_symbols (objfile);
@ -661,10 +671,11 @@ coff_new_init (struct objfile *ignore)
{ {
} }
/* Perform any local cleanups required when we are done with a particular /* Perform any local cleanups required when we are done with a
objfile. I.E, we are in the process of discarding all symbol information particular objfile. I.E, we are in the process of discarding all
for an objfile, freeing up all memory held for it, and unlinking the symbol information for an objfile, freeing up all memory held for
objfile struct from the global list of known objfiles. */ it, and unlinking the objfile struct from the global list of known
objfiles. */
static void static void
coff_symfile_finish (struct objfile *objfile) coff_symfile_finish (struct objfile *objfile)
@ -674,7 +685,7 @@ coff_symfile_finish (struct objfile *objfile)
xfree (objfile->deprecated_sym_private); xfree (objfile->deprecated_sym_private);
} }
/* Let stabs reader clean up */ /* Let stabs reader clean up. */
stabsread_clear_cache (); stabsread_clear_cache ();
dwarf2_free_objfile (objfile); dwarf2_free_objfile (objfile);
@ -716,8 +727,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
struct minimal_symbol *msym; struct minimal_symbol *msym;
/* Work around a stdio bug in SunOS4.1.1 (this makes me nervous.... /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
it's hard to know I've really worked around it. The fix should be it's hard to know I've really worked around it. The fix should
harmless, anyway). The symptom of the bug is that the first be harmless, anyway). The symptom of the bug is that the first
fread (in read_one_sym), will (in my example) actually get data fread (in read_one_sym), will (in my example) actually get data
from file offset 268, when the fseek was to 264 (and ftell shows from file offset 268, when the fseek was to 264 (and ftell shows
264). This causes all hell to break loose. I was unable to 264). This causes all hell to break loose. I was unable to
@ -742,7 +753,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
last_source_file = NULL; last_source_file = NULL;
memset (opaque_type_chain, 0, sizeof opaque_type_chain); memset (opaque_type_chain, 0, sizeof opaque_type_chain);
if (type_vector) /* Get rid of previous one */ if (type_vector) /* Get rid of previous one. */
xfree (type_vector); xfree (type_vector);
type_vector_length = 160; type_vector_length = 160;
type_vector = (struct type **) type_vector = (struct type **)
@ -770,10 +781,12 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
allow printing values in this symtab. */ allow printing values in this symtab. */
current_subfile->language = language_minimal; current_subfile->language = language_minimal;
complete_symtab ("_globals_", 0, 0); complete_symtab ("_globals_", 0, 0);
/* done with all files, everything from here on out is globals */ /* Done with all files, everything from here on out is
globals. */
} }
/* Special case for file with type declarations only, no text. */ /* Special case for file with type declarations only, no
text. */
if (!last_source_file && SDB_TYPE (cs->c_type) if (!last_source_file && SDB_TYPE (cs->c_type)
&& cs->c_secnum == N_DEBUG) && cs->c_secnum == N_DEBUG)
complete_symtab (filestring, 0, 0); complete_symtab (filestring, 0, 0);
@ -781,11 +794,14 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
/* Typedefs should not be treated as symbol definitions. */ /* Typedefs should not be treated as symbol definitions. */
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF) if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{ {
/* Record all functions -- external and static -- in minsyms. */ /* Record all functions -- external and static -- in
minsyms. */
int section = cs_to_section (cs, objfile); int section = cs_to_section (cs, objfile);
tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets,
record_minimal_symbol (cs, tmpaddr, mst_text, section, objfile); SECT_OFF_TEXT (objfile));
record_minimal_symbol (cs, tmpaddr, mst_text,
section, objfile);
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr; fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = tmpaddr; fcn_start_addr = tmpaddr;
@ -804,13 +820,14 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
case C_LINE: case C_LINE:
case C_ALIAS: case C_ALIAS:
case C_HIDDEN: case C_HIDDEN:
complaint (&symfile_complaints, _("Bad n_sclass for symbol %s"), complaint (&symfile_complaints,
_("Bad n_sclass for symbol %s"),
cs->c_name); cs->c_name);
break; break;
case C_FILE: case C_FILE:
/* c_value field contains symnum of next .file entry in table /* c_value field contains symnum of next .file entry in
or symnum of first global after last .file. */ table or symnum of first global after last .file. */
next_file_symnum = cs->c_value; next_file_symnum = cs->c_value;
if (cs->c_naux > 0) if (cs->c_naux > 0)
filestring = coff_getfilename (&main_aux); filestring = coff_getfilename (&main_aux);
@ -827,12 +844,12 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
in_source_file = 1; in_source_file = 1;
break; break;
/* C_LABEL is used for labels and static functions. Including /* C_LABEL is used for labels and static functions.
it here allows gdb to see static functions when no debug Including it here allows gdb to see static functions when
info is available. */ no debug info is available. */
case C_LABEL: case C_LABEL:
/* However, labels within a function can make weird backtraces, /* However, labels within a function can make weird
so filter them out (from phdm@macqel.be). */ backtraces, so filter them out (from phdm@macqel.be). */
if (within_function) if (within_function)
break; break;
case C_STAT: case C_STAT:
@ -843,18 +860,19 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
{ {
if (strcmp (cs->c_name, ".text") == 0) if (strcmp (cs->c_name, ".text") == 0)
{ {
/* FIXME: don't wire in ".text" as section name /* FIXME: don't wire in ".text" as section name or
or symbol name! */ symbol name! */
/* Check for in_source_file deals with case of /* Check for in_source_file deals with case of a
a file with debugging symbols file with debugging symbols followed by a later
followed by a later file with no symbols. */ file with no symbols. */
if (in_source_file) if (in_source_file)
complete_symtab (filestring, complete_symtab (filestring,
cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)), cs->c_value + ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile)),
main_aux.x_scn.x_scnlen); main_aux.x_scn.x_scnlen);
in_source_file = 0; in_source_file = 0;
} }
/* flush rest of '.' symbols */ /* Flush rest of '.' symbols. */
break; break;
} }
else if (!SDB_TYPE (cs->c_type) else if (!SDB_TYPE (cs->c_type)
@ -870,7 +888,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
/* At least on a 3b1, gcc generates swbeg and string labels /* At least on a 3b1, gcc generates swbeg and string labels
that look like this. Ignore them. */ that look like this. Ignore them. */
break; break;
/* fall in for static symbols that don't start with '.' */ /* Fall in for static symbols that don't start with '.' */
case C_THUMBEXT: case C_THUMBEXT:
case C_THUMBEXTFUNC: case C_THUMBEXTFUNC:
case C_EXT: case C_EXT:
@ -917,7 +935,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
sec = cs_to_section (cs, objfile); sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value; tmpaddr = cs->c_value;
/* Statics in a PE file also get relocated */ /* Statics in a PE file also get relocated. */
if (cs->c_sclass == C_EXT if (cs->c_sclass == C_EXT
|| cs->c_sclass == C_THUMBEXTFUNC || cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT || cs->c_sclass == C_THUMBEXT
@ -936,22 +954,24 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
&& bfd_section->flags & SEC_LOAD) && bfd_section->flags & SEC_LOAD)
{ {
ms_type = ms_type =
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ? cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
mst_data : mst_file_data; ? mst_data : mst_file_data;
} }
else if (bfd_section->flags & SEC_ALLOC) else if (bfd_section->flags & SEC_ALLOC)
{ {
ms_type = ms_type =
cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ? cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
mst_bss : mst_file_bss; ? mst_bss : mst_file_bss;
} }
else else
ms_type = mst_unknown; ms_type = mst_unknown;
} }
msym = record_minimal_symbol (cs, tmpaddr, ms_type, sec, objfile); msym = record_minimal_symbol (cs, tmpaddr, ms_type,
sec, objfile);
if (msym) if (msym)
gdbarch_coff_make_msymbol_special (gdbarch, cs->c_sclass, msym); gdbarch_coff_make_msymbol_special (gdbarch,
cs->c_sclass, msym);
if (SDB_TYPE (cs->c_type)) if (SDB_TYPE (cs->c_type))
{ {
@ -970,12 +990,14 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
{ {
within_function = 1; within_function = 1;
/* value contains address of first non-init type code */ /* Value contains address of first non-init type
code. */
/* main_aux.x_sym.x_misc.x_lnsz.x_lnno /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains line number of '{' } */ contains line number of '{' }. */
if (cs->c_naux != 1) if (cs->c_naux != 1)
complaint (&symfile_complaints, complaint (&symfile_complaints,
_("`.bf' symbol %d has no aux entry"), cs->c_symnum); _("`.bf' symbol %d has no aux entry"),
cs->c_symnum);
fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
fcn_first_line_addr = cs->c_value; fcn_first_line_addr = cs->c_value;
@ -986,19 +1008,20 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
new = push_context (depth, fcn_start_addr); new = push_context (depth, fcn_start_addr);
fcn_cs_saved.c_name = getsymname (&fcn_sym_saved); fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
new->name = new->name =
process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, objfile); process_coff_symbol (&fcn_cs_saved,
&fcn_aux_saved, objfile);
} }
else if (strcmp (cs->c_name, ".ef") == 0) else if (strcmp (cs->c_name, ".ef") == 0)
{ {
if (!within_function) if (!within_function)
error (_("Bad coff function information.")); error (_("Bad coff function information."));
/* the value of .ef is the address of epilogue code; /* The value of .ef is the address of epilogue code;
not useful for gdb. */ not useful for gdb. */
/* { main_aux.x_sym.x_misc.x_lnsz.x_lnno /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
contains number of lines to '}' */ contains number of lines to '}' */
if (context_stack_depth <= 0) if (context_stack_depth <= 0)
{ /* We attempted to pop an empty context stack */ { /* We attempted to pop an empty context stack. */
complaint (&symfile_complaints, complaint (&symfile_complaints,
_("`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d"), _("`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d"),
cs->c_symnum); cs->c_symnum);
@ -1019,7 +1042,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
if (cs->c_naux != 1) if (cs->c_naux != 1)
{ {
complaint (&symfile_complaints, complaint (&symfile_complaints,
_("`.ef' symbol %d has no aux entry"), cs->c_symnum); _("`.ef' symbol %d has no aux entry"),
cs->c_symnum);
fcn_last_line = 0x7FFFFFFF; fcn_last_line = 0x7FFFFFFF;
} }
else else
@ -1028,23 +1052,25 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
} }
/* fcn_first_line is the line number of the opening '{'. /* fcn_first_line is the line number of the opening '{'.
Do not record it - because it would affect gdb's idea Do not record it - because it would affect gdb's idea
of the line number of the first statement of the function - of the line number of the first statement of the
except for one-line functions, for which it is also the line function - except for one-line functions, for which
number of all the statements and of the closing '}', and it is also the line number of all the statements and
for which we do not have any other statement-line-number. */ of the closing '}', and for which we do not have any
other statement-line-number. */
if (fcn_last_line == 1) if (fcn_last_line == 1)
record_line (current_subfile, fcn_first_line, record_line (current_subfile, fcn_first_line,
gdbarch_addr_bits_remove (gdbarch, gdbarch_addr_bits_remove (gdbarch,
fcn_first_line_addr)); fcn_first_line_addr));
else else
enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line, enter_linenos (fcn_line_ptr, fcn_first_line,
objfile); fcn_last_line, objfile);
finish_block (new->name, &local_symbols, new->old_blocks, finish_block (new->name, &local_symbols,
new->start_addr, new->old_blocks, new->start_addr,
fcn_cs_saved.c_value fcn_cs_saved.c_value
+ fcn_aux_saved.x_sym.x_misc.x_fsize + fcn_aux_saved.x_sym.x_misc.x_fsize
+ ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)), + ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile)),
objfile objfile
); );
within_function = 0; within_function = 0;
@ -1055,13 +1081,14 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
if (strcmp (cs->c_name, ".bb") == 0) if (strcmp (cs->c_name, ".bb") == 0)
{ {
tmpaddr = cs->c_value; tmpaddr = cs->c_value;
tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); tmpaddr += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
push_context (++depth, tmpaddr); push_context (++depth, tmpaddr);
} }
else if (strcmp (cs->c_name, ".eb") == 0) else if (strcmp (cs->c_name, ".eb") == 0)
{ {
if (context_stack_depth <= 0) if (context_stack_depth <= 0)
{ /* We attempted to pop an empty context stack */ { /* We attempted to pop an empty context stack. */
complaint (&symfile_complaints, complaint (&symfile_complaints,
_("`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d"), _("`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d"),
cs->c_symnum); cs->c_symnum);
@ -1079,7 +1106,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
if (local_symbols && context_stack_depth > 0) if (local_symbols && context_stack_depth > 0)
{ {
tmpaddr = tmpaddr =
cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); cs->c_value + ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
/* Make a block for the local symbols within. */ /* Make a block for the local symbols within. */
finish_block (0, &local_symbols, new->old_blocks, finish_block (0, &local_symbols, new->old_blocks,
new->start_addr, tmpaddr, objfile); new->start_addr, tmpaddr, objfile);
@ -1098,7 +1126,7 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
if ((nsyms == 0) && (pe_file)) if ((nsyms == 0) && (pe_file))
{ {
/* We've got no debugging symbols, but it's a portable /* We've got no debugging symbols, but it's a portable
executable, so try to read the export table */ executable, so try to read the export table. */
read_pe_exported_syms (objfile); read_pe_exported_syms (objfile);
} }
@ -1115,9 +1143,10 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
/* Routines for reading headers and symbols from executable. */ /* Routines for reading headers and symbols from executable. */
/* Read the next symbol, swap it, and return it in both internal_syment /* Read the next symbol, swap it, and return it in both
form, and coff_symbol form. Also return its first auxent, if any, internal_syment form, and coff_symbol form. Also return its first
in internal_auxent form, and skip any other auxents. */ auxent, if any, in internal_auxent form, and skip any other
auxents. */
static void static void
read_one_sym (struct coff_symbol *cs, read_one_sym (struct coff_symbol *cs,
@ -1138,7 +1167,8 @@ read_one_sym (struct coff_symbol *cs,
bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global); bytes = bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
if (bytes != local_auxesz) if (bytes != local_auxesz)
error ("%s: error reading symbols", current_objfile->name); error ("%s: error reading symbols", current_objfile->name);
bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass, bfd_coff_swap_aux_in (symfile_bfd, temp_aux,
sym->n_type, sym->n_sclass,
0, cs->c_naux, (char *) aux); 0, cs->c_naux, (char *) aux);
/* If more than one aux entry, read past it (only the first aux /* If more than one aux entry, read past it (only the first aux
is important). */ is important). */
@ -1193,7 +1223,7 @@ read_one_sym (struct coff_symbol *cs,
} }
} }
/* Support for string table handling */ /* Support for string table handling. */
static char *stringtab = NULL; static char *stringtab = NULL;
@ -1223,14 +1253,14 @@ init_stringtab (bfd *abfd, long offset)
return 0; return 0;
stringtab = (char *) xmalloc (length); stringtab = (char *) xmalloc (length);
/* This is in target format (probably not very useful, and not currently /* This is in target format (probably not very useful, and not
used), not host format. */ currently used), not host format. */
memcpy (stringtab, lengthbuf, sizeof lengthbuf); memcpy (stringtab, lengthbuf, sizeof lengthbuf);
if (length == sizeof length) /* Empty table -- just the count */ if (length == sizeof length) /* Empty table -- just the count. */
return 0; return 0;
val = bfd_bread (stringtab + sizeof lengthbuf, length - sizeof lengthbuf, val = bfd_bread (stringtab + sizeof lengthbuf,
abfd); length - sizeof lengthbuf, abfd);
if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0') if (val != length - sizeof lengthbuf || stringtab[length - 1] != '\0')
return -1; return -1;
@ -1272,9 +1302,9 @@ getsymname (struct internal_syment *symbol_entry)
return result; return result;
} }
/* Extract the file name from the aux entry of a C_FILE symbol. Return /* Extract the file name from the aux entry of a C_FILE symbol.
only the last component of the name. Result is in static storage and Return only the last component of the name. Result is in static
is only good for temporary use. */ storage and is only good for temporary use. */
static char * static char *
coff_getfilename (union internal_auxent *aux_entry) coff_getfilename (union internal_auxent *aux_entry)
@ -1326,14 +1356,14 @@ init_lineno (bfd *abfd, long offset, int size)
if (bfd_seek (abfd, offset, 0) < 0) if (bfd_seek (abfd, offset, 0) < 0)
return -1; return -1;
/* Allocate the desired table, plus a sentinel */ /* Allocate the desired table, plus a sentinel. */
linetab = (char *) xmalloc (size + local_linesz); linetab = (char *) xmalloc (size + local_linesz);
val = bfd_bread (linetab, size, abfd); val = bfd_bread (linetab, size, abfd);
if (val != size) if (val != size)
return -1; return -1;
/* Terminate it with an all-zero sentinel record */ /* Terminate it with an all-zero sentinel record. */
memset (linetab + size, 0, local_linesz); memset (linetab + size, 0, local_linesz);
return 0; return 0;
@ -1374,14 +1404,15 @@ enter_linenos (long file_offset, int first_line,
file_offset); file_offset);
if (file_offset > linetab_size) /* Too big to be an offset? */ if (file_offset > linetab_size) /* Too big to be an offset? */
return; return;
file_offset += linetab_offset; /* Try reading at that linetab offset */ file_offset += linetab_offset; /* Try reading at that linetab
offset. */
} }
rawptr = &linetab[file_offset - linetab_offset]; rawptr = &linetab[file_offset - linetab_offset];
/* skip first line entry for each function */ /* Skip first line entry for each function. */
rawptr += local_linesz; rawptr += local_linesz;
/* line numbers start at one for the first line of the function */ /* Line numbers start at one for the first line of the function. */
first_line--; first_line--;
/* If the line number table is full (e.g. 64K lines in COFF debug /* If the line number table is full (e.g. 64K lines in COFF debug
@ -1396,8 +1427,10 @@ enter_linenos (long file_offset, int first_line,
if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line) if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
{ {
CORE_ADDR addr = lptr.l_addr.l_paddr; CORE_ADDR addr = lptr.l_addr.l_paddr;
addr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); addr += ANOFFSET (objfile->section_offsets,
record_line (current_subfile, first_line + L_LNNO32 (&lptr), SECT_OFF_TEXT (objfile));
record_line (current_subfile,
first_line + L_LNNO32 (&lptr),
gdbarch_addr_bits_remove (gdbarch, addr)); gdbarch_addr_bits_remove (gdbarch, addr));
} }
else else
@ -1414,20 +1447,25 @@ patch_type (struct type *type, struct type *real_type)
TYPE_LENGTH (target) = TYPE_LENGTH (real_target); TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target); TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size); TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target,
field_size);
memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size); memcpy (TYPE_FIELDS (target),
TYPE_FIELDS (real_target),
field_size);
if (TYPE_NAME (real_target)) if (TYPE_NAME (real_target))
{ {
if (TYPE_NAME (target)) if (TYPE_NAME (target))
xfree (TYPE_NAME (target)); xfree (TYPE_NAME (target));
TYPE_NAME (target) = concat (TYPE_NAME (real_target), (char *)NULL); TYPE_NAME (target) = concat (TYPE_NAME (real_target),
(char *) NULL);
} }
} }
/* Patch up all appropriate typedef symbols in the opaque_type_chains /* Patch up all appropriate typedef symbols in the opaque_type_chains
so that they can be used to print out opaque data structures properly. */ so that they can be used to print out opaque data structures
properly. */
static void static void
patch_opaque_types (struct symtab *s) patch_opaque_types (struct symtab *s)
@ -1436,7 +1474,7 @@ patch_opaque_types (struct symtab *s)
struct dict_iterator iter; struct dict_iterator iter;
struct symbol *real_sym; struct symbol *real_sym;
/* Go through the per-file symbols only */ /* Go through the per-file symbols only. */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, real_sym) ALL_BLOCK_SYMBOLS (b, iter, real_sym)
{ {
@ -1522,9 +1560,11 @@ process_coff_symbol (struct coff_symbol *cs,
if (ISFCN (cs->c_type)) if (ISFCN (cs->c_type))
{ {
SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
SYMBOL_TYPE (sym) = SYMBOL_TYPE (sym) =
lookup_function_type (decode_function_type (cs, cs->c_type, aux, objfile)); lookup_function_type (decode_function_type (cs, cs->c_type,
aux, objfile));
SYMBOL_CLASS (sym) = LOC_BLOCK; SYMBOL_CLASS (sym) = LOC_BLOCK;
if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
@ -1552,7 +1592,8 @@ process_coff_symbol (struct coff_symbol *cs,
case C_EXT: case C_EXT:
SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
add_symbol_to_list (sym, &global_symbols); add_symbol_to_list (sym, &global_symbols);
break; break;
@ -1561,15 +1602,16 @@ process_coff_symbol (struct coff_symbol *cs,
case C_STAT: case C_STAT:
SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value; SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
if (within_function) if (within_function)
{ {
/* Static symbol of local scope */ /* Static symbol of local scope. */
add_symbol_to_list (sym, &local_symbols); add_symbol_to_list (sym, &local_symbols);
} }
else else
{ {
/* Static symbol at top level of file */ /* Static symbol at top level of file. */
add_symbol_to_list (sym, &file_symbols); add_symbol_to_list (sym, &file_symbols);
} }
break; break;
@ -1612,19 +1654,19 @@ process_coff_symbol (struct coff_symbol *cs,
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
|| TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC) || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
{ {
/* If we are giving a name to a type such as "pointer to /* If we are giving a name to a type such as
foo" or "function returning foo", we better not set "pointer to foo" or "function returning foo", we
the TYPE_NAME. If the program contains "typedef char better not set the TYPE_NAME. If the program
*caddr_t;", we don't want all variables of type char contains "typedef char *caddr_t;", we don't want
* to print as caddr_t. This is not just a all variables of type char * to print as caddr_t.
consequence of GDB's type management; CC and GCC (at This is not just a consequence of GDB's type
least through version 2.4) both output variables of management; CC and GCC (at least through version
either type char * or caddr_t with the type 2.4) both output variables of either type char *
refering to the C_TPDEF symbol for caddr_t. If a future or caddr_t with the type refering to the C_TPDEF
compiler cleans this up it GDB is not ready for it symbol for caddr_t. If a future compiler cleans
yet, but if it becomes ready we somehow need to this up it GDB is not ready for it yet, but if it
disable this check (without breaking the PCC/GCC2.4 becomes ready we somehow need to disable this
case). check (without breaking the PCC/GCC2.4 case).
Sigh. Sigh.
@ -1634,14 +1676,15 @@ process_coff_symbol (struct coff_symbol *cs,
} }
else else
TYPE_NAME (SYMBOL_TYPE (sym)) = TYPE_NAME (SYMBOL_TYPE (sym)) =
concat (SYMBOL_LINKAGE_NAME (sym), (char *)NULL); concat (SYMBOL_LINKAGE_NAME (sym), (char *) NULL);
} }
/* Keep track of any type which points to empty structured type, /* Keep track of any type which points to empty structured
so it can be filled from a definition from another file. A type, so it can be filled from a definition from another
simple forward reference (TYPE_CODE_UNDEF) is not an file. A simple forward reference (TYPE_CODE_UNDEF) is
empty structured type, though; the forward references not an empty structured type, though; the forward
work themselves out via the magic of coff_lookup_type. */ references work themselves out via the magic of
coff_lookup_type. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
&& TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0
&& TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) && TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym)))
@ -1710,11 +1753,11 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
struct type *base_type, *index_type, *range_type; struct type *base_type, *index_type, *range_type;
/* Define an array type. */ /* Define an array type. */
/* auxent refers to array, not base type */ /* auxent refers to array, not base type. */
if (aux->x_sym.x_tagndx.l == 0) if (aux->x_sym.x_tagndx.l == 0)
cs->c_naux = 0; cs->c_naux = 0;
/* shift the indices down */ /* Shift the indices down. */
dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0]; dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
i = 1; i = 1;
n = dim[0]; n = dim[0];
@ -1725,20 +1768,21 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
base_type = decode_type (cs, new_c_type, aux, objfile); base_type = decode_type (cs, new_c_type, aux, objfile);
index_type = objfile_type (objfile)->builtin_int; index_type = objfile_type (objfile)->builtin_int;
range_type = range_type =
create_range_type ((struct type *) NULL, index_type, 0, n - 1); create_range_type ((struct type *) NULL,
index_type, 0, n - 1);
type = type =
create_array_type ((struct type *) NULL, base_type, range_type); create_array_type ((struct type *) NULL,
base_type, range_type);
} }
return type; return type;
} }
/* Reference to existing type. This only occurs with the /* Reference to existing type. This only occurs with the struct,
struct, union, and enum types. EPI a29k coff union, and enum types. EPI a29k coff fakes us out by producing
fakes us out by producing aux entries with a nonzero aux entries with a nonzero x_tagndx for definitions of structs,
x_tagndx for definitions of structs, unions, and enums, so we unions, and enums, so we have to check the c_sclass field. SCO
have to check the c_sclass field. SCO 3.2v4 cc gets confused 3.2v4 cc gets confused with pointers to pointers to defined
with pointers to pointers to defined structs, and generates structs, and generates negative x_tagndx fields. */
negative x_tagndx fields. */
if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0) if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
{ {
if (cs->c_sclass != C_STRTAG if (cs->c_sclass != C_STRTAG
@ -1765,20 +1809,25 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
return the type that the function returns. */ return the type that the function returns. */
static struct type * static struct type *
decode_function_type (struct coff_symbol *cs, unsigned int c_type, decode_function_type (struct coff_symbol *cs,
union internal_auxent *aux, struct objfile *objfile) unsigned int c_type,
union internal_auxent *aux,
struct objfile *objfile)
{ {
if (aux->x_sym.x_tagndx.l == 0) if (aux->x_sym.x_tagndx.l == 0)
cs->c_naux = 0; /* auxent refers to function, not base type */ cs->c_naux = 0; /* auxent refers to function, not base
type. */
return decode_type (cs, DECREF (c_type), aux, objfile); return decode_type (cs, DECREF (c_type), aux, objfile);
} }
/* basic C types */ /* Basic C types. */
static struct type * static struct type *
decode_base_type (struct coff_symbol *cs, unsigned int c_type, decode_base_type (struct coff_symbol *cs,
union internal_auxent *aux, struct objfile *objfile) unsigned int c_type,
union internal_auxent *aux,
struct objfile *objfile)
{ {
struct gdbarch *gdbarch = get_objfile_arch (objfile); struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *type; struct type *type;
@ -1786,7 +1835,7 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
switch (c_type) switch (c_type)
{ {
case T_NULL: case T_NULL:
/* shows up with "void (*foo)();" structure members */ /* Shows up with "void (*foo)();" structure members. */
return objfile_type (objfile)->builtin_void; return objfile_type (objfile)->builtin_void;
#ifdef T_VOID #ifdef T_VOID
@ -1824,13 +1873,13 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
case T_STRUCT: case T_STRUCT:
if (cs->c_naux != 1) if (cs->c_naux != 1)
{ {
/* anonymous structure type */ /* Anonymous structure type. */
type = coff_alloc_type (cs->c_symnum); type = coff_alloc_type (cs->c_symnum);
TYPE_CODE (type) = TYPE_CODE_STRUCT; TYPE_CODE (type) = TYPE_CODE_STRUCT;
TYPE_NAME (type) = NULL; TYPE_NAME (type) = NULL;
/* This used to set the tag to "<opaque>". But I think setting it /* This used to set the tag to "<opaque>". But I think
to NULL is right, and the printing code can print it as setting it to NULL is right, and the printing code can
"struct {...}". */ print it as "struct {...}". */
TYPE_TAG_NAME (type) = NULL; TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC (type); INIT_CPLUS_SPECIFIC (type);
TYPE_LENGTH (type) = 0; TYPE_LENGTH (type) = 0;
@ -1849,12 +1898,12 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
case T_UNION: case T_UNION:
if (cs->c_naux != 1) if (cs->c_naux != 1)
{ {
/* anonymous union type */ /* Anonymous union type. */
type = coff_alloc_type (cs->c_symnum); type = coff_alloc_type (cs->c_symnum);
TYPE_NAME (type) = NULL; TYPE_NAME (type) = NULL;
/* This used to set the tag to "<opaque>". But I think setting it /* This used to set the tag to "<opaque>". But I think
to NULL is right, and the printing code can print it as setting it to NULL is right, and the printing code can
"union {...}". */ print it as "union {...}". */
TYPE_TAG_NAME (type) = NULL; TYPE_TAG_NAME (type) = NULL;
INIT_CPLUS_SPECIFIC (type); INIT_CPLUS_SPECIFIC (type);
TYPE_LENGTH (type) = 0; TYPE_LENGTH (type) = 0;
@ -1874,13 +1923,13 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
case T_ENUM: case T_ENUM:
if (cs->c_naux != 1) if (cs->c_naux != 1)
{ {
/* anonymous enum type */ /* Anonymous enum type. */
type = coff_alloc_type (cs->c_symnum); type = coff_alloc_type (cs->c_symnum);
TYPE_CODE (type) = TYPE_CODE_ENUM; TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_NAME (type) = NULL; TYPE_NAME (type) = NULL;
/* This used to set the tag to "<opaque>". But I think setting it /* This used to set the tag to "<opaque>". But I think
to NULL is right, and the printing code can print it as setting it to NULL is right, and the printing code can
"enum {...}". */ print it as "enum {...}". */
TYPE_TAG_NAME (type) = NULL; TYPE_TAG_NAME (type) = NULL;
TYPE_LENGTH (type) = 0; TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0; TYPE_FIELDS (type) = 0;
@ -1896,7 +1945,7 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
return type; return type;
case T_MOE: case T_MOE:
/* shouldn't show up here */ /* Shouldn't show up here. */
break; break;
case T_UCHAR: case T_UCHAR:
@ -1916,7 +1965,8 @@ decode_base_type (struct coff_symbol *cs, unsigned int c_type,
else else
return objfile_type (objfile)->builtin_unsigned_long; return objfile_type (objfile)->builtin_unsigned_long;
} }
complaint (&symfile_complaints, _("Unexpected type for symbol %s"), cs->c_name); complaint (&symfile_complaints,
_("Unexpected type for symbol %s"), cs->c_name);
return objfile_type (objfile)->builtin_void; return objfile_type (objfile)->builtin_void;
} }
@ -1969,10 +2019,10 @@ coff_read_struct_type (int index, int length, int lastsym,
list = new; list = new;
/* Save the data. */ /* Save the data. */
list->field.name = list->field.name = obsavestring (name, strlen (name),
obsavestring (name, strlen (name), &objfile->objfile_obstack); &objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux, FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
objfile); &sub_aux, objfile);
SET_FIELD_BITPOS (list->field, 8 * ms->c_value); SET_FIELD_BITPOS (list->field, 8 * ms->c_value);
FIELD_BITSIZE (list->field) = 0; FIELD_BITSIZE (list->field) = 0;
nfields++; nfields++;
@ -1986,10 +2036,10 @@ coff_read_struct_type (int index, int length, int lastsym,
list = new; list = new;
/* Save the data. */ /* Save the data. */
list->field.name = list->field.name = obsavestring (name, strlen (name),
obsavestring (name, strlen (name), &objfile->objfile_obstack); &objfile->objfile_obstack);
FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux, FIELD_TYPE (list->field) = decode_type (ms, ms->c_type,
objfile); &sub_aux, objfile);
SET_FIELD_BITPOS (list->field, ms->c_value); SET_FIELD_BITPOS (list->field, ms->c_value);
FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size; FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
nfields++; nfields++;
@ -2129,15 +2179,22 @@ coff_read_enum_type (int index, int length, int lastsym,
static const struct sym_fns coff_sym_fns = static const struct sym_fns coff_sym_fns =
{ {
bfd_target_coff_flavour, bfd_target_coff_flavour,
coff_new_init, /* sym_new_init: init anything gbl to entire symtab */ coff_new_init, /* sym_new_init: init anything gbl to
coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */ entire symtab */
coff_symfile_read, /* sym_read: read a symbol file into symtab */ coff_symfile_init, /* sym_init: read initial info, setup
coff_symfile_finish, /* sym_finish: finished with file, cleanup */ for sym_read() */
default_symfile_offsets, /* sym_offsets: xlate external to internal form */ coff_symfile_read, /* sym_read: read a symbol file into
default_symfile_segments, /* sym_segments: Get segment information from symtab */
a file. */ coff_symfile_finish, /* sym_finish: finished with file,
cleanup */
default_symfile_offsets, /* sym_offsets: xlate external to
internal form */
default_symfile_segments, /* sym_segments: Get segment
information from a file */
NULL, /* sym_read_linetable */ NULL, /* sym_read_linetable */
default_symfile_relocate, /* sym_relocate: Relocate a debug section. */
default_symfile_relocate, /* sym_relocate: Relocate a debug
section. */
&psym_functions &psym_functions
}; };

View file

@ -19,8 +19,9 @@
#if !defined (COMMAND_H) #if !defined (COMMAND_H)
#define COMMAND_H 1 #define COMMAND_H 1
/* Command classes are top-level categories into which commands are broken /* Command classes are top-level categories into which commands are
down for "help" purposes. broken down for "help" purposes.
Notes on classes: class_alias is for alias commands which are not Notes on classes: class_alias is for alias commands which are not
abbreviations of the original command. class-pseudo is for abbreviations of the original command. class-pseudo is for
commands which are not really commands nor help topics ("stop"). */ commands which are not really commands nor help topics ("stop"). */
@ -30,8 +31,8 @@ enum command_class
/* Special args to help_list */ /* Special args to help_list */
class_deprecated = -3, all_classes = -2, all_commands = -1, class_deprecated = -3, all_classes = -2, all_commands = -1,
/* Classes of commands */ /* Classes of commands */
no_class = -1, class_run = 0, class_vars, class_stack, no_class = -1, class_run = 0, class_vars, class_stack, class_files,
class_files, class_support, class_info, class_breakpoint, class_trace, class_support, class_info, class_breakpoint, class_trace,
class_alias, class_bookmark, class_obscure, class_maintenance, class_alias, class_bookmark, class_obscure, class_maintenance,
class_pseudo, class_tui, class_user, class_xdb class_pseudo, class_tui, class_user, class_xdb
}; };
@ -63,16 +64,17 @@ typedef enum var_types
value. */ value. */
var_auto_boolean, var_auto_boolean,
/* Unsigned Integer. *VAR is an unsigned int. The user can type 0 /* Unsigned Integer. *VAR is an unsigned int. The user can type
to mean "unlimited", which is stored in *VAR as UINT_MAX. */ 0 to mean "unlimited", which is stored in *VAR as UINT_MAX. */
var_uinteger, var_uinteger,
/* Like var_uinteger but signed. *VAR is an int. The user can type 0 /* Like var_uinteger but signed. *VAR is an int. The user can
to mean "unlimited", which is stored in *VAR as INT_MAX. */ type 0 to mean "unlimited", which is stored in *VAR as
INT_MAX. */
var_integer, var_integer,
/* String which the user enters with escapes (e.g. the user types \n and /* String which the user enters with escapes (e.g. the user types
it is a real newline in the stored string). \n and it is a real newline in the stored string).
*VAR is a malloc'd string, or NULL if the string is empty. */ *VAR is a malloc'd string, or NULL if the string is empty. */
var_string, var_string,
/* String which stores what the user types verbatim. /* String which stores what the user types verbatim.
@ -90,8 +92,9 @@ typedef enum var_types
/* ZeroableUnsignedInteger. *VAR is an unsigned int. Zero really /* ZeroableUnsignedInteger. *VAR is an unsigned int. Zero really
means zero. */ means zero. */
var_zuinteger, var_zuinteger,
/* Enumerated type. Can only have one of the specified values. *VAR is a /* Enumerated type. Can only have one of the specified values.
char pointer to the name of the element that we find. */ *VAR is a char pointer to the name of the element that we
find. */
var_enum var_enum
} }
var_types; var_types;
@ -147,7 +150,8 @@ extern int cmd_cfunc_eq (struct cmd_list_element *cmd,
void (*cfunc) (char *args, int from_tty)); void (*cfunc) (char *args, int from_tty));
/* Each command object has a local context attached to it. */ /* Each command object has a local context attached to it. */
extern void set_cmd_context (struct cmd_list_element *cmd, void *context); extern void set_cmd_context (struct cmd_list_element *cmd,
void *context);
extern void *get_cmd_context (struct cmd_list_element *cmd); extern void *get_cmd_context (struct cmd_list_element *cmd);
@ -170,39 +174,42 @@ extern struct cmd_list_element *lookup_cmd_1 (char **,
struct cmd_list_element **, struct cmd_list_element **,
int); int);
extern struct cmd_list_element * extern struct cmd_list_element *deprecate_cmd (struct cmd_list_element *,
deprecate_cmd (struct cmd_list_element *, char * ); char * );
extern void extern void deprecated_cmd_warning (char **);
deprecated_cmd_warning (char **);
extern int extern int lookup_cmd_composition (char *text,
lookup_cmd_composition (char *text,
struct cmd_list_element **alias, struct cmd_list_element **alias,
struct cmd_list_element **prefix_cmd, struct cmd_list_element **prefix_cmd,
struct cmd_list_element **cmd); struct cmd_list_element **cmd);
extern struct cmd_list_element *add_com (char *, enum command_class, extern struct cmd_list_element *add_com (char *, enum command_class,
void (*fun) (char *, int), char *); void (*fun) (char *, int),
char *);
extern struct cmd_list_element *add_com_alias (char *, char *, extern struct cmd_list_element *add_com_alias (char *, char *,
enum command_class, int); enum command_class, int);
extern struct cmd_list_element *add_info (char *, void (*fun) (char *, int), extern struct cmd_list_element *add_info (char *,
void (*fun) (char *, int),
char *); char *);
extern struct cmd_list_element *add_info_alias (char *, char *, int); extern struct cmd_list_element *add_info_alias (char *, char *, int);
extern char **complete_on_cmdlist (struct cmd_list_element *, char *, char *); extern char **complete_on_cmdlist (struct cmd_list_element *,
char *, char *);
extern char **complete_on_enum (const char *enumlist[], char *, char *); extern char **complete_on_enum (const char *enumlist[],
char *, char *);
extern void help_cmd (char *, struct ui_file *); extern void help_cmd (char *, struct ui_file *);
extern void help_list (struct cmd_list_element *, char *, extern void help_list (struct cmd_list_element *, char *,
enum command_class, struct ui_file *); enum command_class, struct ui_file *);
extern void help_cmd_list (struct cmd_list_element *, enum command_class, extern void help_cmd_list (struct cmd_list_element *,
enum command_class,
char *, int, struct ui_file *); char *, int, struct ui_file *);
/* Method for show a set/show variable's VALUE on FILE. If this /* Method for show a set/show variable's VALUE on FILE. If this
@ -354,10 +361,11 @@ extern void dont_repeat (void);
extern void not_just_help_class_command (char *, int); extern void not_just_help_class_command (char *, int);
/* check function pointer */ /* Check function pointer. */
extern int cmd_func_p (struct cmd_list_element *cmd); extern int cmd_func_p (struct cmd_list_element *cmd);
/* call the command function */ /* Call the command function. */
extern void cmd_func (struct cmd_list_element *cmd, char *args, int from_tty); extern void cmd_func (struct cmd_list_element *cmd,
char *args, int from_tty);
#endif /* !defined (COMMAND_H) */ #endif /* !defined (COMMAND_H) */

View file

@ -26,8 +26,8 @@
extern void _initialize_complaints (void); extern void _initialize_complaints (void);
/* Should each complaint message be self explanatory, or should we assume that /* Should each complaint message be self explanatory, or should we
a series of complaints is being produced? */ assume that a series of complaints is being produced? */
/* case 1: First message of a series that must /* case 1: First message of a series that must
start off with explanation. case 2: Subsequent message of a series start off with explanation. case 2: Subsequent message of a series
@ -165,11 +165,13 @@ static int stop_whining = 0;
later handling. */ later handling. */
static void ATTRIBUTE_PRINTF (4, 0) static void ATTRIBUTE_PRINTF (4, 0)
vcomplaint (struct complaints **c, const char *file, int line, const char *fmt, vcomplaint (struct complaints **c, const char *file,
int line, const char *fmt,
va_list args) va_list args)
{ {
struct complaints *complaints = get_complaints (c); struct complaints *complaints = get_complaints (c);
struct complain *complaint = find_complaint (complaints, file, line, fmt); struct complain *complaint = find_complaint (complaints, file,
line, fmt);
enum complaint_series series; enum complaint_series series;
gdb_assert (complaints != NULL); gdb_assert (complaints != NULL);
@ -184,7 +186,8 @@ vcomplaint (struct complaints **c, const char *file, int line, const char *fmt,
series = complaints->series; series = complaints->series;
if (complaint->file != NULL) if (complaint->file != NULL)
internal_vwarning (complaint->file, complaint->line, complaint->fmt, args); internal_vwarning (complaint->file, complaint->line,
complaint->fmt, args);
else if (deprecated_warning_hook) else if (deprecated_warning_hook)
(*deprecated_warning_hook) (complaint->fmt, args); (*deprecated_warning_hook) (complaint->fmt, args);
else else
@ -294,7 +297,8 @@ clear_complaints (struct complaints **c, int less_verbose, int noisy)
case SUBSEQUENT_MESSAGE: case SUBSEQUENT_MESSAGE:
/* It would be really nice to use begin_line() here. /* It would be really nice to use begin_line() here.
Unfortunately that function doesn't track GDB_STDERR and Unfortunately that function doesn't track GDB_STDERR and
consequently will sometimes supress a line when it shouldn't. */ consequently will sometimes supress a line when it
shouldn't. */
fputs_unfiltered ("\n", gdb_stderr); fputs_unfiltered ("\n", gdb_stderr);
break; break;
default: default:
@ -321,7 +325,8 @@ complaints_show_value (struct ui_file *file, int from_tty,
void void
_initialize_complaints (void) _initialize_complaints (void)
{ {
add_setshow_zinteger_cmd ("complaints", class_support, &stop_whining, _("\ add_setshow_zinteger_cmd ("complaints", class_support,
&stop_whining, _("\
Set max number of complaints about incorrect symbols."), _("\ Set max number of complaints about incorrect symbols."), _("\
Show max number of complaints about incorrect symbols."), NULL, Show max number of complaints about incorrect symbols."), NULL,
NULL, complaints_show_value, NULL, complaints_show_value,

View file

@ -30,10 +30,12 @@ struct complaints;
extern struct complaints *symfile_complaints; extern struct complaints *symfile_complaints;
/* Register a complaint. */ /* Register a complaint. */
extern void complaint (struct complaints **complaints, const char *fmt, extern void complaint (struct complaints **complaints,
const char *fmt,
...) ATTRIBUTE_PRINTF (2, 3); ...) ATTRIBUTE_PRINTF (2, 3);
extern void internal_complaint (struct complaints **complaints, extern void internal_complaint (struct complaints **complaints,
const char *file, int line, const char *fmt, const char *file, int line,
const char *fmt,
...) ATTRIBUTE_PRINTF (4, 5); ...) ATTRIBUTE_PRINTF (4, 5);
/* Clear out / initialize all complaint counters that have ever been /* Clear out / initialize all complaint counters that have ever been

View file

@ -50,21 +50,22 @@ char *line_completion_function (const char *text, int matches,
/* readline uses the word breaks for two things: /* readline uses the word breaks for two things:
(1) In figuring out where to point the TEXT parameter to the (1) In figuring out where to point the TEXT parameter to the
rl_completion_entry_function. Since we don't use TEXT for much, rl_completion_entry_function. Since we don't use TEXT for much,
it doesn't matter a lot what the word breaks are for this purpose, but it doesn't matter a lot what the word breaks are for this purpose,
it does affect how much stuff M-? lists. but it does affect how much stuff M-? lists.
(2) If one of the matches contains a word break character, readline (2) If one of the matches contains a word break character, readline
will quote it. That's why we switch between will quote it. That's why we switch between
current_language->la_word_break_characters() and current_language->la_word_break_characters() and
gdb_completer_command_word_break_characters. I'm not sure when gdb_completer_command_word_break_characters. I'm not sure when
we need this behavior (perhaps for funky characters in C++ symbols?). */ we need this behavior (perhaps for funky characters in C++
symbols?). */
/* Variables which are necessary for fancy command line editing. */ /* Variables which are necessary for fancy command line editing. */
/* When completing on command names, we remove '-' from the list of /* When completing on command names, we remove '-' from the list of
word break characters, since we use it in command names. If the word break characters, since we use it in command names. If the
readline library sees one in any of the current completion strings, readline library sees one in any of the current completion strings,
it thinks that the string needs to be quoted and automatically supplies it thinks that the string needs to be quoted and automatically
a leading quote. */ supplies a leading quote. */
static char *gdb_completer_command_word_break_characters = static char *gdb_completer_command_word_break_characters =
" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,"; " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,";
@ -80,9 +81,9 @@ static char *gdb_completer_file_name_break_characters = " \t\n*|\"';?><@";
static char *gdb_completer_file_name_break_characters = " \t\n*|\"';:?><"; static char *gdb_completer_file_name_break_characters = " \t\n*|\"';:?><";
#endif #endif
/* Characters that can be used to quote completion strings. Note that we /* Characters that can be used to quote completion strings. Note that
can't include '"' because the gdb C parser treats such quoted sequences we can't include '"' because the gdb C parser treats such quoted
as strings. */ sequences as strings. */
static char *gdb_completer_quote_characters = "'"; static char *gdb_completer_quote_characters = "'";
/* Accessor for some completer data that may interest other files. */ /* Accessor for some completer data that may interest other files. */
@ -98,20 +99,23 @@ get_gdb_completer_quote_characters (void)
char * char *
readline_line_completion_function (const char *text, int matches) readline_line_completion_function (const char *text, int matches)
{ {
return line_completion_function (text, matches, rl_line_buffer, rl_point); return line_completion_function (text, matches,
rl_line_buffer, rl_point);
} }
/* This can be used for functions which don't want to complete on symbols /* This can be used for functions which don't want to complete on
but don't want to complete on anything else either. */ symbols but don't want to complete on anything else either. */
char ** char **
noop_completer (struct cmd_list_element *ignore, char *text, char *prefix) noop_completer (struct cmd_list_element *ignore,
char *text, char *prefix)
{ {
return NULL; return NULL;
} }
/* Complete on filenames. */ /* Complete on filenames. */
char ** char **
filename_completer (struct cmd_list_element *ignore, char *text, char *word) filename_completer (struct cmd_list_element *ignore,
char *text, char *word)
{ {
int subsequent_name; int subsequent_name;
char **return_val; char **return_val;
@ -142,12 +146,12 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
break; break;
} }
/* We need to set subsequent_name to a non-zero value before the /* We need to set subsequent_name to a non-zero value before the
continue line below, because otherwise, if the first file seen continue line below, because otherwise, if the first file
by GDB is a backup file whose name ends in a `~', we will loop seen by GDB is a backup file whose name ends in a `~', we
indefinitely. */ will loop indefinitely. */
subsequent_name = 1; subsequent_name = 1;
/* Like emacs, don't complete on old versions. Especially useful /* Like emacs, don't complete on old versions. Especially
in the "source" command. */ useful in the "source" command. */
if (p[strlen (p) - 1] == '~') if (p[strlen (p) - 1] == '~')
{ {
xfree (p); xfree (p);
@ -177,9 +181,9 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
} }
} }
#if 0 #if 0
/* There is no way to do this just long enough to affect quote inserting /* There is no way to do this just long enough to affect quote
without also affecting the next completion. This should be fixed in inserting without also affecting the next completion. This
readline. FIXME. */ should be fixed in readline. FIXME. */
/* Ensure that readline does the right thing /* Ensure that readline does the right thing
with respect to inserting quotes. */ with respect to inserting quotes. */
rl_completer_word_break_characters = ""; rl_completer_word_break_characters = "";
@ -193,9 +197,12 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
or or
symbol+offset symbol+offset
This is intended to be used in commands that set breakpoints etc. */ This is intended to be used in commands that set breakpoints
etc. */
char ** char **
location_completer (struct cmd_list_element *ignore, char *text, char *word) location_completer (struct cmd_list_element *ignore,
char *text, char *word)
{ {
int n_syms = 0, n_files = 0; int n_syms = 0, n_files = 0;
char ** fn_list = NULL; char ** fn_list = NULL;
@ -386,13 +393,14 @@ add_struct_fields (struct type *type, int *nextp, char **output,
for (i = 0; i < TYPE_NFIELDS (type); ++i) for (i = 0; i < TYPE_NFIELDS (type); ++i)
{ {
if (i < TYPE_N_BASECLASSES (type)) if (i < TYPE_N_BASECLASSES (type))
add_struct_fields (TYPE_BASECLASS (type, i), nextp, output, add_struct_fields (TYPE_BASECLASS (type, i), nextp,
fieldname, namelen); output, fieldname, namelen);
else if (TYPE_FIELD_NAME (type, i)) else if (TYPE_FIELD_NAME (type, i))
{ {
if (TYPE_FIELD_NAME (type, i)[0] != '\0') if (TYPE_FIELD_NAME (type, i)[0] != '\0')
{ {
if (! strncmp (TYPE_FIELD_NAME (type, i), fieldname, namelen)) if (! strncmp (TYPE_FIELD_NAME (type, i),
fieldname, namelen))
{ {
output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i)); output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i));
++*nextp; ++*nextp;
@ -401,8 +409,8 @@ add_struct_fields (struct type *type, int *nextp, char **output,
else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION) else if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION)
{ {
/* Recurse into anonymous unions. */ /* Recurse into anonymous unions. */
add_struct_fields (TYPE_FIELD_TYPE (type, i), nextp, output, add_struct_fields (TYPE_FIELD_TYPE (type, i), nextp,
fieldname, namelen); output, fieldname, namelen);
} }
} }
} }
@ -432,7 +440,8 @@ add_struct_fields (struct type *type, int *nextp, char **output,
names, but some language parsers also have support for completing names, but some language parsers also have support for completing
field names. */ field names. */
char ** char **
expression_completer (struct cmd_list_element *ignore, char *text, char *word) expression_completer (struct cmd_list_element *ignore,
char *text, char *word)
{ {
struct type *type = NULL; struct type *type = NULL;
char *fieldname, *p; char *fieldname, *p;
@ -485,8 +494,9 @@ expression_completer (struct cmd_list_element *ignore, char *text, char *word)
return location_completer (ignore, p, word); return location_completer (ignore, p, word);
} }
/* Here are some useful test cases for completion. FIXME: These should /* Here are some useful test cases for completion. FIXME: These
be put in the test suite. They should be tested with both M-? and TAB. should be put in the test suite. They should be tested with both
M-? and TAB.
"show output-" "radix" "show output-" "radix"
"show output" "-radix" "show output" "-radix"
@ -521,18 +531,18 @@ complete_line_internal_reason;
TEXT is the caller's idea of the "word" we are looking at. TEXT is the caller's idea of the "word" we are looking at.
LINE_BUFFER is available to be looked at; it contains the entire text LINE_BUFFER is available to be looked at; it contains the entire
of the line. POINT is the offset in that line of the cursor. You text of the line. POINT is the offset in that line of the cursor.
should pretend that the line ends at POINT. You should pretend that the line ends at POINT.
REASON is of type complete_line_internal_reason. REASON is of type complete_line_internal_reason.
If REASON is handle_brkchars: If REASON is handle_brkchars:
Preliminary phase, called by gdb_completion_word_break_characters function, Preliminary phase, called by gdb_completion_word_break_characters
is used to determine the correct set of chars that are word delimiters function, is used to determine the correct set of chars that are
depending on the current command in line_buffer. word delimiters depending on the current command in line_buffer.
No completion list should be generated; the return value should be NULL. No completion list should be generated; the return value should be
This is checked by an assertion in that function. NULL. This is checked by an assertion in that function.
If REASON is handle_completions: If REASON is handle_completions:
Main phase, called by complete_line function, is used to get the list Main phase, called by complete_line function, is used to get the list
@ -544,7 +554,8 @@ complete_line_internal_reason;
*/ */
static char ** static char **
complete_line_internal (const char *text, char *line_buffer, int point, complete_line_internal (const char *text,
char *line_buffer, int point,
complete_line_internal_reason reason) complete_line_internal_reason reason)
{ {
char **list = NULL; char **list = NULL;
@ -553,16 +564,18 @@ complete_line_internal (const char *text, char *line_buffer, int point,
char *word; char *word;
struct cmd_list_element *c, *result_list; struct cmd_list_element *c, *result_list;
/* Choose the default set of word break characters to break completions. /* Choose the default set of word break characters to break
If we later find out that we are doing completions on command strings completions. If we later find out that we are doing completions
(as opposed to strings supplied by the individual command completer on command strings (as opposed to strings supplied by the
functions, which can be any string) then we will switch to the individual command completer functions, which can be any string)
special word break set for command strings, which leaves out the then we will switch to the special word break set for command
'-' character used in some commands. */ strings, which leaves out the '-' character used in some
commands. */
rl_completer_word_break_characters = rl_completer_word_break_characters =
current_language->la_word_break_characters(); current_language->la_word_break_characters();
/* Decide whether to complete on a list of gdb commands or on symbols. */ /* Decide whether to complete on a list of gdb commands or on
symbols. */
tmp_command = (char *) alloca (point + 1); tmp_command = (char *) alloca (point + 1);
p = tmp_command; p = tmp_command;
@ -642,12 +655,13 @@ complete_line_internal (const char *text, char *line_buffer, int point,
if (p == tmp_command + point) if (p == tmp_command + point)
{ {
/* There is no non-whitespace in the line beyond the command. */ /* There is no non-whitespace in the line beyond the
command. */
if (p[-1] == ' ' || p[-1] == '\t') if (p[-1] == ' ' || p[-1] == '\t')
{ {
/* The command is followed by whitespace; we need to complete /* The command is followed by whitespace; we need to
on whatever comes after command. */ complete on whatever comes after command. */
if (c->prefixlist) if (c->prefixlist)
{ {
/* It is a prefix command; what comes after it is /* It is a prefix command; what comes after it is
@ -708,7 +722,7 @@ complete_line_internal (const char *text, char *line_buffer, int point,
else else
{ {
/* The command is not followed by whitespace; we need to /* The command is not followed by whitespace; we need to
complete on the command itself. e.g. "p" which is a complete on the command itself, e.g. "p" which is a
command itself but also can complete to "print", "ptype" command itself but also can complete to "print", "ptype"
etc. */ etc. */
char *q; char *q;
@ -758,7 +772,8 @@ complete_line_internal (const char *text, char *line_buffer, int point,
of file-name completion. */ of file-name completion. */
for (p = word; for (p = word;
p > tmp_command p > tmp_command
&& strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL; && strchr (gdb_completer_file_name_break_characters,
p[-1]) == NULL;
p--) p--)
; ;
rl_completer_word_break_characters = rl_completer_word_break_characters =
@ -786,8 +801,8 @@ complete_line_internal (const char *text, char *line_buffer, int point,
TEXT is the caller's idea of the "word" we are looking at. TEXT is the caller's idea of the "word" we are looking at.
LINE_BUFFER is available to be looked at; it contains the entire text LINE_BUFFER is available to be looked at; it contains the entire
of the line. text of the line.
POINT is the offset in that line of the cursor. You POINT is the offset in that line of the cursor. You
should pretend that the line ends at POINT. */ should pretend that the line ends at POINT. */
@ -795,14 +810,17 @@ complete_line_internal (const char *text, char *line_buffer, int point,
char ** char **
complete_line (const char *text, char *line_buffer, int point) complete_line (const char *text, char *line_buffer, int point)
{ {
return complete_line_internal (text, line_buffer, point, handle_completions); return complete_line_internal (text, line_buffer,
point, handle_completions);
} }
/* Complete on command names. Used by "help". */ /* Complete on command names. Used by "help". */
char ** char **
command_completer (struct cmd_list_element *ignore, char *text, char *word) command_completer (struct cmd_list_element *ignore,
char *text, char *word)
{ {
return complete_line_internal (word, text, strlen (text), handle_help); return complete_line_internal (word, text,
strlen (text), handle_help);
} }
/* Get the list of chars that are considered as word breaks /* Get the list of chars that are considered as word breaks
@ -819,26 +837,26 @@ gdb_completion_word_break_characters (void)
return rl_completer_word_break_characters; return rl_completer_word_break_characters;
} }
/* Generate completions one by one for the completer. Each time we are /* Generate completions one by one for the completer. Each time we
called return another potential completion to the caller. are called return another potential completion to the caller.
line_completion just completes on commands or passes the buck to the line_completion just completes on commands or passes the buck to
command's completer function, the stuff specific to symbol completion the command's completer function, the stuff specific to symbol
is in make_symbol_completion_list. completion is in make_symbol_completion_list.
TEXT is the caller's idea of the "word" we are looking at. TEXT is the caller's idea of the "word" we are looking at.
MATCHES is the number of matches that have currently been collected from MATCHES is the number of matches that have currently been collected
calling this completion function. When zero, then we need to initialize, from calling this completion function. When zero, then we need to
otherwise the initialization has already taken place and we can just initialize, otherwise the initialization has already taken place
return the next potential completion string. and we can just return the next potential completion string.
LINE_BUFFER is available to be looked at; it contains the entire text LINE_BUFFER is available to be looked at; it contains the entire
of the line. POINT is the offset in that line of the cursor. You text of the line. POINT is the offset in that line of the cursor.
should pretend that the line ends at POINT. You should pretend that the line ends at POINT.
Returns NULL if there are no more completions, else a pointer to a string Returns NULL if there are no more completions, else a pointer to a
which is a possible completion, it is the caller's responsibility to string which is a possible completion, it is the caller's
free the string. */ responsibility to free the string. */
static char * static char *
line_completion_function (const char *text, int matches, line_completion_function (const char *text, int matches,
@ -850,15 +868,16 @@ line_completion_function (const char *text, int matches,
if (matches == 0) if (matches == 0)
{ {
/* The caller is beginning to accumulate a new set of completions, so /* The caller is beginning to accumulate a new set of
we need to find all of them now, and cache them for returning one at completions, so we need to find all of them now, and cache
a time on future calls. */ them for returning one at a time on future calls. */
if (list) if (list)
{ {
/* Free the storage used by LIST, but not by the strings inside. /* Free the storage used by LIST, but not by the strings
This is because rl_complete_internal () frees the strings. inside. This is because rl_complete_internal () frees
As complete_line may abort by calling `error' clear LIST now. */ the strings. As complete_line may abort by calling
`error' clear LIST now. */
xfree (list); xfree (list);
list = NULL; list = NULL;
} }
@ -866,11 +885,11 @@ line_completion_function (const char *text, int matches,
list = complete_line (text, line_buffer, point); list = complete_line (text, line_buffer, point);
} }
/* If we found a list of potential completions during initialization then /* If we found a list of potential completions during initialization
dole them out one at a time. The vector of completions is NULL then dole them out one at a time. The vector of completions is
terminated, so after returning the last one, return NULL (and continue NULL terminated, so after returning the last one, return NULL
to do so) each time we are called after that, until a new list is (and continue to do so) each time we are called after that, until
available. */ a new list is available. */
if (list) if (list)
{ {
@ -885,8 +904,8 @@ line_completion_function (const char *text, int matches,
/* Can't do this because readline hasn't yet checked the word breaks /* Can't do this because readline hasn't yet checked the word breaks
for figuring out whether to insert a quote. */ for figuring out whether to insert a quote. */
if (output == NULL) if (output == NULL)
/* Make sure the word break characters are set back to normal for the /* Make sure the word break characters are set back to normal for
next time that readline tries to complete something. */ the next time that readline tries to complete something. */
rl_completer_word_break_characters = rl_completer_word_break_characters =
current_language->la_word_break_characters(); current_language->la_word_break_characters();
#endif #endif

View file

@ -17,19 +17,27 @@
#if !defined (COMPLETER_H) #if !defined (COMPLETER_H)
#define COMPLETER_H 1 #define COMPLETER_H 1
extern char **complete_line (const char *text, char *line_buffer, int point); extern char **complete_line (const char *text,
char *line_buffer,
int point);
extern char *readline_line_completion_function (const char *text, int matches); extern char *readline_line_completion_function (const char *text,
int matches);
extern char **noop_completer (struct cmd_list_element *, char *, char *); extern char **noop_completer (struct cmd_list_element *,
char *, char *);
extern char **filename_completer (struct cmd_list_element *, char *, char *); extern char **filename_completer (struct cmd_list_element *,
char *, char *);
extern char **expression_completer (struct cmd_list_element *, char *, char *); extern char **expression_completer (struct cmd_list_element *,
char *, char *);
extern char **location_completer (struct cmd_list_element *, char *, char *); extern char **location_completer (struct cmd_list_element *,
char *, char *);
extern char **command_completer (struct cmd_list_element *, char *, char *); extern char **command_completer (struct cmd_list_element *,
char *, char *);
extern char *get_gdb_completer_quote_characters (void); extern char *get_gdb_completer_quote_characters (void);

View file

@ -1,7 +1,7 @@
/* Machine independent GDB support for core files on systems using "regsets". /* Machine independent GDB support for core files on systems using "regsets".
Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003, 2007, 2008, Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003, 2007,
2009, 2010 Free Software Foundation, Inc. 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GDB. This file is part of GDB.
@ -59,7 +59,9 @@
static void static void
fetch_core_registers (struct regcache *regcache, fetch_core_registers (struct regcache *regcache,
char *core_reg_sect, unsigned core_reg_size, int which, char *core_reg_sect,
unsigned core_reg_size,
int which,
CORE_ADDR reg_addr) CORE_ADDR reg_addr)
{ {
gdb_gregset_t gregset; gdb_gregset_t gregset;
@ -86,7 +88,8 @@ fetch_core_registers (struct regcache *regcache,
{ {
memcpy (&fpregset, core_reg_sect, sizeof (fpregset)); memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) >= 0) if (gdbarch_fp0_regnum (get_regcache_arch (regcache)) >= 0)
supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p); supply_fpregset (regcache,
(const gdb_fpregset_t *) fpregset_p);
} }
break; break;

View file

@ -52,9 +52,10 @@ static void call_extra_exec_file_hooks (char *filename);
typedef void (*hook_type) (char *); typedef void (*hook_type) (char *);
hook_type deprecated_exec_file_display_hook; /* the original hook */ hook_type deprecated_exec_file_display_hook; /* The original hook. */
static hook_type *exec_file_extra_hooks; /* array of additional hooks */ static hook_type *exec_file_extra_hooks; /* Array of additional
static int exec_file_hook_count = 0; /* size of array */ hooks. */
static int exec_file_hook_count = 0; /* Size of array. */
/* Binary file diddling handle for the core file. */ /* Binary file diddling handle for the core file. */
@ -106,11 +107,13 @@ specify_exec_file_hook (void (*hook) (char *))
if (deprecated_exec_file_display_hook != NULL) if (deprecated_exec_file_display_hook != NULL)
{ {
/* There's already a hook installed. Arrange to have both it /* There's already a hook installed. Arrange to have both it
* and the subsequent hooks called. */ and the subsequent hooks called. */
if (exec_file_hook_count == 0) if (exec_file_hook_count == 0)
{ {
/* If this is the first extra hook, initialize the hook array. */ /* If this is the first extra hook, initialize the hook
exec_file_extra_hooks = (hook_type *) xmalloc (sizeof (hook_type)); array. */
exec_file_extra_hooks = (hook_type *)
xmalloc (sizeof (hook_type));
exec_file_extra_hooks[0] = deprecated_exec_file_display_hook; exec_file_extra_hooks[0] = deprecated_exec_file_display_hook;
deprecated_exec_file_display_hook = call_extra_exec_file_hooks; deprecated_exec_file_display_hook = call_extra_exec_file_hooks;
exec_file_hook_count = 1; exec_file_hook_count = 1;
@ -120,8 +123,8 @@ specify_exec_file_hook (void (*hook) (char *))
Yes, it's inefficient to grow it by one each time but since Yes, it's inefficient to grow it by one each time but since
this is hardly ever called it's not a big deal. */ this is hardly ever called it's not a big deal. */
exec_file_hook_count++; exec_file_hook_count++;
new_array = new_array = (hook_type *)
(hook_type *) xrealloc (exec_file_extra_hooks, xrealloc (exec_file_extra_hooks,
exec_file_hook_count * sizeof (hook_type)); exec_file_hook_count * sizeof (hook_type));
exec_file_extra_hooks = new_array; exec_file_extra_hooks = new_array;
exec_file_extra_hooks[exec_file_hook_count - 1] = hook; exec_file_extra_hooks[exec_file_hook_count - 1] = hook;
@ -274,7 +277,8 @@ struct captured_read_memory_integer_arguments
static int static int
do_captured_read_memory_integer (void *data) do_captured_read_memory_integer (void *data)
{ {
struct captured_read_memory_integer_arguments *args = (struct captured_read_memory_integer_arguments*) data; struct captured_read_memory_integer_arguments *args
= (struct captured_read_memory_integer_arguments*) data;
CORE_ADDR memaddr = args->memaddr; CORE_ADDR memaddr = args->memaddr;
int len = args->len; int len = args->len;
enum bfd_endian byte_order = args->byte_order; enum bfd_endian byte_order = args->byte_order;
@ -309,7 +313,8 @@ safe_read_memory_integer (CORE_ADDR memaddr, int len,
} }
LONGEST LONGEST
read_memory_integer (CORE_ADDR memaddr, int len, enum bfd_endian byte_order) read_memory_integer (CORE_ADDR memaddr, int len,
enum bfd_endian byte_order)
{ {
gdb_byte buf[sizeof (LONGEST)]; gdb_byte buf[sizeof (LONGEST)];
@ -318,7 +323,8 @@ read_memory_integer (CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
} }
ULONGEST ULONGEST
read_memory_unsigned_integer (CORE_ADDR memaddr, int len, enum bfd_endian byte_order) read_memory_unsigned_integer (CORE_ADDR memaddr, int len,
enum bfd_endian byte_order)
{ {
gdb_byte buf[sizeof (ULONGEST)]; gdb_byte buf[sizeof (ULONGEST)];
@ -362,9 +368,11 @@ read_memory_typed_address (CORE_ADDR addr, struct type *type)
return extract_typed_address (buf, type); return extract_typed_address (buf, type);
} }
/* Same as target_write_memory, but report an error if can't write. */ /* Same as target_write_memory, but report an error if can't
write. */
void void
write_memory (CORE_ADDR memaddr, const bfd_byte *myaddr, int len) write_memory (CORE_ADDR memaddr,
const bfd_byte *myaddr, int len)
{ {
int status; int status;
@ -373,7 +381,8 @@ write_memory (CORE_ADDR memaddr, const bfd_byte *myaddr, int len)
memory_error (status, memaddr); memory_error (status, memaddr);
} }
/* Store VALUE at ADDR in the inferior as a LEN-byte unsigned integer. */ /* Store VALUE at ADDR in the inferior as a LEN-byte unsigned
integer. */
void void
write_memory_unsigned_integer (CORE_ADDR addr, int len, write_memory_unsigned_integer (CORE_ADDR addr, int len,
enum bfd_endian byte_order, enum bfd_endian byte_order,
@ -385,7 +394,8 @@ write_memory_unsigned_integer (CORE_ADDR addr, int len,
write_memory (addr, buf, len); write_memory (addr, buf, len);
} }
/* Store VALUE at ADDR in the inferior as a LEN-byte signed integer. */ /* Store VALUE at ADDR in the inferior as a LEN-byte signed
integer. */
void void
write_memory_signed_integer (CORE_ADDR addr, int len, write_memory_signed_integer (CORE_ADDR addr, int len,
enum bfd_endian byte_order, enum bfd_endian byte_order,
@ -405,15 +415,19 @@ char *gnutarget;
static char *gnutarget_string; static char *gnutarget_string;
static void static void
show_gnutarget_string (struct ui_file *file, int from_tty, show_gnutarget_string (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value) struct cmd_list_element *c,
const char *value)
{ {
fprintf_filtered (file, _("The current BFD target is \"%s\".\n"), value); fprintf_filtered (file,
_("The current BFD target is \"%s\".\n"), value);
} }
static void set_gnutarget_command (char *, int, struct cmd_list_element *); static void set_gnutarget_command (char *, int,
struct cmd_list_element *);
static void static void
set_gnutarget_command (char *ignore, int from_tty, struct cmd_list_element *c) set_gnutarget_command (char *ignore, int from_tty,
struct cmd_list_element *c)
{ {
if (strcmp (gnutarget_string, "auto") == 0) if (strcmp (gnutarget_string, "auto") == 0)
gnutarget = NULL; gnutarget = NULL;

View file

@ -59,8 +59,8 @@
static struct core_fns *core_file_fns = NULL; static struct core_fns *core_file_fns = NULL;
/* The core_fns for a core file handler that is prepared to read the core /* The core_fns for a core file handler that is prepared to read the
file currently open on core_bfd. */ core file currently open on core_bfd. */
static struct core_fns *core_vec = NULL; static struct core_fns *core_vec = NULL;
@ -105,10 +105,10 @@ static struct target_ops core_ops;
/* An arbitrary identifier for the core inferior. */ /* An arbitrary identifier for the core inferior. */
#define CORELOW_PID 1 #define CORELOW_PID 1
/* Link a new core_fns into the global core_file_fns list. Called on gdb /* Link a new core_fns into the global core_file_fns list. Called on
startup by the _initialize routine in each core file register reader, to gdb startup by the _initialize routine in each core file register
register information about each format the the reader is prepared to reader, to register information about each format the the reader is
handle. */ prepared to handle. */
void void
deprecated_add_core_fns (struct core_fns *cf) deprecated_add_core_fns (struct core_fns *cf)
@ -142,7 +142,8 @@ sniff_core_bfd (bfd *abfd)
struct core_fns *yummy = NULL; struct core_fns *yummy = NULL;
int matches = 0;; int matches = 0;;
/* Don't sniff if we have support for register sets in CORE_GDBARCH. */ /* Don't sniff if we have support for register sets in
CORE_GDBARCH. */
if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch)) if (core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
return NULL; return NULL;
@ -198,8 +199,8 @@ gdb_check_format (bfd *abfd)
return (0); return (0);
} }
/* Discard all vestiges of any previous core file and mark data and stack /* Discard all vestiges of any previous core file and mark data and
spaces as empty. */ stack spaces as empty. */
static void static void
core_close (int quitting) core_close (int quitting)
@ -209,7 +210,8 @@ core_close (int quitting)
if (core_bfd) if (core_bfd)
{ {
int pid = ptid_get_pid (inferior_ptid); int pid = ptid_get_pid (inferior_ptid);
inferior_ptid = null_ptid; /* Avoid confusion from thread stuff */ inferior_ptid = null_ptid; /* Avoid confusion from thread
stuff. */
exit_inferior_silent (pid); exit_inferior_silent (pid);
/* Clear out solib state while the bfd is still open. See /* Clear out solib state while the bfd is still open. See
@ -236,8 +238,8 @@ core_close_cleanup (void *ignore)
core_close (0/*ignored*/); core_close (0/*ignored*/);
} }
/* Look for sections whose names start with `.reg/' so that we can extract the /* Look for sections whose names start with `.reg/' so that we can
list of threads in a core file. */ extract the list of threads in a core file. */
static void static void
add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg) add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
@ -272,7 +274,7 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
if (reg_sect != NULL if (reg_sect != NULL
&& asect->filepos == reg_sect->filepos) /* Did we find .reg? */ && asect->filepos == reg_sect->filepos) /* Did we find .reg? */
inferior_ptid = ptid; /* Yes, make it current */ inferior_ptid = ptid; /* Yes, make it current. */
} }
/* This routine opens and sets up the core file bfd. */ /* This routine opens and sets up the core file bfd. */
@ -298,9 +300,10 @@ core_open (char *filename, int from_tty)
} }
filename = tilde_expand (filename); filename = tilde_expand (filename);
if (!IS_ABSOLUTE_PATH(filename)) if (!IS_ABSOLUTE_PATH (filename))
{ {
temp = concat (current_directory, "/", filename, (char *)NULL); temp = concat (current_directory, "/",
filename, (char *) NULL);
xfree (filename); xfree (filename);
filename = temp; filename = temp;
} }
@ -326,15 +329,16 @@ core_open (char *filename, int from_tty)
&& !gdb_check_format (temp_bfd)) && !gdb_check_format (temp_bfd))
{ {
/* Do it after the err msg */ /* Do it after the err msg */
/* FIXME: should be checking for errors from bfd_close (for one thing, /* FIXME: should be checking for errors from bfd_close (for one
on error it does not free all the storage associated with the thing, on error it does not free all the storage associated
bfd). */ with the bfd). */
make_cleanup_bfd_close (temp_bfd); make_cleanup_bfd_close (temp_bfd);
error (_("\"%s\" is not a core dump: %s"), error (_("\"%s\" is not a core dump: %s"),
filename, bfd_errmsg (bfd_get_error ())); filename, bfd_errmsg (bfd_get_error ()));
} }
/* Looks semi-reasonable. Toss the old core file and work on the new. */ /* Looks semi-reasonable. Toss the old core file and work on the
new. */
discard_cleanups (old_chain); /* Don't free filename any more */ discard_cleanups (old_chain); /* Don't free filename any more */
unpush_target (&core_ops); unpush_target (&core_ops);
@ -358,7 +362,8 @@ core_open (char *filename, int from_tty)
/* Find the data section */ /* Find the data section */
if (build_section_table (core_bfd, if (build_section_table (core_bfd,
&core_data->sections, &core_data->sections_end)) &core_data->sections,
&core_data->sections_end))
error (_("\"%s\": Can't find sections: %s"), error (_("\"%s\": Can't find sections: %s"),
bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
@ -430,16 +435,17 @@ core_open (char *filename, int from_tty)
siggy = bfd_core_file_failing_signal (core_bfd); siggy = bfd_core_file_failing_signal (core_bfd);
if (siggy > 0) if (siggy > 0)
{ {
/* NOTE: target_signal_from_host() converts a target signal value /* NOTE: target_signal_from_host() converts a target signal
into gdb's internal signal value. Unfortunately gdb's internal value into gdb's internal signal value. Unfortunately gdb's
value is called ``target_signal'' and this function got the internal value is called ``target_signal'' and this function
name ..._from_host(). */ got the name ..._from_host(). */
enum target_signal sig = (core_gdbarch != NULL enum target_signal sig = (core_gdbarch != NULL
? gdbarch_target_signal_from_host (core_gdbarch, siggy) ? gdbarch_target_signal_from_host (core_gdbarch,
siggy)
: target_signal_from_host (siggy)); : target_signal_from_host (siggy));
printf_filtered (_("Program terminated with signal %d, %s.\n"), siggy, printf_filtered (_("Program terminated with signal %d, %s.\n"),
target_signal_to_string (sig)); siggy, target_signal_to_string (sig));
} }
/* Fetch all registers from core file. */ /* Fetch all registers from core file. */
@ -493,7 +499,8 @@ deprecated_core_resize_section_table (int num_added)
NAME section contains, for use in error messages. NAME section contains, for use in error messages.
If REQUIRED is non-zero, print an error if the core file doesn't If REQUIRED is non-zero, print an error if the core file doesn't
have a section by the appropriate name. Otherwise, just do nothing. */ have a section by the appropriate name. Otherwise, just do
nothing. */
static void static void
get_core_register_section (struct regcache *regcache, get_core_register_section (struct regcache *regcache,
@ -510,7 +517,8 @@ get_core_register_section (struct regcache *regcache,
xfree (section_name); xfree (section_name);
if (ptid_get_lwp (inferior_ptid)) if (ptid_get_lwp (inferior_ptid))
section_name = xstrprintf ("%s/%ld", name, ptid_get_lwp (inferior_ptid)); section_name = xstrprintf ("%s/%ld", name,
ptid_get_lwp (inferior_ptid));
else else
section_name = xstrdup (name); section_name = xstrdup (name);
@ -518,7 +526,8 @@ get_core_register_section (struct regcache *regcache,
if (! section) if (! section)
{ {
if (required) if (required)
warning (_("Couldn't find %s registers in core file."), human_name); warning (_("Couldn't find %s registers in core file."),
human_name);
return; return;
} }
@ -536,7 +545,8 @@ get_core_register_section (struct regcache *regcache,
{ {
const struct regset *regset; const struct regset *regset;
regset = gdbarch_regset_from_core_section (core_gdbarch, name, size); regset = gdbarch_regset_from_core_section (core_gdbarch,
name, size);
if (regset == NULL) if (regset == NULL)
{ {
if (required) if (required)
@ -558,7 +568,8 @@ get_core_register_section (struct regcache *regcache,
/* Get the registers out of a core file. This is the machine- /* Get the registers out of a core file. This is the machine-
independent part. Fetch_core_registers is the machine-dependent independent part. Fetch_core_registers is the machine-dependent
part, typically implemented in the xm-file for each architecture. */ part, typically implemented in the xm-file for each
architecture. */
/* We just get all the registers, so we don't use regno. */ /* We just get all the registers, so we don't use regno. */
@ -628,7 +639,7 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
{ {
struct spuid_list *list = list_p; struct spuid_list *list = list_p;
enum bfd_endian byte_order enum bfd_endian byte_order
= bfd_big_endian (abfd)? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; = bfd_big_endian (abfd) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
int fd, pos = 0; int fd, pos = 0;
sscanf (bfd_section_name (abfd, asect), "SPU/%d/regs%n", &fd, &pos); sscanf (bfd_section_name (abfd, asect), "SPU/%d/regs%n", &fd, &pos);
@ -647,7 +658,8 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
static LONGEST static LONGEST
core_xfer_partial (struct target_ops *ops, enum target_object object, core_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf, const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf, ULONGEST offset, LONGEST len) const gdb_byte *writebuf, ULONGEST offset,
LONGEST len)
{ {
switch (object) switch (object)
{ {
@ -693,7 +705,8 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
if (readbuf) if (readbuf)
{ {
/* When the StackGhost cookie is stored in core file, BFD /* When the StackGhost cookie is stored in core file, BFD
represents this with a fake section called ".wcookie". */ represents this with a fake section called
".wcookie". */
struct bfd_section *section; struct bfd_section *section;
bfd_size_type size; bfd_size_type size;
@ -736,7 +749,8 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
if (readbuf && annex) if (readbuf && annex)
{ {
/* When the SPU contexts are stored in a core file, BFD /* When the SPU contexts are stored in a core file, BFD
represents this with a fake section called "SPU/<annex>". */ represents this with a fake section called
"SPU/<annex>". */
struct bfd_section *section; struct bfd_section *section;
bfd_size_type size; bfd_size_type size;
@ -781,15 +795,17 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
default: default:
if (ops->beneath != NULL) if (ops->beneath != NULL)
return ops->beneath->to_xfer_partial (ops->beneath, object, annex, return ops->beneath->to_xfer_partial (ops->beneath, object,
readbuf, writebuf, offset, len); annex, readbuf,
writebuf, offset, len);
return -1; return -1;
} }
} }
/* If mourn is being called in all the right places, this could be say /* If mourn is being called in all the right places, this could be say
`gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */ `gdb internal error' (since generic_mourn calls
breakpoint_init_inferior). */
static int static int
ignore (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt) ignore (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
@ -819,7 +835,8 @@ static const struct target_desc *
core_read_description (struct target_ops *target) core_read_description (struct target_ops *target)
{ {
if (core_gdbarch && gdbarch_core_read_description_p (core_gdbarch)) if (core_gdbarch && gdbarch_core_read_description_p (core_gdbarch))
return gdbarch_core_read_description (core_gdbarch, target, core_bfd); return gdbarch_core_read_description (core_gdbarch,
target, core_bfd);
return NULL; return NULL;
} }

View file

@ -70,25 +70,30 @@ is_operator_name (const char *name)
} }
int int
baseclass_offset (struct type *type, int index, const bfd_byte *valaddr, baseclass_offset (struct type *type, int index,
const bfd_byte *valaddr,
CORE_ADDR address) CORE_ADDR address)
{ {
if (current_cp_abi.baseclass_offset == NULL) if (current_cp_abi.baseclass_offset == NULL)
error (_("ABI doesn't define required function baseclass_offset")); error (_("ABI doesn't define required function baseclass_offset"));
return (*current_cp_abi.baseclass_offset) (type, index, valaddr, address); return (*current_cp_abi.baseclass_offset) (type, index,
valaddr, address);
} }
struct value * struct value *
value_virtual_fn_field (struct value **arg1p, struct fn_field *f, int j, value_virtual_fn_field (struct value **arg1p,
struct fn_field *f, int j,
struct type *type, int offset) struct type *type, int offset)
{ {
if ((current_cp_abi.virtual_fn_field) == NULL) if ((current_cp_abi.virtual_fn_field) == NULL)
return NULL; return NULL;
return (*current_cp_abi.virtual_fn_field) (arg1p, f, j, type, offset); return (*current_cp_abi.virtual_fn_field) (arg1p, f, j,
type, offset);
} }
struct type * struct type *
value_rtti_type (struct value *v, int *full, int *top, int *using_enc) value_rtti_type (struct value *v, int *full,
int *top, int *using_enc)
{ {
struct type *ret = NULL; struct type *ret = NULL;
struct gdb_exception e; struct gdb_exception e;
@ -105,7 +110,8 @@ value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
} }
void void
cplus_print_method_ptr (const gdb_byte *contents, struct type *type, cplus_print_method_ptr (const gdb_byte *contents,
struct type *type,
struct ui_file *stream) struct ui_file *stream)
{ {
if (current_cp_abi.print_method_ptr == NULL) if (current_cp_abi.print_method_ptr == NULL)
@ -131,7 +137,8 @@ cplus_make_method_ptr (struct type *type, gdb_byte *contents,
} }
CORE_ADDR CORE_ADDR
cplus_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc) cplus_skip_trampoline (struct frame_info *frame,
CORE_ADDR stop_pc)
{ {
if (current_cp_abi.skip_trampoline == NULL) if (current_cp_abi.skip_trampoline == NULL)
return 0; return 0;
@ -139,7 +146,8 @@ cplus_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
} }
struct value * struct value *
cplus_method_ptr_to_value (struct value **this_p, struct value *method_ptr) cplus_method_ptr_to_value (struct value **this_p,
struct value *method_ptr)
{ {
if (current_cp_abi.method_ptr_to_value == NULL) if (current_cp_abi.method_ptr_to_value == NULL)
error (_("GDB does not support pointers to methods on this target")); error (_("GDB does not support pointers to methods on this target"));
@ -241,7 +249,8 @@ list_cp_abis (int from_tty)
int i; int i;
ui_out_text (uiout, "The available C++ ABIs are:\n"); ui_out_text (uiout, "The available C++ ABIs are:\n");
cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "cp-abi-list"); cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout,
"cp-abi-list");
for (i = 0; i < num_cp_abis; i++) for (i = 0; i < num_cp_abis; i++)
{ {
char pad[14]; char pad[14];
@ -305,5 +314,6 @@ Set the ABI used for inspecting C++ objects.\n\
&setlist); &setlist);
add_cmd ("cp-abi", class_obscure, show_cp_abi_cmd, add_cmd ("cp-abi", class_obscure, show_cp_abi_cmd,
_("Show the ABI used for inspecting C++ objects."), &showlist); _("Show the ABI used for inspecting C++ objects."),
&showlist);
} }

View file

@ -69,7 +69,8 @@ enum dtor_kinds {
`delete'. */ `delete'. */
complete_object_dtor, complete_object_dtor,
/* A destructor which finalizes a subobject of some larger object. */ /* A destructor which finalizes a subobject of some larger
object. */
base_object_dtor base_object_dtor
}; };
@ -105,8 +106,10 @@ extern int is_operator_name (const char *name);
this is the type containing F. OFFSET is the offset of that base this is the type containing F. OFFSET is the offset of that base
type within *VALUEP. */ type within *VALUEP. */
extern struct value *value_virtual_fn_field (struct value **valuep, extern struct value *value_virtual_fn_field (struct value **valuep,
struct fn_field *f, int j, struct fn_field *f,
struct type *type, int offset); int j,
struct type *type,
int offset);
/* Try to find the run-time type of VALUE, using C++ run-time type /* Try to find the run-time type of VALUE, using C++ run-time type
@ -133,7 +136,8 @@ extern struct value *value_virtual_fn_field (struct value **valuep,
FULL, TOP, and USING_ENC can each be zero, in which case we don't FULL, TOP, and USING_ENC can each be zero, in which case we don't
provide the corresponding piece of information. */ provide the corresponding piece of information. */
extern struct type *value_rtti_type (struct value *value, extern struct type *value_rtti_type (struct value *value,
int *full, int *top, int *using_enc); int *full, int *top,
int *using_enc);
/* Compute the offset of the baseclass which is /* Compute the offset of the baseclass which is
the INDEXth baseclass of class TYPE, the INDEXth baseclass of class TYPE,
@ -144,36 +148,41 @@ extern struct type *value_rtti_type (struct value *value,
-1 is returned on error. */ -1 is returned on error. */
extern int baseclass_offset (struct type *type, int index, extern int baseclass_offset (struct type *type, int index,
const bfd_byte *valaddr, CORE_ADDR address); const bfd_byte *valaddr,
CORE_ADDR address);
/* Describe the target of a pointer to method. CONTENTS is the byte /* Describe the target of a pointer to method. CONTENTS is the byte
pattern representing the pointer to method. TYPE is the pointer to pattern representing the pointer to method. TYPE is the pointer to
method type. STREAM is the stream to print it to. */ method type. STREAM is the stream to print it to. */
void cplus_print_method_ptr (const gdb_byte *contents, struct type *type, void cplus_print_method_ptr (const gdb_byte *contents,
struct type *type,
struct ui_file *stream); struct ui_file *stream);
/* Return the size of a pointer to member function of type TO_TYPE. */ /* Return the size of a pointer to member function of type
TO_TYPE. */
int cplus_method_ptr_size (struct type *to_type); int cplus_method_ptr_size (struct type *to_type);
/* Return the method which should be called by applying METHOD_PTR /* Return the method which should be called by applying METHOD_PTR to
to *THIS_P, and adjust *THIS_P if necessary. */ *THIS_P, and adjust *THIS_P if necessary. */
struct value *cplus_method_ptr_to_value (struct value **this_p, struct value *cplus_method_ptr_to_value (struct value **this_p,
struct value *method_ptr); struct value *method_ptr);
/* Create the byte pattern in CONTENTS representing a pointer of /* Create the byte pattern in CONTENTS representing a pointer of type
type TYPE to member function at ADDRESS (if IS_VIRTUAL is 0) TYPE to member function at ADDRESS (if IS_VIRTUAL is 0) or with
or with virtual table offset ADDRESS (if IS_VIRTUAL is 1). virtual table offset ADDRESS (if IS_VIRTUAL is 1). This is the
This is the opposite of cplus_method_ptr_to_value. */ opposite of cplus_method_ptr_to_value. */
void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS, void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS,
CORE_ADDR address, int is_virtual); CORE_ADDR address, int is_virtual);
/* Determine if we are currently in a C++ thunk. If so, get the address /* Determine if we are currently in a C++ thunk. If so, get the
of the routine we are thunking to and continue to there instead. */ address of the routine we are thunking to and continue to there
instead. */
CORE_ADDR cplus_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc); CORE_ADDR cplus_skip_trampoline (struct frame_info *frame,
CORE_ADDR stop_pc);
/* Return non-zero if an argument of type TYPE should be passed by reference /* Return non-zero if an argument of type TYPE should be passed by
instead of value. */ reference instead of value. */
extern int cp_pass_by_reference (struct type *type); extern int cp_pass_by_reference (struct type *type);
struct cp_abi_ops struct cp_abi_ops
@ -182,22 +191,29 @@ struct cp_abi_ops
const char *longname; const char *longname;
const char *doc; const char *doc;
/* ABI-specific implementations for the functions declared above. */ /* ABI-specific implementations for the functions declared
above. */
enum ctor_kinds (*is_constructor_name) (const char *name); enum ctor_kinds (*is_constructor_name) (const char *name);
enum dtor_kinds (*is_destructor_name) (const char *name); enum dtor_kinds (*is_destructor_name) (const char *name);
int (*is_vtable_name) (const char *name); int (*is_vtable_name) (const char *name);
int (*is_operator_name) (const char *name); int (*is_operator_name) (const char *name);
struct value *(*virtual_fn_field) (struct value **arg1p, struct fn_field * f, struct value *(*virtual_fn_field) (struct value **arg1p,
int j, struct type * type, int offset); struct fn_field * f,
struct type *(*rtti_type) (struct value *v, int *full, int *top, int j, struct type * type,
int *using_enc); int offset);
struct type *(*rtti_type) (struct value *v, int *full,
int *top, int *using_enc);
int (*baseclass_offset) (struct type *type, int index, int (*baseclass_offset) (struct type *type, int index,
const bfd_byte *valaddr, CORE_ADDR address); const bfd_byte *valaddr,
void (*print_method_ptr) (const gdb_byte *contents, struct type *type, CORE_ADDR address);
void (*print_method_ptr) (const gdb_byte *contents,
struct type *type,
struct ui_file *stream); struct ui_file *stream);
int (*method_ptr_size) (struct type *); int (*method_ptr_size) (struct type *);
void (*make_method_ptr) (struct type *, gdb_byte *, CORE_ADDR, int); void (*make_method_ptr) (struct type *, gdb_byte *,
struct value * (*method_ptr_to_value) (struct value **, struct value *); CORE_ADDR, int);
struct value * (*method_ptr_to_value) (struct value **,
struct value *);
CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR); CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
int (*pass_by_reference) (struct type *type); int (*pass_by_reference) (struct type *type);
}; };

View file

@ -99,7 +99,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
"(anonymous namespace)", "(anonymous namespace)",
ANONYMOUS_NAMESPACE_LEN) == 0) ANONYMOUS_NAMESPACE_LEN) == 0)
{ {
int dest_len = (previous_component == 0 ? 0 : previous_component - 2); int dest_len = (previous_component == 0
? 0 : previous_component - 2);
int src_len = next_component; int src_len = next_component;
char *dest = alloca (dest_len + 1); char *dest = alloca (dest_len + 1);
@ -128,14 +129,16 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
} }
/* Add a using directive to using_directives. If the using directive in /* Add a using directive to using_directives. If the using directive
question has already been added, don't add it twice. in question has already been added, don't add it twice.
Create a new struct using_direct which imports the namespace SRC into the
scope DEST. ALIAS is the name of the imported namespace in the current Create a new struct using_direct which imports the namespace SRC
scope. If ALIAS is NULL then the namespace is known by its original name. into the scope DEST. ALIAS is the name of the imported namespace
DECLARATION is the name if the imported varable if this is a declaration in the current scope. If ALIAS is NULL then the namespace is known
import (Eg. using A::x), otherwise it is NULL. The arguments are copied by its original name. DECLARATION is the name if the imported
into newly allocated memory so they can be temporaries. */ varable if this is a declaration import (Eg. using A::x), otherwise
it is NULL. The arguments are copied into newly allocated memory
so they can be temporaries. */
void void
cp_add_using_directive (const char *dest, cp_add_using_directive (const char *dest,
@ -230,8 +233,9 @@ cp_is_anonymous (const char *namespace)
names. This makes sure that names get looked for in all namespaces names. This makes sure that names get looked for in all namespaces
that are in scope. NAME is the natural name of the symbol that that are in scope. NAME is the natural name of the symbol that
we're looking for, BLOCK is the block that we're searching within, we're looking for, BLOCK is the block that we're searching within,
DOMAIN says what kind of symbols we're looking for, and if SYMTAB is DOMAIN says what kind of symbols we're looking for, and if SYMTAB
non-NULL, we should store the symtab where we found the symbol in it. */ is non-NULL, we should store the symtab where we found the symbol
in it. */
struct symbol * struct symbol *
cp_lookup_symbol_nonlocal (const char *name, cp_lookup_symbol_nonlocal (const char *name,
@ -241,15 +245,17 @@ cp_lookup_symbol_nonlocal (const char *name,
struct symbol *sym; struct symbol *sym;
const char *scope = block_scope (block); const char *scope = block_scope (block);
sym = lookup_namespace_scope (name, block, domain, scope, 0); sym = lookup_namespace_scope (name, block,
domain, scope, 0);
if (sym != NULL) if (sym != NULL)
return sym; return sym;
return cp_lookup_symbol_namespace (scope, name, block, domain); return cp_lookup_symbol_namespace (scope, name,
block, domain);
} }
/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in /* Look up NAME in the C++ namespace NAMESPACE. Other arguments are
cp_lookup_symbol_nonlocal. */ as in cp_lookup_symbol_nonlocal. */
static struct symbol * static struct symbol *
cp_lookup_symbol_in_namespace (const char *namespace, cp_lookup_symbol_in_namespace (const char *namespace,
@ -263,14 +269,14 @@ cp_lookup_symbol_in_namespace (const char *namespace,
} }
else else
{ {
char *concatenated_name = alloca (strlen (namespace) + 2 + char *concatenated_name = alloca (strlen (namespace) + 2
strlen (name) + 1); + strlen (name) + 1);
strcpy (concatenated_name, namespace); strcpy (concatenated_name, namespace);
strcat (concatenated_name, "::"); strcat (concatenated_name, "::");
strcat (concatenated_name, name); strcat (concatenated_name, name);
return lookup_symbol_file (concatenated_name, block, return lookup_symbol_file (concatenated_name, block, domain,
domain, cp_is_anonymous (namespace)); cp_is_anonymous (namespace));
} }
} }
@ -284,30 +290,30 @@ reset_directive_searched (void *data)
direct->searched = 0; direct->searched = 0;
} }
/* Search for NAME by applying all import statements belonging /* Search for NAME by applying all import statements belonging to
to BLOCK which are applicable in SCOPE. If DECLARATION_ONLY the search BLOCK which are applicable in SCOPE. If DECLARATION_ONLY the
is restricted to using declarations. search is restricted to using declarations.
Example: Example:
namespace A{ namespace A {
int x; int x;
} }
using A::x; using A::x;
If SEARCH_PARENTS the search will include imports which are applicable in If SEARCH_PARENTS the search will include imports which are
parents of SCOPE. applicable in parents of SCOPE.
Example: Example:
namespace A{ namespace A {
using namespace X; using namespace X;
namespace B{ namespace B {
using namespace Y; using namespace Y;
} }
} }
If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of
and Y will be considered. If SEARCH_PARENTS is false only the import of Y namespaces X and Y will be considered. If SEARCH_PARENTS is false
is considered. */ only the import of Y is considered. */
struct symbol * struct symbol *
cp_lookup_symbol_imports (const char *scope, cp_lookup_symbol_imports (const char *scope,
@ -325,14 +331,15 @@ cp_lookup_symbol_imports (const char *scope,
/* First, try to find the symbol in the given namespace. */ /* First, try to find the symbol in the given namespace. */
if (!declaration_only) if (!declaration_only)
sym = cp_lookup_symbol_in_namespace (scope, name, block, domain); sym = cp_lookup_symbol_in_namespace (scope, name,
block, domain);
if (sym != NULL) if (sym != NULL)
return sym; return sym;
/* Go through the using directives. If any of them add new /* Go through the using directives. If any of them add new names to
names to the namespace we're searching in, see if we can find a the namespace we're searching in, see if we can find a match by
match by applying them. */ applying them. */
for (current = block_using (block); for (current = block_using (block);
current != NULL; current != NULL;
@ -343,33 +350,35 @@ cp_lookup_symbol_imports (const char *scope,
? (strncmp (scope, current->import_dest, ? (strncmp (scope, current->import_dest,
strlen (current->import_dest)) == 0 strlen (current->import_dest)) == 0
&& (len == 0 && (len == 0
|| scope[len] == ':' || scope[len] == '\0')) || scope[len] == ':'
|| scope[len] == '\0'))
: strcmp (scope, current->import_dest) == 0); : strcmp (scope, current->import_dest) == 0);
/* If the import destination is the current scope or one of its ancestors then /* If the import destination is the current scope or one of its
it is applicable. */ ancestors then it is applicable. */
if (directive_match && !current->searched) if (directive_match && !current->searched)
{ {
/* Mark this import as searched so that the recursive call does not /* Mark this import as searched so that the recursive call
search it again. */ does not search it again. */
current->searched = 1; current->searched = 1;
searched_cleanup = make_cleanup (reset_directive_searched, current); searched_cleanup = make_cleanup (reset_directive_searched,
current);
/* If there is an import of a single declaration, compare the imported /* If there is an import of a single declaration, compare the
declaration (after optional renaming by its alias) with the sought imported declaration (after optional renaming by its alias)
out name. If there is a match pass current->import_src as NAMESPACE with the sought out name. If there is a match pass
to direct the search towards the imported namespace. */ current->import_src as NAMESPACE to direct the search
towards the imported namespace. */
if (current->declaration if (current->declaration
&& strcmp (name, current->alias ? current->alias && strcmp (name, current->alias
: current->declaration) == 0) ? current->alias : current->declaration) == 0)
sym = cp_lookup_symbol_in_namespace (current->import_src, sym = cp_lookup_symbol_in_namespace (current->import_src,
current->declaration, current->declaration,
block, block, domain);
domain);
/* If this is a DECLARATION_ONLY search or a symbol was found or /* If this is a DECLARATION_ONLY search or a symbol was found
this import statement was an import declaration, the search or this import statement was an import declaration, the
of this import is complete. */ search of this import is complete. */
if (declaration_only || sym != NULL || current->declaration) if (declaration_only || sym != NULL || current->declaration)
{ {
current->searched = 0; current->searched = 0;
@ -381,26 +390,24 @@ cp_lookup_symbol_imports (const char *scope,
continue; continue;
} }
if (current->alias != NULL && strcmp (name, current->alias) == 0) if (current->alias != NULL
/* If the import is creating an alias and the alias matches the && strcmp (name, current->alias) == 0)
sought name. Pass current->import_src as the NAME to direct the /* If the import is creating an alias and the alias matches
search towards the aliased namespace. */ the sought name. Pass current->import_src as the NAME to
direct the search towards the aliased namespace. */
{ {
sym = cp_lookup_symbol_in_namespace (scope, sym = cp_lookup_symbol_in_namespace (scope,
current->import_src, current->import_src,
block, block, domain);
domain);
} }
else if (current->alias == NULL) else if (current->alias == NULL)
{ {
/* If this import statement creates no alias, pass current->inner as /* If this import statement creates no alias, pass
NAMESPACE to direct the search towards the imported namespace. */ current->inner as NAMESPACE to direct the search
towards the imported namespace. */
sym = cp_lookup_symbol_imports (current->import_src, sym = cp_lookup_symbol_imports (current->import_src,
name, name, block,
block, domain, 0, 0);
domain,
0,
0);
} }
current->searched = 0; current->searched = 0;
discard_cleanups (searched_cleanup); discard_cleanups (searched_cleanup);
@ -417,7 +424,8 @@ cp_lookup_symbol_imports (const char *scope,
NAME. */ NAME. */
static struct symbol * static struct symbol *
search_symbol_list (const char *name, int num, struct symbol **syms) search_symbol_list (const char *name, int num,
struct symbol **syms)
{ {
int i; int i;
@ -451,7 +459,8 @@ cp_lookup_symbol_imports_or_template (const char *scope,
/* Search the function's template parameters. */ /* Search the function's template parameters. */
if (SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION (function)) if (SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION (function))
{ {
struct template_symbol *templ = (struct template_symbol *) function; struct template_symbol *templ
= (struct template_symbol *) function;
struct symbol *result; struct symbol *result;
result = search_symbol_list (name, result = search_symbol_list (name,
@ -482,13 +491,16 @@ cp_lookup_symbol_imports_or_template (const char *scope,
else else
{ {
name_copy[prefix_len] = '\0'; name_copy[prefix_len] = '\0';
context = lookup_typename (lang, arch, name_copy, parent, 1); context = lookup_typename (lang, arch,
name_copy,
parent, 1);
} }
if (context == NULL) if (context == NULL)
break; break;
result = search_symbol_list (name, result
= search_symbol_list (name,
TYPE_N_TEMPLATE_ARGUMENTS (context), TYPE_N_TEMPLATE_ARGUMENTS (context),
TYPE_TEMPLATE_ARGUMENTS (context)); TYPE_TEMPLATE_ARGUMENTS (context));
if (result != NULL) if (result != NULL)
@ -502,9 +514,10 @@ cp_lookup_symbol_imports_or_template (const char *scope,
return cp_lookup_symbol_imports (scope, name, block, domain, 1, 1); return cp_lookup_symbol_imports (scope, name, block, domain, 1, 1);
} }
/* Searches for NAME in the current namespace, and by applying relevant import /* Searches for NAME in the current namespace, and by applying
statements belonging to BLOCK and its parents. SCOPE is the namespace scope relevant import statements belonging to BLOCK and its parents.
of the context in which the search is being evaluated. */ SCOPE is the namespace scope of the context in which the search is
being evaluated. */
struct symbol* struct symbol*
cp_lookup_symbol_namespace (const char *scope, cp_lookup_symbol_namespace (const char *scope,
@ -515,14 +528,17 @@ cp_lookup_symbol_namespace (const char *scope,
struct symbol *sym; struct symbol *sym;
/* First, try to find the symbol in the given namespace. */ /* First, try to find the symbol in the given namespace. */
sym = cp_lookup_symbol_in_namespace (scope, name, block, domain); sym = cp_lookup_symbol_in_namespace (scope, name,
block, domain);
if (sym != NULL) if (sym != NULL)
return sym; return sym;
/* Search for name in namespaces imported to this and parent blocks. */ /* Search for name in namespaces imported to this and parent
blocks. */
while (block != NULL) while (block != NULL)
{ {
sym = cp_lookup_symbol_imports (scope, name, block, domain, 0, 1); sym = cp_lookup_symbol_imports (scope, name, block,
domain, 0, 1);
if (sym) if (sym)
return sym; return sym;
@ -571,7 +587,8 @@ lookup_namespace_scope (const char *name,
new_scope_len += 2; new_scope_len += 2;
} }
new_scope_len += cp_find_first_component (scope + new_scope_len); new_scope_len += cp_find_first_component (scope + new_scope_len);
sym = lookup_namespace_scope (name, block, domain, scope, new_scope_len); sym = lookup_namespace_scope (name, block, domain,
scope, new_scope_len);
if (sym != NULL) if (sym != NULL)
return sym; return sym;
} }
@ -582,7 +599,8 @@ lookup_namespace_scope (const char *name,
namespace = alloca (scope_len + 1); namespace = alloca (scope_len + 1);
strncpy (namespace, scope, scope_len); strncpy (namespace, scope, scope_len);
namespace[scope_len] = '\0'; namespace[scope_len] = '\0';
return cp_lookup_symbol_in_namespace (namespace, name, block, domain); return cp_lookup_symbol_in_namespace (namespace, name,
block, domain);
} }
/* Look up NAME in BLOCK's static block and in global blocks. If /* Look up NAME in BLOCK's static block and in global blocks. If
@ -664,24 +682,26 @@ cp_lookup_nested_type (struct type *parent_type,
lookup_symbol_namespace works when looking them up. */ lookup_symbol_namespace works when looking them up. */
const char *parent_name = TYPE_TAG_NAME (parent_type); const char *parent_name = TYPE_TAG_NAME (parent_type);
struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name, struct symbol *sym
nested_name, = cp_lookup_symbol_in_namespace (parent_name, nested_name,
block, block, VAR_DOMAIN);
VAR_DOMAIN);
char *concatenated_name; char *concatenated_name;
if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF) if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
return SYMBOL_TYPE (sym); return SYMBOL_TYPE (sym);
/* Now search all static file-level symbols. Not strictly correct, /* Now search all static file-level symbols. Not strictly
but more useful than an error. We do not try to guess any imported correct, but more useful than an error. We do not try to
namespace as even the fully specified namespace seach is is already guess any imported namespace as even the fully specified
not C++ compliant and more assumptions could make it too magic. */ namespace seach is is already not C++ compliant and more
assumptions could make it too magic. */
concatenated_name = alloca (strlen (parent_name) + 2 concatenated_name = alloca (strlen (parent_name) + 2
+ strlen (nested_name) + 1); + strlen (nested_name) + 1);
sprintf (concatenated_name, "%s::%s", parent_name, nested_name); sprintf (concatenated_name, "%s::%s",
sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN); parent_name, nested_name);
sym = lookup_static_symbol_aux (concatenated_name,
VAR_DOMAIN);
if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF) if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
return SYMBOL_TYPE (sym); return SYMBOL_TYPE (sym);
@ -733,11 +753,12 @@ cp_lookup_transparent_type (const char *name)
/* Lookup the the type definition associated to NAME in /* Lookup the the type definition associated to NAME in
namespaces/classes containing SCOPE whose name is strictly longer namespaces/classes containing SCOPE whose name is strictly longer
than LENGTH. LENGTH must be the index of the start of a than LENGTH. LENGTH must be the index of the start of a component
component of SCOPE. */ of SCOPE. */
static struct type * static struct type *
cp_lookup_transparent_type_loop (const char *name, const char *scope, cp_lookup_transparent_type_loop (const char *name,
const char *scope,
int length) int length)
{ {
int scope_length = length + cp_find_first_component (scope + length); int scope_length = length + cp_find_first_component (scope + length);
@ -748,7 +769,8 @@ cp_lookup_transparent_type_loop (const char *name, const char *scope,
if (scope[scope_length] == ':') if (scope[scope_length] == ':')
{ {
struct type *retval struct type *retval
= cp_lookup_transparent_type_loop (name, scope, scope_length + 2); = cp_lookup_transparent_type_loop (name, scope,
scope_length + 2);
if (retval != NULL) if (retval != NULL)
return retval; return retval;
@ -865,7 +887,8 @@ free_namespace_block (struct symtab *symtab)
it shouldn't consist solely of namespaces. */ it shouldn't consist solely of namespaces. */
void void
cp_check_possible_namespace_symbols (const char *name, struct objfile *objfile) cp_check_possible_namespace_symbols (const char *name,
struct objfile *objfile)
{ {
check_possible_namespace_symbols_loop (name, check_possible_namespace_symbols_loop (name,
cp_find_first_component (name), cp_find_first_component (name),
@ -904,7 +927,8 @@ check_possible_namespace_symbols_loop (const char *name, int len,
objfile); objfile);
if (!done) if (!done)
done = check_one_possible_namespace_symbol (name, len, objfile); done = check_one_possible_namespace_symbol (name, len,
objfile);
return done; return done;
} }
@ -932,11 +956,13 @@ check_one_possible_namespace_symbol (const char *name, int len,
{ {
struct type *type; struct type *type;
type = init_type (TYPE_CODE_NAMESPACE, 0, 0, name_copy, objfile); type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
name_copy, objfile);
TYPE_TAG_NAME (type) = TYPE_NAME (type); TYPE_TAG_NAME (type) = TYPE_NAME (type);
sym = obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); sym = obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol)); memset (sym, 0, sizeof (struct symbol));
SYMBOL_SET_LANGUAGE (sym, language_cplus); SYMBOL_SET_LANGUAGE (sym, language_cplus);
/* Note that init_type copied the name to the objfile's /* Note that init_type copied the name to the objfile's
@ -989,7 +1015,8 @@ maintenance_cplus_namespace (char *args, int from_tty)
struct dict_iterator iter; struct dict_iterator iter;
struct symbol *sym; struct symbol *sym;
ALL_BLOCK_SYMBOLS (get_possible_namespace_block (objfile), iter, sym) ALL_BLOCK_SYMBOLS (get_possible_namespace_block (objfile),
iter, sym)
{ {
printf_unfiltered ("%s\n", SYMBOL_PRINT_NAME (sym)); printf_unfiltered ("%s\n", SYMBOL_PRINT_NAME (sym));
} }
@ -1002,7 +1029,8 @@ extern initialize_file_ftype _initialize_cp_namespace;
void void
_initialize_cp_namespace (void) _initialize_cp_namespace (void)
{ {
add_cmd ("namespace", class_maintenance, maintenance_cplus_namespace, add_cmd ("namespace", class_maintenance,
maintenance_cplus_namespace,
_("Print the list of possible C++ namespaces."), _("Print the list of possible C++ namespaces."),
&maint_cplus_cmd_list); &maint_cplus_cmd_list);
} }

View file

@ -74,14 +74,15 @@ static void maint_cplus_command (char *arg, int from_tty);
static void first_component_command (char *arg, int from_tty); static void first_component_command (char *arg, int from_tty);
/* Operator validation. /* Operator validation.
NOTE: Multi-byte operators (usually the assignment variety operator) NOTE: Multi-byte operators (usually the assignment variety
must appear before the single byte version, i.e., "+=" before "+". */ operator) must appear before the single byte version, i.e., "+="
before "+". */
static const char *operator_tokens[] = static const char *operator_tokens[] =
{ {
"++", "+=", "+", "->*", "->", "--", "-=", "-", "*=", "*", "/=", "/", "++", "+=", "+", "->*", "->", "--", "-=", "-", "*=", "*",
"%=", "%", "!=", "==", "!", "&&", "<<=", "<<", ">>=", ">>", "/=", "/", "%=", "%", "!=", "==", "!", "&&", "<<=", "<<",
"<=", "<", ">=", ">", "~", "&=", "&", "|=", "||", "|", "^=", "^", ">>=", ">>", "<=", "<", ">=", ">", "~", "&=", "&", "|=",
"=", "()", "[]", ",", "new", "delete" "||", "|", "^=", "^", "=", "()", "[]", ",", "new", "delete"
/* new[] and delete[] require special whitespace handling */ /* new[] and delete[] require special whitespace handling */
}; };
@ -146,11 +147,11 @@ cp_canonicalize_string (const char *string)
return ret; return ret;
} }
/* Convert a mangled name to a demangle_component tree. *MEMORY is set to the /* Convert a mangled name to a demangle_component tree. *MEMORY is
block of used memory that should be freed when finished with the tree. set to the block of used memory that should be freed when finished
DEMANGLED_P is set to the char * that should be freed when finished with with the tree. DEMANGLED_P is set to the char * that should be
the tree, or NULL if none was needed. OPTIONS will be passed to the freed when finished with the tree, or NULL if none was needed.
demangler. */ OPTIONS will be passed to the demangler. */
static struct demangle_component * static struct demangle_component *
mangled_name_to_comp (const char *mangled_name, int options, mangled_name_to_comp (const char *mangled_name, int options,
@ -163,7 +164,8 @@ mangled_name_to_comp (const char *mangled_name, int options,
to trees. */ to trees. */
if (mangled_name[0] == '_' && mangled_name[1] == 'Z') if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
{ {
ret = cplus_demangle_v3_components (mangled_name, options, memory); ret = cplus_demangle_v3_components (mangled_name,
options, memory);
if (ret) if (ret)
{ {
*demangled_p = NULL; *demangled_p = NULL;
@ -171,12 +173,14 @@ mangled_name_to_comp (const char *mangled_name, int options,
} }
} }
/* If it doesn't, or if that failed, then try to demangle the name. */ /* If it doesn't, or if that failed, then try to demangle the
name. */
demangled_name = cplus_demangle (mangled_name, options); demangled_name = cplus_demangle (mangled_name, options);
if (demangled_name == NULL) if (demangled_name == NULL)
return NULL; return NULL;
/* If we could demangle the name, parse it to build the component tree. */ /* If we could demangle the name, parse it to build the component
tree. */
ret = cp_demangled_name_to_comp (demangled_name, NULL); ret = cp_demangled_name_to_comp (demangled_name, NULL);
if (ret == NULL) if (ret == NULL)
@ -199,14 +203,15 @@ cp_class_name_from_physname (const char *physname)
struct demangle_component *ret_comp, *prev_comp, *cur_comp; struct demangle_component *ret_comp, *prev_comp, *cur_comp;
int done; int done;
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage, ret_comp = mangled_name_to_comp (physname, DMGL_ANSI,
&demangled_name); &storage, &demangled_name);
if (ret_comp == NULL) if (ret_comp == NULL)
return NULL; return NULL;
done = 0; done = 0;
/* First strip off any qualifiers, if we have a function or method. */ /* First strip off any qualifiers, if we have a function or
method. */
while (!done) while (!done)
switch (ret_comp->type) switch (ret_comp->type)
{ {
@ -233,9 +238,9 @@ cp_class_name_from_physname (const char *physname)
if (ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE) if (ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE)
ret_comp = d_left (ret_comp); ret_comp = d_left (ret_comp);
/* What we have now should be a name, possibly qualified. Additional /* What we have now should be a name, possibly qualified.
qualifiers could live in the left subtree or the right subtree. Find Additional qualifiers could live in the left subtree or the right
the last piece. */ subtree. Find the last piece. */
done = 0; done = 0;
prev_comp = NULL; prev_comp = NULL;
cur_comp = ret_comp; cur_comp = ret_comp;
@ -266,7 +271,8 @@ cp_class_name_from_physname (const char *physname)
{ {
/* We want to discard the rightmost child of PREV_COMP. */ /* We want to discard the rightmost child of PREV_COMP. */
*prev_comp = *d_left (prev_comp); *prev_comp = *d_left (prev_comp);
/* The ten is completely arbitrary; we don't have a good estimate. */ /* The ten is completely arbitrary; we don't have a good
estimate. */
ret = cp_comp_to_string (ret_comp, 10); ret = cp_comp_to_string (ret_comp, 10);
} }
@ -276,9 +282,10 @@ cp_class_name_from_physname (const char *physname)
return ret; return ret;
} }
/* Return the child of COMP which is the basename of a method, variable, /* Return the child of COMP which is the basename of a method,
et cetera. All scope qualifiers are discarded, but template arguments variable, et cetera. All scope qualifiers are discarded, but
will be included. The component tree may be modified. */ template arguments will be included. The component tree may be
modified. */
static struct demangle_component * static struct demangle_component *
unqualified_name_from_comp (struct demangle_component *comp) unqualified_name_from_comp (struct demangle_component *comp)
@ -342,8 +349,8 @@ method_name_from_physname (const char *physname)
char *demangled_name = NULL, *ret; char *demangled_name = NULL, *ret;
struct demangle_component *ret_comp; struct demangle_component *ret_comp;
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage, ret_comp = mangled_name_to_comp (physname, DMGL_ANSI,
&demangled_name); &storage, &demangled_name);
if (ret_comp == NULL) if (ret_comp == NULL)
return NULL; return NULL;
@ -351,7 +358,8 @@ method_name_from_physname (const char *physname)
ret = NULL; ret = NULL;
if (ret_comp != NULL) if (ret_comp != NULL)
/* The ten is completely arbitrary; we don't have a good estimate. */ /* The ten is completely arbitrary; we don't have a good
estimate. */
ret = cp_comp_to_string (ret_comp, 10); ret = cp_comp_to_string (ret_comp, 10);
xfree (storage); xfree (storage);
@ -551,7 +559,8 @@ cp_find_first_component_aux (const char *name, int permissive)
case 'o': case 'o':
/* Operator names can screw up the recursion. */ /* Operator names can screw up the recursion. */
if (operator_possible if (operator_possible
&& strncmp (name + index, "operator", LENGTH_OF_OPERATOR) == 0) && strncmp (name + index, "operator",
LENGTH_OF_OPERATOR) == 0)
{ {
index += LENGTH_OF_OPERATOR; index += LENGTH_OF_OPERATOR;
while (ISSPACE(name[index])) while (ISSPACE(name[index]))
@ -644,13 +653,15 @@ cp_entire_prefix_len (const char *name)
completion list. */ completion list. */
static void static void
overload_list_add_symbol (struct symbol *sym, const char *oload_name) overload_list_add_symbol (struct symbol *sym,
const char *oload_name)
{ {
int newsize; int newsize;
int i; int i;
char *sym_name; char *sym_name;
/* If there is no type information, we can't do anything, so skip */ /* If there is no type information, we can't do anything, so
skip. */
if (SYMBOL_TYPE (sym) == NULL) if (SYMBOL_TYPE (sym) == NULL)
return; return;
@ -674,12 +685,13 @@ overload_list_add_symbol (struct symbol *sym, const char *oload_name)
xfree (sym_name); xfree (sym_name);
/* We have a match for an overload instance, so add SYM to the current list /* We have a match for an overload instance, so add SYM to the
* of overload instances */ current list of overload instances */
if (sym_return_val_index + 3 > sym_return_val_size) if (sym_return_val_index + 3 > sym_return_val_size)
{ {
newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *); newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize); sym_return_val = (struct symbol **)
xrealloc ((char *) sym_return_val, newsize);
} }
sym_return_val[sym_return_val_index++] = sym; sym_return_val[sym_return_val_index++] = sym;
sym_return_val[sym_return_val_index] = NULL; sym_return_val[sym_return_val_index] = NULL;
@ -774,8 +786,8 @@ make_symbol_overload_list_namespace (const char *func_name,
} }
/* Search the namespace of the given type and namespace of and public base /* Search the namespace of the given type and namespace of and public
types. */ base types. */
static void static void
make_symbol_overload_list_adl_namespace (struct type *type, make_symbol_overload_list_adl_namespace (struct type *type,
@ -785,7 +797,8 @@ make_symbol_overload_list_adl_namespace (struct type *type,
char *type_name; char *type_name;
int i, prefix_len; int i, prefix_len;
while (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF while (TYPE_CODE (type) == TYPE_CODE_PTR
|| TYPE_CODE (type) == TYPE_CODE_REF
|| TYPE_CODE (type) == TYPE_CODE_ARRAY || TYPE_CODE (type) == TYPE_CODE_ARRAY
|| TYPE_CODE (type) == TYPE_CODE_TYPEDEF) || TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
{ {
@ -816,13 +829,14 @@ make_symbol_overload_list_adl_namespace (struct type *type,
for (i = 0; i < TYPE_N_BASECLASSES (type); i++) for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
{ {
if (BASETYPE_VIA_PUBLIC (type, i)) if (BASETYPE_VIA_PUBLIC (type, i))
make_symbol_overload_list_adl_namespace (TYPE_BASECLASS (type, i), make_symbol_overload_list_adl_namespace (TYPE_BASECLASS (type,
i),
func_name); func_name);
} }
} }
/* Adds the the overload list overload candidates for FUNC_NAME found through /* Adds the the overload list overload candidates for FUNC_NAME found
argument dependent lookup. */ through argument dependent lookup. */
struct symbol ** struct symbol **
make_symbol_overload_list_adl (struct type **arg_types, int nargs, make_symbol_overload_list_adl (struct type **arg_types, int nargs,
@ -833,12 +847,14 @@ make_symbol_overload_list_adl (struct type **arg_types, int nargs,
gdb_assert (sym_return_val_size != -1); gdb_assert (sym_return_val_size != -1);
for (i = 1; i <= nargs; i++) for (i = 1; i <= nargs; i++)
make_symbol_overload_list_adl_namespace (arg_types[i - 1], func_name); make_symbol_overload_list_adl_namespace (arg_types[i - 1],
func_name);
return sym_return_val; return sym_return_val;
} }
/* Used for cleanups to reset the "searched" flag in case of an error. */ /* Used for cleanups to reset the "searched" flag in case of an
error. */
static void static void
reset_directive_searched (void *data) reset_directive_searched (void *data)
@ -874,19 +890,22 @@ make_symbol_overload_list_using (const char *func_name,
if (current->searched) if (current->searched)
continue; continue;
/* If this is a namespace alias or imported declaration ignore it. */ /* If this is a namespace alias or imported declaration ignore
it. */
if (current->alias != NULL || current->declaration != NULL) if (current->alias != NULL || current->declaration != NULL)
continue; continue;
if (strcmp (namespace, current->import_dest) == 0) if (strcmp (namespace, current->import_dest) == 0)
{ {
/* Mark this import as searched so that the recursive call does /* Mark this import as searched so that the recursive call
not search it again. */ does not search it again. */
struct cleanup *old_chain; struct cleanup *old_chain;
current->searched = 1; current->searched = 1;
old_chain = make_cleanup (reset_directive_searched, current); old_chain = make_cleanup (reset_directive_searched,
current);
make_symbol_overload_list_using (func_name, current->import_src); make_symbol_overload_list_using (func_name,
current->import_src);
current->searched = 0; current->searched = 0;
discard_cleanups (old_chain); discard_cleanups (old_chain);
@ -911,8 +930,8 @@ make_symbol_overload_list_qualified (const char *func_name)
struct dict_iterator iter; struct dict_iterator iter;
const struct dictionary *dict; const struct dictionary *dict;
/* Look through the partial symtabs for all symbols which begin /* Look through the partial symtabs for all symbols which begin by
by matching FUNC_NAME. Make sure we read that symbol table in. */ matching FUNC_NAME. Make sure we read that symbol table in. */
ALL_OBJFILES (objfile) ALL_OBJFILES (objfile)
{ {
@ -998,7 +1017,9 @@ static void
maint_cplus_command (char *arg, int from_tty) maint_cplus_command (char *arg, int from_tty)
{ {
printf_unfiltered (_("\"maintenance cplus\" must be followed by the name of a command.\n")); printf_unfiltered (_("\"maintenance cplus\" must be followed by the name of a command.\n"));
help_list (maint_cplus_cmd_list, "maintenance cplus ", -1, gdb_stdout); help_list (maint_cplus_cmd_list,
"maintenance cplus ",
-1, gdb_stdout);
} }
/* This is a front end for cp_find_first_component, for unit testing. /* This is a front end for cp_find_first_component, for unit testing.
@ -1034,7 +1055,8 @@ extern initialize_file_ftype _initialize_cp_support; /* -Wmissing-prototypes */
while (0) while (0)
/* Returns the length of the operator name or 0 if INPUT does not /* Returns the length of the operator name or 0 if INPUT does not
point to a valid C++ operator. INPUT should start with "operator". */ point to a valid C++ operator. INPUT should start with
"operator". */
int int
cp_validate_operator (const char *input) cp_validate_operator (const char *input)
{ {
@ -1053,13 +1075,15 @@ cp_validate_operator (const char *input)
p += 8; p += 8;
SKIP_SPACE (p); SKIP_SPACE (p);
for (i = 0; i < sizeof (operator_tokens) / sizeof (operator_tokens[0]); for (i = 0;
i < sizeof (operator_tokens) / sizeof (operator_tokens[0]);
++i) ++i)
{ {
int length = strlen (operator_tokens[i]); int length = strlen (operator_tokens[i]);
/* By using strncmp here, we MUST have operator_tokens ordered! /* By using strncmp here, we MUST have operator_tokens
See additional notes where operator_tokens is defined above. */ ordered! See additional notes where operator_tokens is
defined above. */
if (strncmp (p, operator_tokens[i], length) == 0) if (strncmp (p, operator_tokens[i], length) == 0)
{ {
const char *op = p; const char *op = p;
@ -1071,8 +1095,8 @@ cp_validate_operator (const char *input)
|| strncmp (op, "delete", 6) == 0) || strncmp (op, "delete", 6) == 0)
{ {
/* Special case: new[] and delete[]. We must be careful /* Special case: new[] and delete[]. We must be
to swallow whitespace before/in "[]". */ careful to swallow whitespace before/in "[]". */
SKIP_SPACE (p); SKIP_SPACE (p);
if (*p == '[') if (*p == '[')
@ -1093,12 +1117,12 @@ cp_validate_operator (const char *input)
/* Check input for a conversion operator. */ /* Check input for a conversion operator. */
/* Skip past base typename */ /* Skip past base typename. */
while (*p != '*' && *p != '&' && *p != 0 && *p != ' ') while (*p != '*' && *p != '&' && *p != 0 && *p != ' ')
++p; ++p;
SKIP_SPACE (p); SKIP_SPACE (p);
/* Add modifiers '*'/'&' */ /* Add modifiers '*' / '&'. */
while (*p == '*' || *p == '&') while (*p == '*' || *p == '&')
{ {
++p; ++p;
@ -1130,12 +1154,19 @@ cp_validate_operator (const char *input)
void void
_initialize_cp_support (void) _initialize_cp_support (void)
{ {
add_prefix_cmd ("cplus", class_maintenance, maint_cplus_command, add_prefix_cmd ("cplus", class_maintenance,
_("C++ maintenance commands."), &maint_cplus_cmd_list, maint_cplus_command,
"maintenance cplus ", 0, &maintenancelist); _("C++ maintenance commands."),
add_alias_cmd ("cp", "cplus", class_maintenance, 1, &maintenancelist); &maint_cplus_cmd_list,
"maintenance cplus ",
0, &maintenancelist);
add_alias_cmd ("cp", "cplus",
class_maintenance, 1,
&maintenancelist);
add_cmd ("first_component", class_maintenance, first_component_command, add_cmd ("first_component",
class_maintenance,
first_component_command,
_("Print the first class/namespace component of NAME."), _("Print the first class/namespace component of NAME."),
&maint_cplus_cmd_list); &maint_cplus_cmd_list);
} }

View file

@ -37,13 +37,14 @@ struct type;
struct demangle_component; struct demangle_component;
/* This struct is designed to store data from using directives. It /* This struct is designed to store data from using directives. It
says that names from namespace IMPORT_SRC should be visible within namespace says that names from namespace IMPORT_SRC should be visible within
IMPORT_DEST. These form a linked list; NEXT is the next element of the namespace IMPORT_DEST. These form a linked list; NEXT is the next
list. If the imported namespace or declaration has been aliased within the element of the list. If the imported namespace or declaration has
IMPORT_DEST namespace, ALIAS is set to a string representing the alias. been aliased within the IMPORT_DEST namespace, ALIAS is set to a
Otherwise, ALIAS is NULL. DECLARATION is the name of the imported string representing the alias. Otherwise, ALIAS is NULL.
declaration, if this import statement represents one. Otherwise DECLARATION DECLARATION is the name of the imported declaration, if this import
is NULL and this import statement represents a namespace. statement represents one. Otherwise DECLARATION is NULL and this
import statement represents a namespace.
C++: using namespace A; C++: using namespace A;
Fortran: use A Fortran: use A
@ -66,15 +67,18 @@ struct demangle_component;
import_dest = local scope of the import statement even such as "" import_dest = local scope of the import statement even such as ""
alias = "LOCALNS" alias = "LOCALNS"
declaration = NULL declaration = NULL
The namespace will get imported as the import_dest::LOCALNS namespace. The namespace will get imported as the import_dest::LOCALNS
namespace.
C++ cannot express it, it would be something like: using localname = A::x; C++ cannot express it, it would be something like: using localname
= A::x;
Fortran: use A, only localname => x Fortran: use A, only localname => x
import_src = "A" import_src = "A"
import_dest = local scope of the import statement even such as "" import_dest = local scope of the import statement even such as ""
alias = "localname" alias = "localname"
declaration = "x" declaration = "x"
The declaration will get imported as localname or `import_dest`localname. */ The declaration will get imported as localname or
`import_dest`localname. */
struct using_direct struct using_direct
{ {
@ -86,7 +90,8 @@ struct using_direct
struct using_direct *next; struct using_direct *next;
/* Used during import search to temporarily mark this node as searched. */ /* Used during import search to temporarily mark this node as
searched. */
int searched; int searched;
}; };

View file

@ -38,7 +38,7 @@
#include "language.h" #include "language.h"
#include "python/python.h" #include "python/python.h"
/* Controls printing of vtbl's */ /* Controls printing of vtbl's. */
static void static void
show_vtblprint (struct ui_file *file, int from_tty, show_vtblprint (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value) struct cmd_list_element *c, const char *value)
@ -62,9 +62,11 @@ Printing of object's derived type based on vtable info is %s.\n"),
static void static void
show_static_field_print (struct ui_file *file, int from_tty, show_static_field_print (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value) struct cmd_list_element *c,
const char *value)
{ {
fprintf_filtered (file, _("Printing of C++ static members is %s.\n"), fprintf_filtered (file,
_("Printing of C++ static members is %s.\n"),
value); value);
} }
@ -79,10 +81,12 @@ static void cp_print_static_field (struct type *, struct value *,
struct ui_file *, int, struct ui_file *, int,
const struct value_print_options *); const struct value_print_options *);
static void cp_print_value (struct type *, struct type *, const gdb_byte *, static void cp_print_value (struct type *, struct type *,
int, CORE_ADDR, struct ui_file *, int, const gdb_byte *, int,
const struct value *, CORE_ADDR, struct ui_file *,
const struct value_print_options *, struct type **); int, const struct value *,
const struct value_print_options *,
struct type **);
/* GCC versions after 2.4.5 use this. */ /* GCC versions after 2.4.5 use this. */
@ -105,8 +109,8 @@ cp_is_vtbl_ptr_type (struct type *type)
int int
cp_is_vtbl_member (struct type *type) cp_is_vtbl_member (struct type *type)
{ {
/* With older versions of g++, the vtbl field pointed to an array /* With older versions of g++, the vtbl field pointed to an array of
of structures. Nowadays it points directly to the structure. */ structures. Nowadays it points directly to the structure. */
if (TYPE_CODE (type) == TYPE_CODE_PTR) if (TYPE_CODE (type) == TYPE_CODE_PTR)
{ {
type = TYPE_TARGET_TYPE (type); type = TYPE_TARGET_TYPE (type);
@ -127,9 +131,10 @@ cp_is_vtbl_member (struct type *type)
} }
else if (TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */ else if (TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
{ {
/* The type name of the thunk pointer is NULL when using dwarf2. /* The type name of the thunk pointer is NULL when using
We could test for a pointer to a function, but there is dwarf2. We could test for a pointer to a function, but
no type info for the virtual table either, so it wont help. */ there is no type info for the virtual table either, so it
wont help. */
return cp_is_vtbl_ptr_type (type); return cp_is_vtbl_ptr_type (type);
} }
} }
@ -137,24 +142,26 @@ cp_is_vtbl_member (struct type *type)
} }
/* Mutually recursive subroutines of cp_print_value and c_val_print to /* 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. print out a structure's fields: cp_print_value_fields and
cp_print_value.
TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and OPTIONS have the TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and OPTIONS have the same
same meanings as in cp_print_value and c_val_print. meanings as in cp_print_value and c_val_print.
2nd argument REAL_TYPE is used to carry over the type of the derived 2nd argument REAL_TYPE is used to carry over the type of the
class across the recursion to base classes. derived class across the recursion to base classes.
DONT_PRINT is an array of baseclass types that we DONT_PRINT is an array of baseclass types that we should not print,
should not print, or zero if called from top level. */ or zero if called from top level. */
void void
cp_print_value_fields (struct type *type, struct type *real_type, cp_print_value_fields (struct type *type, struct type *real_type,
const gdb_byte *valaddr, int offset, CORE_ADDR address, const gdb_byte *valaddr, int offset,
struct ui_file *stream, int recurse, CORE_ADDR address, struct ui_file *stream,
const struct value *val, int recurse, const struct value *val,
const struct value_print_options *options, const struct value_print_options *options,
struct type **dont_print_vb, int dont_print_statmem) struct type **dont_print_vb,
int dont_print_statmem)
{ {
int i, len, n_baseclasses; int i, len, n_baseclasses;
int fields_seen = 0; int fields_seen = 0;
@ -164,12 +171,14 @@ cp_print_value_fields (struct type *type, struct type *real_type,
if (recurse == 0) if (recurse == 0)
{ {
/* Any object can be left on obstacks only during an unexpected error. */ /* Any object can be left on obstacks only during an unexpected
error. */
if (obstack_object_size (&dont_print_statmem_obstack) > 0) if (obstack_object_size (&dont_print_statmem_obstack) > 0)
{ {
obstack_free (&dont_print_statmem_obstack, NULL); obstack_free (&dont_print_statmem_obstack, NULL);
obstack_begin (&dont_print_statmem_obstack, 32 * sizeof (CORE_ADDR)); obstack_begin (&dont_print_statmem_obstack,
32 * sizeof (CORE_ADDR));
} }
if (obstack_object_size (&dont_print_stat_array_obstack) > 0) if (obstack_object_size (&dont_print_stat_array_obstack) > 0)
{ {
@ -187,8 +196,10 @@ cp_print_value_fields (struct type *type, struct type *real_type,
duplicates of virtual baseclasses. */ duplicates of virtual baseclasses. */
if (n_baseclasses > 0) if (n_baseclasses > 0)
cp_print_value (type, real_type, valaddr, offset, address, stream, cp_print_value (type, real_type, valaddr,
recurse + 1, val, options, dont_print_vb); offset, address, stream,
recurse + 1, val, options,
dont_print_vb);
/* Second, print out data fields */ /* Second, print out data fields */
@ -253,11 +264,13 @@ cp_print_value_fields (struct type *type, struct type *real_type,
fputs_filtered ("\"( nodef \"", stream); fputs_filtered ("\"( nodef \"", stream);
if (field_is_static (&TYPE_FIELD (type, i))) if (field_is_static (&TYPE_FIELD (type, i)))
fputs_filtered ("static ", stream); fputs_filtered ("static ", stream);
fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), fprintf_symbol_filtered (stream,
TYPE_FIELD_NAME (type, i),
current_language->la_language, current_language->la_language,
DMGL_PARAMS | DMGL_ANSI); DMGL_PARAMS | DMGL_ANSI);
fputs_filtered ("\" \"", stream); fputs_filtered ("\" \"", stream);
fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), fprintf_symbol_filtered (stream,
TYPE_FIELD_NAME (type, i),
current_language->la_language, current_language->la_language,
DMGL_PARAMS | DMGL_ANSI); DMGL_PARAMS | DMGL_ANSI);
fputs_filtered ("\") \"", stream); fputs_filtered ("\") \"", stream);
@ -268,11 +281,13 @@ cp_print_value_fields (struct type *type, struct type *real_type,
if (field_is_static (&TYPE_FIELD (type, i))) if (field_is_static (&TYPE_FIELD (type, i)))
fputs_filtered ("static ", stream); fputs_filtered ("static ", stream);
fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), fprintf_symbol_filtered (stream,
TYPE_FIELD_NAME (type, i),
current_language->la_language, current_language->la_language,
DMGL_PARAMS | DMGL_ANSI); DMGL_PARAMS | DMGL_ANSI);
annotate_field_name_end (); annotate_field_name_end ();
/* do not print leading '=' in case of anonymous unions */ /* Do not print leading '=' in case of anonymous
unions. */
if (strcmp (TYPE_FIELD_NAME (type, i), "")) if (strcmp (TYPE_FIELD_NAME (type, i), ""))
fputs_filtered (" = ", stream); fputs_filtered (" = ", stream);
annotate_field_value (); annotate_field_value ();
@ -283,8 +298,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
{ {
struct value *v; struct value *v;
/* Bitfields require special handling, especially due to byte /* Bitfields require special handling, especially due to
order problems. */ byte order problems. */
if (TYPE_FIELD_IGNORE (type, i)) if (TYPE_FIELD_IGNORE (type, i))
{ {
fputs_filtered ("<optimized out or zero length>", stream); fputs_filtered ("<optimized out or zero length>", stream);
@ -297,7 +312,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
{ {
fputs_filtered (_("<synthetic pointer>"), stream); fputs_filtered (_("<synthetic pointer>"), stream);
} }
else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i), else if (!value_bits_valid (val,
TYPE_FIELD_BITPOS (type, i),
TYPE_FIELD_BITSIZE (type, i))) TYPE_FIELD_BITSIZE (type, i)))
{ {
fputs_filtered (_("<value optimized out>"), stream); fputs_filtered (_("<value optimized out>"), stream);
@ -319,7 +335,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
{ {
if (TYPE_FIELD_IGNORE (type, i)) if (TYPE_FIELD_IGNORE (type, i))
{ {
fputs_filtered ("<optimized out or zero length>", stream); fputs_filtered ("<optimized out or zero length>",
stream);
} }
else if (field_is_static (&TYPE_FIELD (type, i))) else if (field_is_static (&TYPE_FIELD (type, i)))
{ {
@ -328,8 +345,9 @@ cp_print_value_fields (struct type *type, struct type *real_type,
if (v == NULL) if (v == NULL)
fputs_filtered ("<optimized out>", stream); fputs_filtered ("<optimized out>", stream);
else else
cp_print_static_field (TYPE_FIELD_TYPE (type, i), v, cp_print_static_field (TYPE_FIELD_TYPE (type, i),
stream, recurse + 1, options); v, stream, recurse + 1,
options);
} }
else else
{ {
@ -337,7 +355,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
opts.deref_ref = 0; opts.deref_ref = 0;
val_print (TYPE_FIELD_TYPE (type, i), val_print (TYPE_FIELD_TYPE (type, i),
valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, valaddr,
offset + TYPE_FIELD_BITPOS (type, i) / 8,
address, address,
stream, recurse + 1, val, &opts, stream, recurse + 1, val, &opts,
current_language); current_language);
@ -351,7 +370,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
int obstack_final_size = int obstack_final_size =
obstack_object_size (&dont_print_statmem_obstack); obstack_object_size (&dont_print_statmem_obstack);
if (obstack_final_size > statmem_obstack_initial_size) { if (obstack_final_size > statmem_obstack_initial_size)
{
/* In effect, a pop of the printed-statics stack. */ /* In effect, a pop of the printed-statics stack. */
void *free_to_ptr = void *free_to_ptr =
@ -370,8 +390,9 @@ cp_print_value_fields (struct type *type, struct type *real_type,
if (obstack_final_size > stat_array_obstack_initial_size) if (obstack_final_size > stat_array_obstack_initial_size)
{ {
void *free_to_ptr = void *free_to_ptr =
obstack_next_free (&dont_print_stat_array_obstack) - obstack_next_free (&dont_print_stat_array_obstack)
(obstack_final_size - stat_array_obstack_initial_size); - (obstack_final_size
- stat_array_obstack_initial_size);
obstack_free (&dont_print_stat_array_obstack, obstack_free (&dont_print_stat_array_obstack,
free_to_ptr); free_to_ptr);
@ -419,9 +440,9 @@ cp_print_value_fields_rtti (struct type *type,
/* Ugh, we have to convert back to a value here. */ /* Ugh, we have to convert back to a value here. */
value = value_from_contents_and_address (type, valaddr + offset, value = value_from_contents_and_address (type, valaddr + offset,
address + offset); address + offset);
/* We don't actually care about most of the result here -- just the /* We don't actually care about most of the result here -- just
type. We already have the correct offset, due to how val_print the type. We already have the correct offset, due to how
was initially called. */ val_print was initially called. */
real_type = value_rtti_type (value, &full, &top, &using_enc); real_type = value_rtti_type (value, &full, &top, &using_enc);
} }
@ -433,14 +454,14 @@ cp_print_value_fields_rtti (struct type *type,
dont_print_vb, dont_print_statmem); dont_print_vb, dont_print_statmem);
} }
/* Special val_print routine to avoid printing multiple copies of virtual /* Special val_print routine to avoid printing multiple copies of
baseclasses. */ virtual baseclasses. */
static void static void
cp_print_value (struct type *type, struct type *real_type, cp_print_value (struct type *type, struct type *real_type,
const gdb_byte *valaddr, int offset, CORE_ADDR address, const gdb_byte *valaddr, int offset,
struct ui_file *stream, int recurse, CORE_ADDR address, struct ui_file *stream,
const struct value *val, int recurse, const struct value *val,
const struct value_print_options *options, const struct value_print_options *options,
struct type **dont_print_vb) struct type **dont_print_vb)
{ {
@ -453,9 +474,9 @@ cp_print_value (struct type *type, struct type *real_type,
if (dont_print_vb == 0) if (dont_print_vb == 0)
{ {
/* If we're at top level, carve out a completely fresh /* If we're at top level, carve out a completely fresh chunk of
chunk of the obstack and use that until this particular the obstack and use that until this particular invocation
invocation returns. */ returns. */
/* Bump up the high-water mark. Now alpha is omega. */ /* Bump up the high-water mark. Now alpha is omega. */
obstack_finish (&dont_print_vb_obstack); obstack_finish (&dont_print_vb_obstack);
} }
@ -473,8 +494,8 @@ cp_print_value (struct type *type, struct type *real_type,
struct type **first_dont_print struct type **first_dont_print
= (struct type **) obstack_base (&dont_print_vb_obstack); = (struct type **) obstack_base (&dont_print_vb_obstack);
int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) int j = (struct type **)
- first_dont_print; obstack_next_free (&dont_print_vb_obstack) - first_dont_print;
while (--j >= 0) while (--j >= 0)
if (baseclass == first_dont_print[j]) if (baseclass == first_dont_print[j])
@ -486,20 +507,22 @@ cp_print_value (struct type *type, struct type *real_type,
thisoffset = offset; thisoffset = offset;
thistype = real_type; thistype = real_type;
boffset = baseclass_offset (type, i, valaddr + offset, address + offset); boffset = baseclass_offset (type, i, valaddr + offset,
address + offset);
skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1; skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
if (BASETYPE_VIA_VIRTUAL (type, i)) if (BASETYPE_VIA_VIRTUAL (type, i))
{ {
/* The virtual base class pointer might have been /* The virtual base class pointer might have been clobbered
clobbered by the user program. Make sure that it by the user program. Make sure that it still points to a
still points to a valid memory location. */ valid memory location. */
if (boffset != -1 if (boffset != -1
&& ((boffset + offset) < 0 && ((boffset + offset) < 0
|| (boffset + offset) >= TYPE_LENGTH (real_type))) || (boffset + offset) >= TYPE_LENGTH (real_type)))
{ {
/* FIXME (alloca): unsafe if baseclass is really really large. */ /* FIXME (alloca): unsafe if baseclass is really really
large. */
gdb_byte *buf = alloca (TYPE_LENGTH (baseclass)); gdb_byte *buf = alloca (TYPE_LENGTH (baseclass));
base_valaddr = buf; base_valaddr = buf;
@ -517,15 +540,15 @@ cp_print_value (struct type *type, struct type *real_type,
else else
base_valaddr = valaddr; base_valaddr = valaddr;
/* now do the printing */ /* Now do the printing. */
if (options->pretty) if (options->pretty)
{ {
fprintf_filtered (stream, "\n"); fprintf_filtered (stream, "\n");
print_spaces_filtered (2 * recurse, stream); print_spaces_filtered (2 * recurse, stream);
} }
fputs_filtered ("<", stream); fputs_filtered ("<", stream);
/* Not sure what the best notation is in the case where there is no /* Not sure what the best notation is in the case where there is
baseclass name. */ no baseclass name. */
fputs_filtered (basename ? basename : "", stream); fputs_filtered (basename ? basename : "", stream);
fputs_filtered ("> = ", stream); fputs_filtered ("> = ", stream);
@ -542,8 +565,8 @@ cp_print_value (struct type *type, struct type *real_type,
result = apply_val_pretty_printer (baseclass, base_valaddr, result = apply_val_pretty_printer (baseclass, base_valaddr,
thisoffset + boffset, thisoffset + boffset,
address, address,
stream, recurse, val, stream, recurse,
options, val, options,
current_language); current_language);
if (!result) if (!result)
@ -571,11 +594,10 @@ cp_print_value (struct type *type, struct type *real_type,
} }
} }
/* Print value of a static member. /* Print value of a static member. To avoid infinite recursion when
To avoid infinite recursion when printing a class that contains printing a class that contains a static instance of the class, we
a static instance of the class, we keep the addresses of all printed keep the addresses of all printed static member classes in an
static member classes in an obstack and refuse to print them more obstack and refuse to print them more than once.
than once.
VAL contains the value to print, TYPE, STREAM, RECURSE, and OPTIONS VAL contains the value to print, TYPE, STREAM, RECURSE, and OPTIONS
have the same meanings as in c_val_print. */ have the same meanings as in c_val_print. */
@ -618,8 +640,8 @@ cp_print_static_field (struct type *type,
cp_print_value_fields (type, value_enclosing_type (val), cp_print_value_fields (type, value_enclosing_type (val),
value_contents_for_printing (val), value_contents_for_printing (val),
value_embedded_offset (val), addr, value_embedded_offset (val), addr,
stream, recurse, stream, recurse, val,
val, options, NULL, 1); options, NULL, 1);
return; return;
} }
@ -645,23 +667,25 @@ cp_print_static_field (struct type *type,
} }
} }
obstack_grow (&dont_print_stat_array_obstack, (char *) &target_type, obstack_grow (&dont_print_stat_array_obstack,
(char *) &target_type,
sizeof (struct type *)); sizeof (struct type *));
} }
opts = *options; opts = *options;
opts.deref_ref = 0; opts.deref_ref = 0;
val_print (type, value_contents_for_printing (val), val_print (type, value_contents_for_printing (val),
value_embedded_offset (val), value_address (val), value_embedded_offset (val),
stream, recurse, value_address (val),
val, &opts, current_language); stream, recurse, val,
&opts, current_language);
} }
/* Find the field in *DOMAIN, or its non-virtual base classes, with bit offset /* Find the field in *DOMAIN, or its non-virtual base classes, with
OFFSET. Set *DOMAIN to the containing type and *FIELDNO to the containing bit offset OFFSET. Set *DOMAIN to the containing type and *FIELDNO
field number. If OFFSET is not exactly at the start of some field, set to the containing field number. If OFFSET is not exactly at the
*DOMAIN to NULL. */ start of some field, set *DOMAIN to NULL. */
static void static void
cp_find_class_member (struct type **domain_p, int *fieldno, cp_find_class_member (struct type **domain_p, int *fieldno,
@ -716,7 +740,9 @@ cp_print_class_member (const gdb_byte *valaddr, struct type *type,
LONGEST val; LONGEST val;
unsigned int fieldno; unsigned int fieldno;
val = extract_signed_integer (valaddr, TYPE_LENGTH (type), byte_order); val = extract_signed_integer (valaddr,
TYPE_LENGTH (type),
byte_order);
/* Pointers to data members are usually byte offsets into an object. /* Pointers to data members are usually byte offsets into an object.
Because a data member can have offset zero, and a NULL pointer to Because a data member can have offset zero, and a NULL pointer to
@ -781,7 +807,10 @@ Show printing of object's derived type based on vtable info."), NULL,
show_objectprint, show_objectprint,
&setprintlist, &showprintlist); &setprintlist, &showprintlist);
obstack_begin (&dont_print_stat_array_obstack, 32 * sizeof (struct type *)); obstack_begin (&dont_print_stat_array_obstack,
obstack_begin (&dont_print_statmem_obstack, 32 * sizeof (CORE_ADDR)); 32 * sizeof (struct type *));
obstack_begin (&dont_print_vb_obstack, 32 * sizeof (struct type *)); obstack_begin (&dont_print_statmem_obstack,
32 * sizeof (CORE_ADDR));
obstack_begin (&dont_print_vb_obstack,
32 * sizeof (struct type *));
} }