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:
parent
db09a73fa4
commit
aff410f180
24 changed files with 1489 additions and 1076 deletions
|
@ -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.
|
||||||
|
|
145
gdb/c-lang.c
145
gdb/c-lang.c
|
@ -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 */
|
||||||
|
|
26
gdb/c-lang.h
26
gdb/c-lang.h
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
206
gdb/c-valprint.c
206
gdb/c-valprint.c
|
@ -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,
|
||||||
¤t_target);
|
¤t_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),
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
455
gdb/coffread.c
455
gdb/coffread.c
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
189
gdb/completer.c
189
gdb/completer.c
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
30
gdb/cp-abi.c
30
gdb/cp-abi.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
70
gdb/cp-abi.h
70
gdb/cp-abi.h
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
155
gdb/cp-support.c
155
gdb/cp-support.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 *));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue