mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-03 23:56:39 +00:00
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
@ -11,6 +11,30 @@
|
||||
* breakpoint.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>
|
||||
|
||||
* bfin-tdep.c (bfin_register_type): Move || to start of line.
|
||||
|
147
gdb/c-lang.c
147
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
|
||||
the enum constant representing the character type. Also set
|
||||
*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
|
||||
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. */
|
||||
|
||||
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)
|
||||
{
|
||||
@ -175,8 +177,10 @@ append_string_as_wide (const char *string, struct obstack *output)
|
||||
escapes across calls. */
|
||||
|
||||
static void
|
||||
print_wchar (gdb_wint_t w, const gdb_byte *orig, int orig_len,
|
||||
int width, enum bfd_endian byte_order, struct obstack *output,
|
||||
print_wchar (gdb_wint_t w, const gdb_byte *orig,
|
||||
int orig_len, int width,
|
||||
enum bfd_endian byte_order,
|
||||
struct obstack *output,
|
||||
int quoter, int *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];
|
||||
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
|
||||
way. Otherwise, print it as a hex escape. */
|
||||
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
|
||||
string whose delimiter is QUOTER. Note that that format for printing
|
||||
characters and strings is language specific. */
|
||||
/* Print the character C on STREAM as part of the contents of a
|
||||
literal string whose delimiter is QUOTER. Note that that format
|
||||
for printing characters and strings is language specific. */
|
||||
|
||||
void
|
||||
c_emit_char (int c, struct type *type,
|
||||
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 cleanup *cleanups;
|
||||
const char *encoding;
|
||||
@ -273,8 +279,8 @@ c_emit_char (int c, struct type *type,
|
||||
buf = alloca (TYPE_LENGTH (type));
|
||||
pack_long (buf, type, c);
|
||||
|
||||
iter = make_wchar_iterator (buf, TYPE_LENGTH (type), encoding,
|
||||
TYPE_LENGTH (type));
|
||||
iter = make_wchar_iterator (buf, TYPE_LENGTH (type),
|
||||
encoding, TYPE_LENGTH (type));
|
||||
cleanups = make_cleanup_wchar_iterator (iter);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
for (i = 0; i < num_chars; ++i)
|
||||
print_wchar (chars[i], buf, buflen, TYPE_LENGTH (type),
|
||||
byte_order, &wchar_buf, quoter, &need_escape);
|
||||
print_wchar (chars[i], buf, buflen,
|
||||
TYPE_LENGTH (type), byte_order,
|
||||
&wchar_buf, quoter, &need_escape);
|
||||
}
|
||||
}
|
||||
|
||||
/* This handles the NUM_CHARS == 0 case as well. */
|
||||
if (print_escape)
|
||||
print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type), byte_order,
|
||||
&wchar_buf, quoter, &need_escape);
|
||||
print_wchar (gdb_WEOF, buf, buflen, TYPE_LENGTH (type),
|
||||
byte_order, &wchar_buf, quoter, &need_escape);
|
||||
}
|
||||
|
||||
/* The output in the host encoding. */
|
||||
@ -365,15 +372,17 @@ c_printchar (int c, struct type *type, struct ui_file *stream)
|
||||
fputc_filtered ('\'', stream);
|
||||
}
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
LENGTH is -1 if the string is nul terminated. Each character is WIDTH bytes
|
||||
long. Printing stops early if the number hits print_max; repeat counts are
|
||||
printed as appropriate. Print ellipses at the end if we had to stop before
|
||||
printing LENGTH characters, or if FORCE_ELLIPSES. */
|
||||
/* Print the character string STRING, printing at most LENGTH
|
||||
characters. LENGTH is -1 if the string is nul terminated. Each
|
||||
character is WIDTH bytes long. Printing stops early if the number
|
||||
hits print_max; repeat counts are printed as appropriate. Print
|
||||
ellipses at the end if we had to stop before printing LENGTH
|
||||
characters, or if FORCE_ELLIPSES. */
|
||||
|
||||
void
|
||||
c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
|
||||
unsigned int length, const char *user_encoding, int force_ellipses,
|
||||
c_printstr (struct ui_file *stream, struct type *type,
|
||||
const gdb_byte *string, unsigned int length,
|
||||
const char *user_encoding, int force_ellipses,
|
||||
const struct value_print_options *options)
|
||||
{
|
||||
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
|
||||
the last byte of it is a null, we don't print that, in traditional C
|
||||
style. */
|
||||
the last byte of it is a null, we don't print that, in
|
||||
traditional C style. */
|
||||
if (!force_ellipses
|
||||
&& length > 0
|
||||
&& (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;
|
||||
}
|
||||
|
||||
encoding = (user_encoding && *user_encoding) ? user_encoding : type_encoding;
|
||||
encoding = (user_encoding && *user_encoding)
|
||||
? user_encoding : type_encoding;
|
||||
|
||||
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])
|
||||
{
|
||||
num_chars = wchar_iterate (iter, &result, &chars, &buf, &buflen);
|
||||
num_chars = wchar_iterate (iter, &result, &chars,
|
||||
&buf, &buflen);
|
||||
++reps;
|
||||
}
|
||||
|
||||
@ -536,8 +547,10 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
|
||||
|
||||
while (reps-- > 0)
|
||||
{
|
||||
print_wchar (current_char, orig_buf, orig_len, width,
|
||||
byte_order, &wchar_buf, '"', &need_escape);
|
||||
print_wchar (current_char, orig_buf,
|
||||
orig_len, width,
|
||||
byte_order, &wchar_buf,
|
||||
'"', &need_escape);
|
||||
++things_printed;
|
||||
}
|
||||
}
|
||||
@ -564,8 +577,8 @@ c_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
|
||||
in_quotes = 1;
|
||||
}
|
||||
need_escape = 0;
|
||||
print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf,
|
||||
'"', &need_escape);
|
||||
print_wchar (gdb_WEOF, buf, buflen, width, byte_order,
|
||||
&wchar_buf, '"', &need_escape);
|
||||
break;
|
||||
|
||||
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 ("\","));
|
||||
in_quotes = 0;
|
||||
}
|
||||
obstack_grow_wstr (&wchar_buf, LCST (" <incomplete sequence "));
|
||||
print_wchar (gdb_WEOF, buf, buflen, width, byte_order, &wchar_buf,
|
||||
obstack_grow_wstr (&wchar_buf,
|
||||
LCST (" <incomplete sequence "));
|
||||
print_wchar (gdb_WEOF, buf, buflen, width,
|
||||
byte_order, &wchar_buf,
|
||||
0, &need_escape);
|
||||
obstack_grow_wstr (&wchar_buf, LCST (">"));
|
||||
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
|
||||
buffer in BUFFER, which should be freed by the caller. If the
|
||||
in- and out-parameter *LENGTH is specified at -1, the string is read
|
||||
buffer in BUFFER, which should be freed by the caller. If the in-
|
||||
and out-parameter *LENGTH is specified at -1, the string is read
|
||||
until a null character of the appropriate width is found, otherwise
|
||||
the string is read to the length of characters specified.
|
||||
The size of a character is determined by the length of the target
|
||||
type of the pointer or array. If VALUE is an array with a known
|
||||
length, the function will not read past the end of the array.
|
||||
On completion, *LENGTH will be set to the size of the string read in
|
||||
the string is read to the length of characters specified. The size
|
||||
of a character is determined by the length of the target type of
|
||||
the pointer or array. If VALUE is an array with a known length,
|
||||
the function will not read past the end of the array. On
|
||||
completion, *LENGTH will be set to the size of the string read in
|
||||
characters. (If a length of -1 is specified, the length returned
|
||||
will not include the null character). CHARSET is always set to the
|
||||
target charset. */
|
||||
|
||||
void
|
||||
c_get_string (struct value *value, gdb_byte **buffer, int *length,
|
||||
struct type **char_type, const char **charset)
|
||||
c_get_string (struct value *value, gdb_byte **buffer,
|
||||
int *length, struct type **char_type,
|
||||
const char **charset)
|
||||
{
|
||||
int err, width;
|
||||
unsigned int fetchlimit;
|
||||
struct type *type = check_typedef (value_type (value));
|
||||
struct type *element_type = TYPE_TARGET_TYPE (type);
|
||||
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;
|
||||
|
||||
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 we know the size of the array, we can use it as a limit on the
|
||||
number of characters to be fetched. */
|
||||
/* If we know the size of the array, we can use it as a limit on
|
||||
the number of characters to be fetched. */
|
||||
if (TYPE_NFIELDS (type) == 1
|
||||
&& 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);
|
||||
width = TYPE_LENGTH (element_type);
|
||||
|
||||
/* If the string lives in GDB's memory instead of the inferior's, then we
|
||||
just need to copy it to BUFFER. Also, since such strings are arrays
|
||||
with known size, FETCHLIMIT will hold the size of the array. */
|
||||
/* If the string lives in GDB's memory instead of the inferior's,
|
||||
then we just need to copy it to BUFFER. Also, since such strings
|
||||
are arrays with known size, FETCHLIMIT will hold the size of the
|
||||
array. */
|
||||
if ((VALUE_LVAL (value) == not_lval
|
||||
|| VALUE_LVAL (value) == lval_internalvar)
|
||||
&& fetchlimit != UINT_MAX)
|
||||
@ -686,8 +704,8 @@ c_get_string (struct value *value, gdb_byte **buffer, int *length,
|
||||
else
|
||||
/* Otherwise, look for a null character. */
|
||||
for (i = 0; i < fetchlimit; i++)
|
||||
if (extract_unsigned_integer (contents + i * width, width,
|
||||
byte_order) == 0)
|
||||
if (extract_unsigned_integer (contents + i * width,
|
||||
width, byte_order) == 0)
|
||||
break;
|
||||
|
||||
/* 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 the last character is null, subtract it from LENGTH. */
|
||||
if (*length > 0
|
||||
&& extract_unsigned_integer (*buffer + *length - width, width,
|
||||
byte_order) == 0)
|
||||
&& extract_unsigned_integer (*buffer + *length - width,
|
||||
width, byte_order) == 0)
|
||||
*length -= width;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
convert_between_encodings ("UTF-32BE", dest_charset, data, 4, 4, output,
|
||||
translit_none);
|
||||
convert_between_encodings ("UTF-32BE", dest_charset, data,
|
||||
4, 4, output, translit_none);
|
||||
|
||||
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. */
|
||||
|
||||
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;
|
||||
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. */
|
||||
|
||||
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;
|
||||
|
||||
@ -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 (p > data)
|
||||
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 (p < limit)
|
||||
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_transparent_type,/* lookup_transparent_type */
|
||||
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 */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
@ -1306,7 +1328,8 @@ const struct language_defn cplus_language_defn =
|
||||
cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
|
||||
cp_lookup_transparent_type, /* lookup_transparent_type */
|
||||
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 */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
@ -1344,13 +1367,14 @@ const struct language_defn asm_language_defn =
|
||||
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
|
||||
basic_lookup_transparent_type,/* lookup_transparent_type */
|
||||
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 */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
default_word_break_characters,
|
||||
default_make_symbol_completion_list,
|
||||
c_language_arch_info, /* FIXME: la_language_arch_info. */
|
||||
c_language_arch_info, /* FIXME: la_language_arch_info. */
|
||||
default_print_array_index,
|
||||
default_pass_by_reference,
|
||||
c_get_string,
|
||||
@ -1387,7 +1411,8 @@ const struct language_defn minimal_language_defn =
|
||||
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
|
||||
basic_lookup_transparent_type,/* lookup_transparent_type */
|
||||
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 */
|
||||
1, /* c-style arrays */
|
||||
0, /* String lower bound */
|
||||
|
28
gdb/c-lang.h
28
gdb/c-lang.h
@ -64,12 +64,15 @@ extern void c_error (char *);
|
||||
extern int c_parse_escape (char **, struct obstack *);
|
||||
|
||||
/* Defined in c-typeprint.c */
|
||||
extern void c_print_type (struct type *, const char *, struct ui_file *, int,
|
||||
int);
|
||||
extern void c_print_type (struct type *, const char *,
|
||||
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,
|
||||
const struct value *,
|
||||
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: */
|
||||
|
||||
extern struct value *evaluate_subexp_c (struct type *expect_type,
|
||||
struct expression *exp, int *pos,
|
||||
enum noside noside);
|
||||
struct expression *exp,
|
||||
int *pos,
|
||||
enum noside noside);
|
||||
|
||||
extern void c_printchar (int, struct type *, struct ui_file *);
|
||||
|
||||
extern void c_printstr (struct ui_file * stream, struct type *elttype,
|
||||
const gdb_byte *string, unsigned int length,
|
||||
const char *user_encoding, int force_ellipses,
|
||||
extern void c_printstr (struct ui_file * stream,
|
||||
struct type *elttype,
|
||||
const gdb_byte *string,
|
||||
unsigned int length,
|
||||
const char *user_encoding,
|
||||
int force_ellipses,
|
||||
const struct value_print_options *options);
|
||||
|
||||
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: */
|
||||
|
||||
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 */
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include "bfd.h" /* Binary File Description */
|
||||
#include "bfd.h" /* Binary File Description. */
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
@ -36,17 +36,21 @@
|
||||
#include "gdb_string.h"
|
||||
#include <errno.h>
|
||||
|
||||
static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
|
||||
int, int);
|
||||
static void c_type_print_varspec_prefix (struct type *,
|
||||
struct ui_file *,
|
||||
int, int, int);
|
||||
|
||||
/* Print "const", "volatile", or address space modifiers. */
|
||||
static void c_type_print_modifier (struct type *, struct ui_file *,
|
||||
/* Print "const", "volatile", or address space modifiers. */
|
||||
static void c_type_print_modifier (struct type *,
|
||||
struct ui_file *,
|
||||
int, int);
|
||||
|
||||
/* LEVEL is the depth to indent lines by. */
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
/* For demangled function names, we have the arglist as part of the name,
|
||||
so don't print an additional pair of ()'s */
|
||||
/* For demangled function names, we have the arglist as part of
|
||||
the name, so don't print an additional pair of ()'s */
|
||||
|
||||
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. */
|
||||
|
||||
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)
|
||||
{
|
||||
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.
|
||||
Print only the actual base classes of this type, not the base classes
|
||||
of the base classes. I.E. for the derivation hierarchy:
|
||||
Print only the actual base classes of this type, not the base
|
||||
classes of the base classes. I.e. for the derivation hierarchy:
|
||||
|
||||
class A { int a; };
|
||||
class B : public A {int b; };
|
||||
@ -117,21 +123,25 @@ c_print_typedef (struct type *type, struct symbol *new_symbol,
|
||||
int c;
|
||||
}
|
||||
|
||||
Not as the following (like gdb used to), which is not legal C++ syntax for
|
||||
derived types and may be confused with the multiple inheritance form:
|
||||
Not as the following (like gdb used to), which is not legal C++
|
||||
syntax for derived types and may be confused with the multiple
|
||||
inheritance form:
|
||||
|
||||
class C : public B : public A {
|
||||
int c;
|
||||
}
|
||||
|
||||
In general, gdb should try to print the types as closely as 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
|
||||
derivation via protected inheritance, so gdb can print it out */
|
||||
In general, gdb should try to print the types as closely as
|
||||
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 derivation via protected inheritance, so gdb can
|
||||
print it out */
|
||||
|
||||
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;
|
||||
int i;
|
||||
@ -140,8 +150,9 @@ cp_type_print_derivation_info (struct ui_file *stream, struct type *type)
|
||||
{
|
||||
fputs_filtered (i == 0 ? ": " : ", ", stream);
|
||||
fprintf_filtered (stream, "%s%s ",
|
||||
BASETYPE_VIA_PUBLIC (type, i) ? "public"
|
||||
: (TYPE_FIELD_PROTECTED (type, i) ? "protected" : "private"),
|
||||
BASETYPE_VIA_PUBLIC (type, i)
|
||||
? "public" : (TYPE_FIELD_PROTECTED (type, i)
|
||||
? "protected" : "private"),
|
||||
BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : "");
|
||||
name = type_name_no_tag (TYPE_BASECLASS (type, i));
|
||||
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. */
|
||||
|
||||
static void
|
||||
cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring,
|
||||
int staticp, struct ui_file *stream)
|
||||
cp_type_print_method_args (struct type *mtype, char *prefix,
|
||||
char *varstring, int staticp,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
struct field *args = TYPE_FIELDS (mtype);
|
||||
int nargs = TYPE_NFIELDS (mtype);
|
||||
int varargs = TYPE_VARARGS (mtype);
|
||||
int i;
|
||||
|
||||
fprintf_symbol_filtered (stream, prefix, language_cplus, DMGL_ANSI);
|
||||
fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI);
|
||||
fprintf_symbol_filtered (stream, prefix,
|
||||
language_cplus, DMGL_ANSI);
|
||||
fprintf_symbol_filtered (stream, varstring,
|
||||
language_cplus, DMGL_ANSI);
|
||||
fputs_filtered ("(", stream);
|
||||
|
||||
/* Skip the class variable. */
|
||||
@ -220,8 +234,10 @@ cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring,
|
||||
name. */
|
||||
|
||||
static void
|
||||
c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
|
||||
int show, int passed_a_ptr, int need_post_space)
|
||||
c_type_print_varspec_prefix (struct type *type,
|
||||
struct ui_file *stream,
|
||||
int show, int passed_a_ptr,
|
||||
int need_post_space)
|
||||
{
|
||||
char *name;
|
||||
|
||||
@ -236,53 +252,62 @@ c_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
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, "*");
|
||||
c_type_print_modifier (type, stream, 1, need_post_space);
|
||||
break;
|
||||
|
||||
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));
|
||||
if (name)
|
||||
fputs_filtered (name, stream);
|
||||
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, "::*");
|
||||
break;
|
||||
|
||||
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, "(");
|
||||
name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
|
||||
if (name)
|
||||
fputs_filtered (name, stream);
|
||||
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, "::*");
|
||||
break;
|
||||
|
||||
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, "&");
|
||||
c_type_print_modifier (type, stream, 1, need_post_space);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_METHOD:
|
||||
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)
|
||||
fprintf_filtered (stream, "(");
|
||||
break;
|
||||
|
||||
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)
|
||||
fprintf_filtered (stream, "(");
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this"
|
||||
in non-static methods, are displayed if SHOW_ARTIFICIAL is
|
||||
non-zero. LANGUAGE is the language in which TYPE was defined. This is
|
||||
a necessary evil since this code is used by the C, C++, and Java
|
||||
backends. */
|
||||
non-zero. LANGUAGE is the language in which TYPE was defined.
|
||||
This is a necessary evil since this code is used by the C, C++, and
|
||||
Java backends. */
|
||||
|
||||
void
|
||||
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)
|
||||
java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
|
||||
java_print_type (TYPE_FIELD_TYPE (type, i),
|
||||
"", stream, -1, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -466,7 +493,8 @@ is_type_conversion_operator (struct type *type, int i, int j)
|
||||
return 1;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -481,14 +509,14 @@ is_type_conversion_operator (struct type *type, int i, int j)
|
||||
static char *
|
||||
remove_qualifiers (char *qid)
|
||||
{
|
||||
int quoted = 0; /* zero if we're not in quotes;
|
||||
'"' if we're in a double-quoted string;
|
||||
'\'' if we're in a single-quoted string. */
|
||||
int depth = 0; /* number of unclosed parens we've seen */
|
||||
int quoted = 0; /* zero if we're not in quotes;
|
||||
'"' if we're in a double-quoted string;
|
||||
'\'' if we're in a single-quoted string. */
|
||||
int depth = 0; /* number of unclosed parens we've seen */
|
||||
char *parenstack = (char *) alloca (strlen (qid));
|
||||
char *scan;
|
||||
char *last = 0; /* The character after the rightmost
|
||||
`::' token we've seen so far. */
|
||||
char *last = 0; /* The character after the rightmost
|
||||
`::' token we've seen so far. */
|
||||
|
||||
for (scan = qid; *scan; scan++)
|
||||
{
|
||||
@ -504,8 +532,8 @@ remove_qualifiers (char *qid)
|
||||
/* If we're inside parenthesis (i.e., an argument list) or
|
||||
angle brackets (i.e., a list of template arguments), then
|
||||
we don't record the position of this :: token, since it's
|
||||
not relevant to the top-level structure we're trying
|
||||
to operate on. */
|
||||
not relevant to the top-level structure we're trying to
|
||||
operate on. */
|
||||
if (depth == 0)
|
||||
{
|
||||
last = scan + 2;
|
||||
@ -529,10 +557,10 @@ remove_qualifiers (char *qid)
|
||||
depth--;
|
||||
else
|
||||
{
|
||||
/* We're going to do a little error recovery here. If we
|
||||
don't find a match for *scan on the paren stack, but
|
||||
there is something lower on the stack that does match, we
|
||||
pop the stack to that point. */
|
||||
/* We're going to do a little error recovery here. If
|
||||
we don't find a match for *scan on the paren stack,
|
||||
but there is something lower on the stack that does
|
||||
match, we pop the stack to that point. */
|
||||
int i;
|
||||
|
||||
for (i = depth - 1; i >= 0; i--)
|
||||
@ -558,8 +586,10 @@ remove_qualifiers (char *qid)
|
||||
Args work like c_type_print_varspec_prefix. */
|
||||
|
||||
void
|
||||
c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
|
||||
int show, int passed_a_ptr, int demangled_args)
|
||||
c_type_print_varspec_suffix (struct type *type,
|
||||
struct ui_file *stream,
|
||||
int show, int passed_a_ptr,
|
||||
int demangled_args)
|
||||
{
|
||||
if (type == 0)
|
||||
return;
|
||||
@ -580,29 +610,30 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
|
||||
|
||||
fprintf_filtered (stream, "[");
|
||||
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, "]");
|
||||
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
|
||||
0, 0);
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
||||
show, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_CODE_MEMBERPTR:
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
|
||||
0, 0);
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
||||
show, 0, 0);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_METHODPTR:
|
||||
fprintf_filtered (stream, ")");
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
|
||||
0, 0);
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
||||
show, 0, 0);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_REF:
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
|
||||
1, 0);
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
||||
show, 1, 0);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_METHOD:
|
||||
@ -610,14 +641,15 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
|
||||
if (passed_a_ptr)
|
||||
fprintf_filtered (stream, ")");
|
||||
if (!demangled_args)
|
||||
c_type_print_args (type, stream, 1, current_language->la_language);
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
|
||||
passed_a_ptr, 0);
|
||||
c_type_print_args (type, stream, 1,
|
||||
current_language->la_language);
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
||||
show, passed_a_ptr, 0);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
|
||||
passed_a_ptr, 0);
|
||||
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
||||
show, passed_a_ptr, 0);
|
||||
break;
|
||||
|
||||
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_DECFLOAT:
|
||||
/* 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;
|
||||
default:
|
||||
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,
|
||||
function value or array element), or the description of a
|
||||
structure or union.
|
||||
function value or array element), or the description of a structure
|
||||
or union.
|
||||
|
||||
SHOW positive means print details about the type (e.g. enum 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
|
||||
"struct {...}".
|
||||
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;}".
|
||||
SHOW positive means print details about the type (e.g. enum
|
||||
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 "struct {...}".
|
||||
|
||||
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.
|
||||
We increase it for some recursive calls. */
|
||||
|
||||
void
|
||||
c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
int level)
|
||||
c_type_print_base (struct type *type, struct ui_file *stream,
|
||||
int show, int level)
|
||||
{
|
||||
int i;
|
||||
int len, real_len;
|
||||
@ -689,11 +724,12 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
return;
|
||||
}
|
||||
|
||||
/* When SHOW is zero or less, and there is a valid type name, then always
|
||||
just print the type name directly from the type. */
|
||||
/* If we have "typedef struct foo {. . .} bar;" do we want to print it
|
||||
as "struct foo" or as "bar"? Pick the latter, because C++ folk tend
|
||||
to expect things like "class5 *foo" rather than "struct class5 *foo". */
|
||||
/* When SHOW is zero or less, and there is a valid type name, then
|
||||
always just print the type name directly from the type. */
|
||||
/* If we have "typedef struct foo {. . .} bar;" do we want to print
|
||||
it as "struct foo" or as "bar"? Pick the latter, because C++
|
||||
folk tend to expect things like "class5 *foo" rather than "struct
|
||||
class5 *foo". */
|
||||
|
||||
if (show <= 0
|
||||
&& 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))
|
||||
{
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
/* If we get here, the typedef doesn't have a name, and we couldn't
|
||||
resolve TYPE_TARGET_TYPE. Not much we can do. */
|
||||
/* If we get here, the typedef doesn't have a name, and we
|
||||
couldn't resolve TYPE_TARGET_TYPE. Not much we can do. */
|
||||
gdb_assert (TYPE_NAME (type) == NULL);
|
||||
gdb_assert (TYPE_TARGET_TYPE (type) == NULL);
|
||||
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_METHOD:
|
||||
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;
|
||||
|
||||
case TYPE_CODE_STRUCT:
|
||||
@ -739,12 +776,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
|
||||
struct_union:
|
||||
|
||||
/* Print the tag if it exists.
|
||||
* The HP aCC compiler emits
|
||||
* a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}"
|
||||
* tag for unnamed struct/union/enum's, which we don't
|
||||
* want to print.
|
||||
*/
|
||||
/* Print the tag if it exists. The HP aCC compiler emits a
|
||||
spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed
|
||||
enum}" tag for unnamed struct/union/enum's, which we don't
|
||||
want to print. */
|
||||
if (TYPE_TAG_NAME (type) != NULL
|
||||
&& 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 (" ");
|
||||
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)
|
||||
fprintf_filtered (stream, "{...}");
|
||||
}
|
||||
@ -771,21 +807,23 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
&& TYPE_TYPEDEF_FIELD_COUNT (type) == 0)
|
||||
{
|
||||
if (TYPE_STUB (type))
|
||||
fprintfi_filtered (level + 4, stream, _("<incomplete type>\n"));
|
||||
fprintfi_filtered (level + 4, stream,
|
||||
_("<incomplete type>\n"));
|
||||
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
|
||||
one for the first field we find, and use that section type
|
||||
thereafter until we find another type. */
|
||||
thereafter until we find another type. */
|
||||
|
||||
section_type = s_none;
|
||||
|
||||
/* For a class, if all members are private, there's no need
|
||||
for a "private:" label; similarly, for a struct or union
|
||||
masquerading as a class, if all members are public, there's
|
||||
no need for a "public:" label. */
|
||||
no need for a "public:" label. */
|
||||
|
||||
if (TYPE_DECLARED_CLASS (type))
|
||||
{
|
||||
@ -820,7 +858,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
QUIT;
|
||||
len = TYPE_NFIELDS (type);
|
||||
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;
|
||||
break;
|
||||
@ -878,7 +917,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
if (section_type != s_private)
|
||||
{
|
||||
section_type = s_private;
|
||||
fprintfi_filtered (level + 2, stream, "private:\n");
|
||||
fprintfi_filtered (level + 2, stream,
|
||||
"private:\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -886,7 +926,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
if (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
|
||||
between them. Make sure to count only method that we will
|
||||
display; artificial methods will be hidden. */
|
||||
between them. Make sure to count only method that we
|
||||
will display; artificial methods will be hidden. */
|
||||
len = TYPE_NFN_FIELDS (type);
|
||||
real_len = 0;
|
||||
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);
|
||||
char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
|
||||
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++)
|
||||
{
|
||||
@ -965,7 +1007,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
if (section_type != s_private)
|
||||
{
|
||||
section_type = s_private;
|
||||
fprintfi_filtered (level + 2, stream, "private:\n");
|
||||
fprintfi_filtered (level + 2, stream,
|
||||
"private:\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -973,7 +1016,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
if (section_type != s_public)
|
||||
{
|
||||
section_type = s_public;
|
||||
fprintfi_filtered (level + 2, stream, "public:\n");
|
||||
fprintfi_filtered (level + 2, stream,
|
||||
"public:\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -985,12 +1029,15 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
|
||||
{
|
||||
/* 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));
|
||||
break;
|
||||
}
|
||||
else if (!is_constructor /* constructors don't have declared types */
|
||||
&& !is_full_physname_constructor /* " " */
|
||||
else if (!is_constructor /* Constructors don't
|
||||
have declared
|
||||
types. */
|
||||
&& !is_full_physname_constructor /* " " */
|
||||
&& !is_type_conversion_operator (type, i, j))
|
||||
{
|
||||
type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
|
||||
@ -1008,11 +1055,11 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
DMGL_ANSI | DMGL_PARAMS);
|
||||
if (demangled_name == NULL)
|
||||
{
|
||||
/* in some cases (for instance with the HP demangling),
|
||||
if a function has more than 10 arguments,
|
||||
the demangling will fail.
|
||||
Let's try to reconstruct the function signature from
|
||||
the symbol information */
|
||||
/* In some cases (for instance with the HP
|
||||
demangling), if a function has more than 10
|
||||
arguments, the demangling will fail.
|
||||
Let's try to reconstruct the function
|
||||
signature from the symbol information. */
|
||||
if (!TYPE_FN_FIELD_STUB (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);
|
||||
}
|
||||
else
|
||||
fprintf_filtered (stream, _("<badly mangled name '%s'>"),
|
||||
fprintf_filtered (stream,
|
||||
_("<badly mangled name '%s'>"),
|
||||
mangled_name);
|
||||
}
|
||||
else
|
||||
@ -1034,14 +1082,17 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
char *demangled_no_class
|
||||
= 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");
|
||||
if (p != NULL)
|
||||
{
|
||||
int length = p - demangled_no_class;
|
||||
|
||||
demangled_no_static = (char *) xmalloc (length + 1);
|
||||
strncpy (demangled_no_static, demangled_no_class, length);
|
||||
demangled_no_static
|
||||
= (char *) xmalloc (length + 1);
|
||||
strncpy (demangled_no_static,
|
||||
demangled_no_class, length);
|
||||
*(demangled_no_static + length) = '\0';
|
||||
fputs_filtered (demangled_no_static, stream);
|
||||
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, "}");
|
||||
|
||||
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_LINE (type));
|
||||
}
|
||||
@ -1097,7 +1149,7 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
The aCC compiler emits a spurious
|
||||
"{unnamed struct}"/"{unnamed union}"/"{unnamed enum}"
|
||||
tag for unnamed struct/union/enum's, which we don't
|
||||
want to print. */
|
||||
want to print. */
|
||||
if (TYPE_TAG_NAME (type) != NULL
|
||||
&& strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
|
||||
{
|
||||
@ -1109,7 +1161,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
wrap_here (" ");
|
||||
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)
|
||||
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);
|
||||
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++;
|
||||
@ -1159,10 +1213,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Handle types not explicitly handled by the other cases,
|
||||
such as fundamental types. For these, just print whatever
|
||||
the type name is, as recorded in the type itself. If there
|
||||
is no type name, then complain. */
|
||||
/* Handle types not explicitly handled by the other cases, such
|
||||
as fundamental types. For these, just print whatever the
|
||||
type name is, as recorded in the type itself. If there is no
|
||||
type name, then complain. */
|
||||
if (TYPE_NAME (type) != NULL)
|
||||
{
|
||||
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
|
||||
{
|
||||
/* At least for dump_symtab, it is important that this not be
|
||||
an error (). */
|
||||
/* At least for dump_symtab, it is important that this not
|
||||
be an error (). */
|
||||
fprintf_filtered (stream, _("<invalid type code %d>"),
|
||||
TYPE_CODE (type));
|
||||
}
|
||||
|
210
gdb/c-valprint.c
210
gdb/c-valprint.c
@ -36,14 +36,17 @@
|
||||
stream STREAM. */
|
||||
|
||||
static void
|
||||
print_function_pointer_address (struct gdbarch *gdbarch, CORE_ADDR address,
|
||||
struct ui_file *stream, int addressprint)
|
||||
print_function_pointer_address (struct gdbarch *gdbarch,
|
||||
CORE_ADDR address,
|
||||
struct ui_file *stream,
|
||||
int addressprint)
|
||||
{
|
||||
CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
|
||||
¤t_target);
|
||||
CORE_ADDR func_addr
|
||||
= gdbarch_convert_from_func_ptr_addr (gdbarch, address,
|
||||
¤t_target);
|
||||
|
||||
/* If the function pointer is represented by a description, print the
|
||||
address of the description. */
|
||||
/* If the function pointer is represented by a description, print
|
||||
the address of the description. */
|
||||
if (addressprint && func_addr != address)
|
||||
{
|
||||
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
|
||||
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
|
||||
or pointer to integers. FORMAT is the current format letter,
|
||||
or 0 if none.
|
||||
or pointer to integers. FORMAT is the current format letter, or 0
|
||||
if none.
|
||||
|
||||
We guess that "char" is a character. Explicitly signed and
|
||||
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')
|
||||
{
|
||||
/* Print this as a string if we can manage it. For now, no
|
||||
wide character support. */
|
||||
/* Print this as a string if we can manage it. For now, no wide
|
||||
character support. */
|
||||
if (TYPE_CODE (true_type) == TYPE_CODE_INT
|
||||
&& TYPE_LENGTH (true_type) == 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
|
||||
the inferior at address ADDRESS, onto stdio stream STREAM according to
|
||||
OPTIONS. The data at VALADDR is in target byte order.
|
||||
/* Print data of type TYPE located at VALADDR (within GDB), which came
|
||||
from the inferior at address ADDRESS, onto stdio stream STREAM
|
||||
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
|
||||
printed. */
|
||||
If the data are a string pointer, returns the number of string
|
||||
characters printed. */
|
||||
|
||||
int
|
||||
c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
CORE_ADDR address, struct ui_file *stream, int recurse,
|
||||
c_val_print (struct type *type, const gdb_byte *valaddr,
|
||||
int embedded_offset, CORE_ADDR address,
|
||||
struct ui_file *stream, int recurse,
|
||||
const struct value *original_value,
|
||||
const struct value_print_options *options)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_type_arch (type);
|
||||
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;
|
||||
struct type *elttype, *unresolved_elttype;
|
||||
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
|
||||
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,
|
||||
TARGET_CHAR_BIT * embedded_offset,
|
||||
TARGET_CHAR_BIT * TYPE_LENGTH (type)))
|
||||
{
|
||||
/* If requested, look for the first null char and only print
|
||||
elements up to it. */
|
||||
/* If requested, look for the first null char and only
|
||||
print elements up to it. */
|
||||
if (options->stop_print_at_null)
|
||||
{
|
||||
unsigned int temp_len;
|
||||
@ -216,24 +221,28 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
{
|
||||
fprintf_filtered (stream, "{");
|
||||
/* 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))
|
||||
{
|
||||
i = 1;
|
||||
fprintf_filtered (stream, _("%d vtable entries"), len - 1);
|
||||
fprintf_filtered (stream, _("%d vtable entries"),
|
||||
len - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
val_print_array_elements (type, valaddr + embedded_offset,
|
||||
address + embedded_offset, stream,
|
||||
recurse, original_value, options, i);
|
||||
address + embedded_offset,
|
||||
stream, recurse,
|
||||
original_value, options, i);
|
||||
fprintf_filtered (stream, "}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Array of unspecified length: treat like pointer to first elt. */
|
||||
/* Array of unspecified length: treat like pointer to first
|
||||
elt. */
|
||||
addr = address;
|
||||
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 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
|
||||
= 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. */
|
||||
print_function_pointer_address (gdbarch, addr, stream,
|
||||
options->addressprint);
|
||||
/* Return value is irrelevant except for string pointers. */
|
||||
/* Return value is irrelevant except for string
|
||||
pointers. */
|
||||
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
|
||||
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)
|
||||
{
|
||||
i = val_print_string (unresolved_elttype, NULL, addr, -1, stream,
|
||||
options);
|
||||
i = val_print_string (unresolved_elttype, NULL,
|
||||
addr, -1,
|
||||
stream, options);
|
||||
}
|
||||
else if (cp_is_vtbl_member (type))
|
||||
{
|
||||
/* print vtbl's nicely */
|
||||
CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset);
|
||||
/* Print vtbl's nicely. */
|
||||
CORE_ADDR vt_address = unpack_pointer (type,
|
||||
valaddr
|
||||
+ embedded_offset);
|
||||
|
||||
struct minimal_symbol *msymbol =
|
||||
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;
|
||||
|
||||
if (msymbol != NULL)
|
||||
wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), block,
|
||||
VAR_DOMAIN, &is_this_fld);
|
||||
wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol),
|
||||
block, VAR_DOMAIN,
|
||||
&is_this_fld);
|
||||
|
||||
if (wsym)
|
||||
{
|
||||
@ -332,8 +348,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
wtype = unresolved_elttype;
|
||||
}
|
||||
vt_val = value_at (wtype, vt_address);
|
||||
common_val_print (vt_val, stream, recurse + 1, options,
|
||||
current_language);
|
||||
common_val_print (vt_val, stream, recurse + 1,
|
||||
options, current_language);
|
||||
if (options->pretty)
|
||||
{
|
||||
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
|
||||
'\0' if we reached the end. val_print_string takes care including
|
||||
the terminating '\0' if necessary. */
|
||||
/* Return number of characters printed, including the
|
||||
terminating '\0' if we reached the end. val_print_string
|
||||
takes care including the terminating '\0' if
|
||||
necessary. */
|
||||
return i;
|
||||
}
|
||||
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 vtable entry - we only get here if NOT using
|
||||
-fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */
|
||||
int offset = (embedded_offset +
|
||||
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8);
|
||||
struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET);
|
||||
-fvtable_thunks. (Otherwise, look under
|
||||
TYPE_CODE_PTR.) */
|
||||
int offset = (embedded_offset
|
||||
+ TYPE_FIELD_BITPOS (type,
|
||||
VTBL_FNADDR_OFFSET) / 8);
|
||||
struct type *field_type = TYPE_FIELD_TYPE (type,
|
||||
VTBL_FNADDR_OFFSET);
|
||||
CORE_ADDR addr
|
||||
= 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
|
||||
cp_print_value_fields_rtti (type, valaddr,
|
||||
embedded_offset, address, stream,
|
||||
recurse, original_value, options, NULL, 0);
|
||||
embedded_offset, address,
|
||||
stream, recurse,
|
||||
original_value, options,
|
||||
NULL, 0);
|
||||
break;
|
||||
|
||||
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,
|
||||
options, 0, stream);
|
||||
else
|
||||
val_print_type_code_flags (type, valaddr + embedded_offset, stream);
|
||||
val_print_type_code_flags (type, valaddr + embedded_offset,
|
||||
stream);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_FUNC:
|
||||
@ -451,8 +474,9 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
options, 0, stream);
|
||||
break;
|
||||
}
|
||||
/* FIXME, we should consider, at least for ANSI C language, eliminating
|
||||
the distinction made between FUNCs and POINTERs to FUNCs. */
|
||||
/* FIXME, we should consider, at least for ANSI C language,
|
||||
eliminating the distinction made between FUNCs and POINTERs
|
||||
to FUNCs. */
|
||||
fprintf_filtered (stream, "{");
|
||||
type_print (type, "", stream, -1);
|
||||
fprintf_filtered (stream, "} ");
|
||||
@ -483,12 +507,12 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
|
||||
case TYPE_CODE_RANGE:
|
||||
/* FIXME: create_range_type does not set the unsigned bit in a
|
||||
range type (I think it probably should copy it from the target
|
||||
type), so we won't print values which are too large to
|
||||
range type (I think it probably should copy it from the
|
||||
target type), so we won't print values which are too large to
|
||||
fit in a signed integer correctly. */
|
||||
/* FIXME: Doesn't handle ranges of enums correctly. (Can't just
|
||||
print with the target type, though, because the size of our type
|
||||
and the target type might differ). */
|
||||
print with the target type, though, because the size of our
|
||||
type and the target type might differ). */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case TYPE_CODE_INT:
|
||||
@ -503,15 +527,18 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
}
|
||||
else
|
||||
{
|
||||
val_print_type_code_int (type, valaddr + embedded_offset, stream);
|
||||
/* C and C++ has no single byte int type, char is used instead.
|
||||
Since we don't know whether the value is really intended to
|
||||
be used as an integer or a character, print the character
|
||||
equivalent as well. */
|
||||
val_print_type_code_int (type, valaddr + embedded_offset,
|
||||
stream);
|
||||
/* C and C++ has no single byte int type, char is used
|
||||
instead. Since we don't know whether the value is really
|
||||
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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -555,7 +582,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
print_scalar_formatted (valaddr + embedded_offset, type,
|
||||
options, 0, stream);
|
||||
else
|
||||
print_decimal_floating (valaddr + embedded_offset, type, stream);
|
||||
print_decimal_floating (valaddr + embedded_offset,
|
||||
type, stream);
|
||||
break;
|
||||
|
||||
case TYPE_CODE_VOID:
|
||||
@ -567,9 +595,10 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
break;
|
||||
|
||||
case TYPE_CODE_UNDEF:
|
||||
/* This happens (without TYPE_FLAG_STUB set) on systems which don't use
|
||||
dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
|
||||
and no complete type for struct foo in that file. */
|
||||
/* This happens (without TYPE_FLAG_STUB set) on systems which
|
||||
don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a
|
||||
"struct foo *bar" and no complete type for struct foo in that
|
||||
file. */
|
||||
fprintf_filtered (stream, _("<incomplete type>"));
|
||||
break;
|
||||
|
||||
@ -579,7 +608,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
TYPE_TARGET_TYPE (type),
|
||||
options, 0, stream);
|
||||
else
|
||||
print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type),
|
||||
print_floating (valaddr + embedded_offset,
|
||||
TYPE_TARGET_TYPE (type),
|
||||
stream);
|
||||
fprintf_filtered (stream, " + ");
|
||||
if (options->format)
|
||||
@ -596,7 +626,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
|
||||
break;
|
||||
|
||||
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);
|
||||
return (0);
|
||||
@ -635,10 +666,11 @@ c_value_print (struct value *val, struct ui_file *stream,
|
||||
if (TYPE_CODE (val_type) == TYPE_CODE_PTR
|
||||
&& TYPE_NAME (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)))))
|
||||
{
|
||||
/* Print nothing */
|
||||
/* Print nothing. */
|
||||
}
|
||||
else if (options->objectprint
|
||||
&& (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
|
||||
@ -647,35 +679,39 @@ c_value_print (struct value *val, struct ui_file *stream,
|
||||
if (TYPE_CODE(type) == TYPE_CODE_REF)
|
||||
{
|
||||
/* 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;
|
||||
temparg=value_copy(val);
|
||||
deprecated_set_value_type (temparg, lookup_pointer_type (TYPE_TARGET_TYPE(type)));
|
||||
val=temparg;
|
||||
deprecated_set_value_type
|
||||
(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, "(");
|
||||
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)
|
||||
{
|
||||
/* RTTI entry found */
|
||||
/* RTTI entry found. */
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a reference type referencing the real type */
|
||||
/* Create a reference type referencing the real
|
||||
type. */
|
||||
type = lookup_reference_type (real_type);
|
||||
}
|
||||
/* JYG: Need to adjust pointer value. */
|
||||
/* JYG: Need to adjust pointer value. */
|
||||
/* NOTE: cagney/2005-01-02: THIS IS BOGUS. */
|
||||
value_contents_writeable (val)[0] -= top;
|
||||
|
||||
/* 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);
|
||||
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))
|
||||
{
|
||||
/* Attempt to determine real type of object */
|
||||
/* Attempt to determine real type of object. */
|
||||
real_type = value_rtti_type (val, &full, &top, &using_enc);
|
||||
if (real_type)
|
||||
{
|
||||
/* We have RTTI information, so use it */
|
||||
val = value_full_object (val, real_type, full, top, using_enc);
|
||||
/* We have RTTI information, so use it. */
|
||||
val = value_full_object (val, real_type,
|
||||
full, top, using_enc);
|
||||
fprintf_filtered (stream, "(%s%s) ",
|
||||
TYPE_NAME (real_type),
|
||||
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),
|
||||
value_contents_for_printing (val), 0,
|
||||
value_address (val), stream, 0,
|
||||
val, &opts, current_language);
|
||||
/* Note: When we look up RTTI entries, we don't get any information on
|
||||
const or volatile attributes */
|
||||
/* Note: When we look up RTTI entries, we don't get any
|
||||
information on const or volatile attributes. */
|
||||
}
|
||||
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 ?) ",
|
||||
TYPE_NAME (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,
|
||||
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),
|
||||
|
@ -238,8 +238,10 @@ show_target_charset_name (struct ui_file *file, int from_tty,
|
||||
|
||||
static const char *target_wide_charset_name = "auto";
|
||||
static void
|
||||
show_target_wide_charset_name (struct ui_file *file, int from_tty,
|
||||
struct cmd_list_element *c, const char *value)
|
||||
show_target_wide_charset_name (struct ui_file *file,
|
||||
int from_tty,
|
||||
struct cmd_list_element *c,
|
||||
const char *value)
|
||||
{
|
||||
if (!strcmp (value, "auto"))
|
||||
fprintf_filtered (file,
|
||||
@ -338,9 +340,10 @@ validate (struct gdbarch *gdbarch)
|
||||
|
||||
/* This is the sfunc for the 'set charset' command. */
|
||||
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;
|
||||
validate (get_current_arch ());
|
||||
}
|
||||
@ -372,12 +375,14 @@ set_target_wide_charset_sfunc (char *charset, int from_tty,
|
||||
|
||||
/* sfunc for the 'show charset' command. */
|
||||
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)
|
||||
{
|
||||
show_host_charset_name (file, from_tty, c, host_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. */
|
||||
struct wchar_iterator *
|
||||
make_wchar_iterator (const gdb_byte *input, size_t bytes, const char *charset,
|
||||
size_t width)
|
||||
make_wchar_iterator (const gdb_byte *input, size_t bytes,
|
||||
const char *charset, size_t width)
|
||||
{
|
||||
struct wchar_iterator *result;
|
||||
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 num;
|
||||
size_t r = iconv (iter->desc,
|
||||
(ICONV_CONST char **) &iter->input, &iter->bytes,
|
||||
&outptr, &out_avail);
|
||||
(ICONV_CONST char **) &iter->input,
|
||||
&iter->bytes, &outptr, &out_avail);
|
||||
|
||||
if (r == (size_t) -1)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EILSEQ:
|
||||
/* Invalid input sequence. We still might have converted a
|
||||
character; if so, return it. */
|
||||
/* Invalid input sequence. We still might have
|
||||
converted a character; if so, return it. */
|
||||
if (out_avail < out_request * sizeof (gdb_wchar_t))
|
||||
break;
|
||||
|
||||
/* Otherwise skip the first invalid character, and let the
|
||||
caller know about it. */
|
||||
/* Otherwise skip the first invalid character, and let
|
||||
the caller know about it. */
|
||||
*out_result = wchar_iterate_invalid;
|
||||
*ptr = iter->input;
|
||||
*len = iter->width;
|
||||
@ -794,9 +799,9 @@ find_charset_names (void)
|
||||
int fail = 1;
|
||||
struct gdb_environ *iconv_env;
|
||||
|
||||
/* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is not
|
||||
a tty. We need to recognize it and ignore it. This text is subject
|
||||
to translation, so force LANGUAGE=C. */
|
||||
/* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is
|
||||
not a tty. We need to recognize it and ignore it. This text is
|
||||
subject to translation, so force LANGUAGE=C. */
|
||||
iconv_env = make_environ ();
|
||||
init_environ (iconv_env);
|
||||
set_in_environ (iconv_env, "LANGUAGE", "C");
|
||||
@ -845,8 +850,8 @@ find_charset_names (void)
|
||||
buf[len] = '\0';
|
||||
|
||||
/* libiconv will print multiple entries per line, separated
|
||||
by spaces. Older iconvs will print multiple entries per line,
|
||||
indented by two spaces, and separated by ", "
|
||||
by spaces. Older iconvs will print multiple entries per
|
||||
line, indented by two spaces, and separated by ", "
|
||||
(i.e. the human readable form). */
|
||||
start = buf;
|
||||
while (1)
|
||||
@ -933,15 +938,15 @@ _initialize_charset (void)
|
||||
leak a little memory, if the user later changes the host charset,
|
||||
but that doesn't matter much. */
|
||||
auto_host_charset_name = xstrdup (nl_langinfo (CODESET));
|
||||
/* Solaris will return `646' here -- but the Solaris iconv then
|
||||
does not accept this. Darwin (and maybe FreeBSD) may return "" here,
|
||||
/* Solaris will return `646' here -- but the Solaris iconv then does
|
||||
not accept this. Darwin (and maybe FreeBSD) may return "" here,
|
||||
which GNU libiconv doesn't like (infinite loop). */
|
||||
if (!strcmp (auto_host_charset_name, "646") || !*auto_host_charset_name)
|
||||
auto_host_charset_name = "ASCII";
|
||||
auto_target_charset_name = auto_host_charset_name;
|
||||
#elif defined (USE_WIN32API)
|
||||
{
|
||||
static char w32_host_default_charset[16]; /* "CP" + x<=5 digits + paranoia. */
|
||||
static char w32_host_default_charset[16]; /* "CP" + x<=5 digits + paranoia. */
|
||||
|
||||
snprintf (w32_host_default_charset, sizeof w32_host_default_charset,
|
||||
"CP%d", GetACP());
|
||||
|
@ -60,8 +60,10 @@ enum transliterations
|
||||
caller is responsible for initializing the obstack, and for
|
||||
destroying the obstack should an error occur.
|
||||
TRANSLIT specifies how invalid conversions should be handled. */
|
||||
|
||||
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,
|
||||
enum transliterations translit);
|
||||
|
||||
@ -91,7 +93,8 @@ struct wchar_iterator;
|
||||
This function either returns a new character set iterator, or calls
|
||||
error. The result can be freed using a cleanup; see
|
||||
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,
|
||||
size_t width);
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contributed by Raoul M. Gough (RaoulGough@yahoo.co.uk). */
|
||||
Contributed by Raoul M. Gough (RaoulGough@yahoo.co.uk). */
|
||||
|
||||
#include "coff-pe-read.h"
|
||||
|
||||
@ -36,10 +36,11 @@
|
||||
|
||||
struct read_pe_section_data
|
||||
{
|
||||
CORE_ADDR vma_offset; /* Offset to loaded address of section. */
|
||||
unsigned long rva_start; /* Start 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. */
|
||||
CORE_ADDR vma_offset; /* Offset to loaded address of section. */
|
||||
unsigned long rva_start; /* Start 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. */
|
||||
};
|
||||
|
||||
#define PE_SECTION_INDEX_TEXT 0
|
||||
@ -49,8 +50,8 @@ struct read_pe_section_data
|
||||
#define PE_SECTION_INDEX_INVALID -1
|
||||
|
||||
/* Get the index of the named section in our own array, which contains
|
||||
text, data and bss in that order. Return PE_SECTION_INDEX_INVALID
|
||||
if passed an unrecognised section name. */
|
||||
text, data and bss in that order. Return PE_SECTION_INDEX_INVALID
|
||||
if passed an unrecognised section name. */
|
||||
|
||||
static int
|
||||
read_pe_section_index (const char *section_name)
|
||||
@ -76,7 +77,7 @@ read_pe_section_index (const char *section_name)
|
||||
}
|
||||
}
|
||||
|
||||
/* Record the virtual memory address of a section. */
|
||||
/* Record the virtual memory address of a section. */
|
||||
|
||||
static void
|
||||
get_section_vmas (bfd *abfd, asection *sectp, void *context)
|
||||
@ -87,14 +88,14 @@ get_section_vmas (bfd *abfd, asection *sectp, void *context)
|
||||
if (sectix != PE_SECTION_INDEX_INVALID)
|
||||
{
|
||||
/* Data within the section start at rva_start in the pe and at
|
||||
bfd_get_section_vma() within memory. Store the offset. */
|
||||
bfd_get_section_vma() within memory. Store the offset. */
|
||||
|
||||
sections[sectix].vma_offset
|
||||
= bfd_get_section_vma (abfd, sectp) - sections[sectix].rva_start;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a minimal symbol entry for an exported symbol. */
|
||||
/* Create a minimal symbol entry for an exported symbol. */
|
||||
|
||||
static void
|
||||
add_pe_exported_sym (char *sym_name,
|
||||
@ -102,7 +103,7 @@ add_pe_exported_sym (char *sym_name,
|
||||
const struct read_pe_section_data *section_data,
|
||||
const char *dll_name, struct objfile *objfile)
|
||||
{
|
||||
/* Add the stored offset to get the loaded address of the symbol. */
|
||||
/* Add the stored offset to get the loaded address of the symbol. */
|
||||
|
||||
CORE_ADDR vma = func_rva + section_data->vma_offset;
|
||||
|
||||
@ -110,8 +111,8 @@ add_pe_exported_sym (char *sym_name,
|
||||
int dll_name_len = strlen (dll_name);
|
||||
|
||||
/* Generate a (hopefully unique) qualified name using the first part
|
||||
of the dll name, e.g. KERNEL32!AddAtomA. This matches the style
|
||||
used by windbg from the "Microsoft Debugging Tools for Windows". */
|
||||
of the dll name, e.g. KERNEL32!AddAtomA. This matches the style
|
||||
used by windbg from the "Microsoft Debugging Tools for Windows". */
|
||||
|
||||
qualified_name = xmalloc (dll_name_len + strlen (sym_name) + 2);
|
||||
|
||||
@ -124,11 +125,12 @@ add_pe_exported_sym (char *sym_name,
|
||||
|
||||
xfree (qualified_name);
|
||||
|
||||
/* Enter the plain name as well, which might not be unique. */
|
||||
prim_record_minimal_symbol (sym_name, vma, section_data->ms_type, objfile);
|
||||
/* Enter the plain name as well, which might not be unique. */
|
||||
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. */
|
||||
|
||||
static void
|
||||
read_pe_truncate_name (char *dll_name)
|
||||
@ -137,7 +139,7 @@ read_pe_truncate_name (char *dll_name)
|
||||
{
|
||||
if ((*dll_name) == '.')
|
||||
{
|
||||
*dll_name = '\0'; /* truncates and causes loop exit. */
|
||||
*dll_name = '\0'; /* truncates and causes loop exit. */
|
||||
}
|
||||
|
||||
else
|
||||
@ -147,7 +149,7 @@ read_pe_truncate_name (char *dll_name)
|
||||
}
|
||||
}
|
||||
|
||||
/* Low-level support functions, direct from the ld module pe-dll.c. */
|
||||
/* Low-level support functions, direct from the ld module pe-dll.c. */
|
||||
static unsigned int
|
||||
pe_get16 (bfd *abfd, int where)
|
||||
{
|
||||
@ -177,8 +179,8 @@ pe_as32 (void *ptr)
|
||||
}
|
||||
|
||||
/* Read the (non-debug) export symbol table from a portable
|
||||
executable. Code originally lifted from the ld function
|
||||
pe_implied_import_dll in pe-dll.c. */
|
||||
executable. Code originally lifted from the ld function
|
||||
pe_implied_import_dll in pe-dll.c. */
|
||||
|
||||
void
|
||||
read_pe_exported_syms (struct objfile *objfile)
|
||||
@ -195,7 +197,7 @@ read_pe_exported_syms (struct objfile *objfile)
|
||||
|
||||
/* Array elements are for text, data and bss in that order
|
||||
Initialization with start_rva > end_rva guarantees that
|
||||
unused sections won't be matched. */
|
||||
unused sections won't be matched. */
|
||||
struct read_pe_section_data section_data[PE_SECTION_TABLE_SIZE]
|
||||
= { {0, 1, 0, mst_text},
|
||||
{0, 1, 0, mst_data},
|
||||
@ -217,7 +219,7 @@ read_pe_exported_syms (struct objfile *objfile)
|
||||
{
|
||||
/* This is not a recognized PE format file. Abort now, because
|
||||
the code is untested on anything else. *FIXME* test on
|
||||
further architectures and loosen or remove this test. */
|
||||
further architectures and loosen or remove this test. */
|
||||
return;
|
||||
}
|
||||
|
||||
@ -272,11 +274,12 @@ read_pe_exported_syms (struct objfile *objfile)
|
||||
|
||||
if (export_size == 0)
|
||||
{
|
||||
/* Empty export table. */
|
||||
/* Empty export table. */
|
||||
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++)
|
||||
{
|
||||
unsigned long secptr1 = secptr + 40 * i;
|
||||
@ -311,14 +314,14 @@ read_pe_exported_syms (struct objfile *objfile)
|
||||
ordbase = pe_as32 (expdata + 16);
|
||||
exp_funcbase = pe_as32 (expdata + 28);
|
||||
|
||||
/* Use internal dll name instead of full pathname. */
|
||||
/* Use internal dll name instead of full pathname. */
|
||||
dll_name = pe_as32 (expdata + 12) + erva;
|
||||
|
||||
bfd_map_over_sections (dll, get_section_vmas, section_data);
|
||||
|
||||
/* Adjust the vma_offsets in case this PE got relocated. This
|
||||
assumes that *all* sections share the same relocation offset
|
||||
as the text section. */
|
||||
as the text section. */
|
||||
for (i = 0; i < PE_SECTION_TABLE_SIZE; i++)
|
||||
{
|
||||
section_data[i].vma_offset
|
||||
@ -326,7 +329,7 @@ read_pe_exported_syms (struct objfile *objfile)
|
||||
}
|
||||
|
||||
/* Truncate name at first dot. Should maybe also convert to all
|
||||
lower case for convenience on Windows. */
|
||||
lower case for convenience on Windows. */
|
||||
read_pe_truncate_name (dll_name);
|
||||
|
||||
/* Iterate through the list of symbols. */
|
||||
@ -338,7 +341,7 @@ read_pe_exported_syms (struct objfile *objfile)
|
||||
/* Pointer to the function address vector. */
|
||||
unsigned long func_rva = pe_as32 (erva + exp_funcbase + i * 4);
|
||||
|
||||
/* Find this symbol's section in our own array. */
|
||||
/* Find this symbol's section in our own array. */
|
||||
int sectix = 0;
|
||||
|
||||
for (sectix = 0; sectix < PE_SECTION_TABLE_SIZE; ++sectix)
|
||||
@ -354,6 +357,6 @@ read_pe_exported_syms (struct objfile *objfile)
|
||||
}
|
||||
}
|
||||
|
||||
/* discard expdata. */
|
||||
/* Discard expdata. */
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
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);
|
||||
|
||||
#endif /* !defined (COFF_PE_READ_H) */
|
||||
|
485
gdb/coffread.c
485
gdb/coffread.c
File diff suppressed because it is too large
Load Diff
@ -19,8 +19,9 @@
|
||||
#if !defined (COMMAND_H)
|
||||
#define COMMAND_H 1
|
||||
|
||||
/* Command classes are top-level categories into which commands are broken
|
||||
down for "help" purposes.
|
||||
/* Command classes are top-level categories into which commands are
|
||||
broken down for "help" purposes.
|
||||
|
||||
Notes on classes: class_alias is for alias commands which are not
|
||||
abbreviations of the original command. class-pseudo is for
|
||||
commands which are not really commands nor help topics ("stop"). */
|
||||
@ -30,8 +31,8 @@ enum command_class
|
||||
/* Special args to help_list */
|
||||
class_deprecated = -3, all_classes = -2, all_commands = -1,
|
||||
/* Classes of commands */
|
||||
no_class = -1, class_run = 0, class_vars, class_stack,
|
||||
class_files, class_support, class_info, class_breakpoint, class_trace,
|
||||
no_class = -1, class_run = 0, class_vars, class_stack, class_files,
|
||||
class_support, class_info, class_breakpoint, class_trace,
|
||||
class_alias, class_bookmark, class_obscure, class_maintenance,
|
||||
class_pseudo, class_tui, class_user, class_xdb
|
||||
};
|
||||
@ -63,16 +64,17 @@ typedef enum var_types
|
||||
value. */
|
||||
var_auto_boolean,
|
||||
|
||||
/* Unsigned Integer. *VAR is an unsigned int. The user can type 0
|
||||
to mean "unlimited", which is stored in *VAR as UINT_MAX. */
|
||||
/* Unsigned Integer. *VAR is an unsigned int. The user can type
|
||||
0 to mean "unlimited", which is stored in *VAR as UINT_MAX. */
|
||||
var_uinteger,
|
||||
|
||||
/* Like var_uinteger but signed. *VAR is an int. The user can type 0
|
||||
to mean "unlimited", which is stored in *VAR as INT_MAX. */
|
||||
/* Like var_uinteger but signed. *VAR is an int. The user can
|
||||
type 0 to mean "unlimited", which is stored in *VAR as
|
||||
INT_MAX. */
|
||||
var_integer,
|
||||
|
||||
/* String which the user enters with escapes (e.g. the user types \n and
|
||||
it is a real newline in the stored string).
|
||||
/* String which the user enters with escapes (e.g. the user types
|
||||
\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_string,
|
||||
/* String which stores what the user types verbatim.
|
||||
@ -90,8 +92,9 @@ typedef enum var_types
|
||||
/* ZeroableUnsignedInteger. *VAR is an unsigned int. Zero really
|
||||
means zero. */
|
||||
var_zuinteger,
|
||||
/* Enumerated type. Can only have one of the specified values. *VAR is a
|
||||
char pointer to the name of the element that we find. */
|
||||
/* Enumerated type. Can only have one of the specified values.
|
||||
*VAR is a char pointer to the name of the element that we
|
||||
find. */
|
||||
var_enum
|
||||
}
|
||||
var_types;
|
||||
@ -147,7 +150,8 @@ extern int cmd_cfunc_eq (struct cmd_list_element *cmd,
|
||||
void (*cfunc) (char *args, int from_tty));
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
@ -170,39 +174,42 @@ extern struct cmd_list_element *lookup_cmd_1 (char **,
|
||||
struct cmd_list_element **,
|
||||
int);
|
||||
|
||||
extern struct cmd_list_element *
|
||||
deprecate_cmd (struct cmd_list_element *, char * );
|
||||
extern struct cmd_list_element *deprecate_cmd (struct cmd_list_element *,
|
||||
char * );
|
||||
|
||||
extern void
|
||||
deprecated_cmd_warning (char **);
|
||||
extern void deprecated_cmd_warning (char **);
|
||||
|
||||
extern int
|
||||
lookup_cmd_composition (char *text,
|
||||
struct cmd_list_element **alias,
|
||||
struct cmd_list_element **prefix_cmd,
|
||||
struct cmd_list_element **cmd);
|
||||
extern int lookup_cmd_composition (char *text,
|
||||
struct cmd_list_element **alias,
|
||||
struct cmd_list_element **prefix_cmd,
|
||||
struct cmd_list_element **cmd);
|
||||
|
||||
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 *,
|
||||
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 *);
|
||||
|
||||
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_list (struct cmd_list_element *, char *,
|
||||
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 *);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* check function pointer */
|
||||
/* Check function pointer. */
|
||||
extern int cmd_func_p (struct cmd_list_element *cmd);
|
||||
|
||||
/* call the command function */
|
||||
extern void cmd_func (struct cmd_list_element *cmd, char *args, int from_tty);
|
||||
/* Call the command function. */
|
||||
extern void cmd_func (struct cmd_list_element *cmd,
|
||||
char *args, int from_tty);
|
||||
|
||||
#endif /* !defined (COMMAND_H) */
|
||||
|
@ -26,8 +26,8 @@
|
||||
|
||||
extern void _initialize_complaints (void);
|
||||
|
||||
/* Should each complaint message be self explanatory, or should we assume that
|
||||
a series of complaints is being produced? */
|
||||
/* Should each complaint message be self explanatory, or should we
|
||||
assume that a series of complaints is being produced? */
|
||||
|
||||
/* case 1: First message of a series that must
|
||||
start off with explanation. case 2: Subsequent message of a series
|
||||
@ -165,11 +165,13 @@ static int stop_whining = 0;
|
||||
later handling. */
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
gdb_assert (complaints != NULL);
|
||||
@ -184,7 +186,8 @@ vcomplaint (struct complaints **c, const char *file, int line, const char *fmt,
|
||||
series = complaints->series;
|
||||
|
||||
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)
|
||||
(*deprecated_warning_hook) (complaint->fmt, args);
|
||||
else
|
||||
@ -294,7 +297,8 @@ clear_complaints (struct complaints **c, int less_verbose, int noisy)
|
||||
case SUBSEQUENT_MESSAGE:
|
||||
/* It would be really nice to use begin_line() here.
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
@ -321,7 +325,8 @@ complaints_show_value (struct ui_file *file, int from_tty,
|
||||
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."), _("\
|
||||
Show max number of complaints about incorrect symbols."), NULL,
|
||||
NULL, complaints_show_value,
|
||||
|
@ -30,10 +30,12 @@ struct complaints;
|
||||
extern struct complaints *symfile_complaints;
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
/* Clear out / initialize all complaint counters that have ever been
|
||||
|
193
gdb/completer.c
193
gdb/completer.c
@ -50,21 +50,22 @@ char *line_completion_function (const char *text, int matches,
|
||||
/* readline uses the word breaks for two things:
|
||||
(1) In figuring out where to point the TEXT parameter to the
|
||||
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 does affect how much stuff M-? lists.
|
||||
it doesn't matter a lot what the word breaks are for this purpose,
|
||||
but it does affect how much stuff M-? lists.
|
||||
(2) If one of the matches contains a word break character, readline
|
||||
will quote it. That's why we switch between
|
||||
current_language->la_word_break_characters() and
|
||||
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. */
|
||||
|
||||
/* When completing on command names, we remove '-' from the list of
|
||||
word break characters, since we use it in command names. If the
|
||||
readline library sees one in any of the current completion strings,
|
||||
it thinks that the string needs to be quoted and automatically supplies
|
||||
a leading quote. */
|
||||
it thinks that the string needs to be quoted and automatically
|
||||
supplies a leading quote. */
|
||||
static char *gdb_completer_command_word_break_characters =
|
||||
" \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*|\"';:?><";
|
||||
#endif
|
||||
|
||||
/* Characters that can be used to quote completion strings. Note that we
|
||||
can't include '"' because the gdb C parser treats such quoted sequences
|
||||
as strings. */
|
||||
/* Characters that can be used to quote completion strings. Note that
|
||||
we can't include '"' because the gdb C parser treats such quoted
|
||||
sequences as strings. */
|
||||
static char *gdb_completer_quote_characters = "'";
|
||||
|
||||
/* Accessor for some completer data that may interest other files. */
|
||||
@ -98,20 +99,23 @@ get_gdb_completer_quote_characters (void)
|
||||
char *
|
||||
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
|
||||
but don't want to complete on anything else either. */
|
||||
/* This can be used for functions which don't want to complete on
|
||||
symbols but don't want to complete on anything else either. */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Complete on filenames. */
|
||||
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;
|
||||
char **return_val;
|
||||
@ -142,12 +146,12 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
|
||||
break;
|
||||
}
|
||||
/* We need to set subsequent_name to a non-zero value before the
|
||||
continue line below, because otherwise, if the first file seen
|
||||
by GDB is a backup file whose name ends in a `~', we will loop
|
||||
indefinitely. */
|
||||
continue line below, because otherwise, if the first file
|
||||
seen by GDB is a backup file whose name ends in a `~', we
|
||||
will loop indefinitely. */
|
||||
subsequent_name = 1;
|
||||
/* Like emacs, don't complete on old versions. Especially useful
|
||||
in the "source" command. */
|
||||
/* Like emacs, don't complete on old versions. Especially
|
||||
useful in the "source" command. */
|
||||
if (p[strlen (p) - 1] == '~')
|
||||
{
|
||||
xfree (p);
|
||||
@ -177,9 +181,9 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* There is no way to do this just long enough to affect quote inserting
|
||||
without also affecting the next completion. This should be fixed in
|
||||
readline. FIXME. */
|
||||
/* There is no way to do this just long enough to affect quote
|
||||
inserting without also affecting the next completion. This
|
||||
should be fixed in readline. FIXME. */
|
||||
/* Ensure that readline does the right thing
|
||||
with respect to inserting quotes. */
|
||||
rl_completer_word_break_characters = "";
|
||||
@ -193,9 +197,12 @@ filename_completer (struct cmd_list_element *ignore, char *text, char *word)
|
||||
or
|
||||
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 **
|
||||
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;
|
||||
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)
|
||||
{
|
||||
if (i < TYPE_N_BASECLASSES (type))
|
||||
add_struct_fields (TYPE_BASECLASS (type, i), nextp, output,
|
||||
fieldname, namelen);
|
||||
add_struct_fields (TYPE_BASECLASS (type, i), nextp,
|
||||
output, fieldname, namelen);
|
||||
else if (TYPE_FIELD_NAME (type, i))
|
||||
{
|
||||
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));
|
||||
++*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)
|
||||
{
|
||||
/* Recurse into anonymous unions. */
|
||||
add_struct_fields (TYPE_FIELD_TYPE (type, i), nextp, output,
|
||||
fieldname, namelen);
|
||||
add_struct_fields (TYPE_FIELD_TYPE (type, i), nextp,
|
||||
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
|
||||
field names. */
|
||||
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;
|
||||
char *fieldname, *p;
|
||||
@ -481,12 +490,13 @@ expression_completer (struct cmd_list_element *ignore, char *text, char *word)
|
||||
p--)
|
||||
;
|
||||
|
||||
/* Not ideal but it is what we used to do before... */
|
||||
/* Not ideal but it is what we used to do before... */
|
||||
return location_completer (ignore, p, word);
|
||||
}
|
||||
|
||||
/* Here are some useful test cases for completion. FIXME: These should
|
||||
be put in the test suite. They should be tested with both M-? and TAB.
|
||||
/* Here are some useful test cases for completion. FIXME: These
|
||||
should be put in the test suite. They should be tested with both
|
||||
M-? and TAB.
|
||||
|
||||
"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.
|
||||
|
||||
LINE_BUFFER is available to be looked at; it contains the entire text
|
||||
of the line. POINT is the offset in that line of the cursor. You
|
||||
should pretend that the line ends at POINT.
|
||||
LINE_BUFFER is available to be looked at; it contains the entire
|
||||
text of the line. POINT is the offset in that line of the cursor.
|
||||
You should pretend that the line ends at POINT.
|
||||
|
||||
REASON is of type complete_line_internal_reason.
|
||||
|
||||
If REASON is handle_brkchars:
|
||||
Preliminary phase, called by gdb_completion_word_break_characters function,
|
||||
is used to determine the correct set of chars that are word delimiters
|
||||
depending on the current command in line_buffer.
|
||||
No completion list should be generated; the return value should be NULL.
|
||||
This is checked by an assertion in that function.
|
||||
Preliminary phase, called by gdb_completion_word_break_characters
|
||||
function, is used to determine the correct set of chars that are
|
||||
word delimiters depending on the current command in line_buffer.
|
||||
No completion list should be generated; the return value should be
|
||||
NULL. This is checked by an assertion in that function.
|
||||
|
||||
If REASON is handle_completions:
|
||||
Main phase, called by complete_line function, is used to get the list
|
||||
@ -544,7 +554,8 @@ complete_line_internal_reason;
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
char **list = NULL;
|
||||
@ -553,16 +564,18 @@ complete_line_internal (const char *text, char *line_buffer, int point,
|
||||
char *word;
|
||||
struct cmd_list_element *c, *result_list;
|
||||
|
||||
/* Choose the default set of word break characters to break completions.
|
||||
If we later find out that we are doing completions on command strings
|
||||
(as opposed to strings supplied by the individual command completer
|
||||
functions, which can be any string) then we will switch to the
|
||||
special word break set for command strings, which leaves out the
|
||||
'-' character used in some commands. */
|
||||
/* Choose the default set of word break characters to break
|
||||
completions. If we later find out that we are doing completions
|
||||
on command strings (as opposed to strings supplied by the
|
||||
individual command completer functions, which can be any string)
|
||||
then we will switch to the special word break set for command
|
||||
strings, which leaves out the '-' character used in some
|
||||
commands. */
|
||||
rl_completer_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);
|
||||
p = tmp_command;
|
||||
|
||||
@ -642,12 +655,13 @@ complete_line_internal (const char *text, char *line_buffer, int 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')
|
||||
{
|
||||
/* The command is followed by whitespace; we need to complete
|
||||
on whatever comes after command. */
|
||||
/* The command is followed by whitespace; we need to
|
||||
complete on whatever comes after command. */
|
||||
if (c->prefixlist)
|
||||
{
|
||||
/* 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
|
||||
{
|
||||
/* 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"
|
||||
etc. */
|
||||
char *q;
|
||||
@ -758,7 +772,8 @@ complete_line_internal (const char *text, char *line_buffer, int point,
|
||||
of file-name completion. */
|
||||
for (p = word;
|
||||
p > tmp_command
|
||||
&& strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
|
||||
&& strchr (gdb_completer_file_name_break_characters,
|
||||
p[-1]) == NULL;
|
||||
p--)
|
||||
;
|
||||
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.
|
||||
|
||||
LINE_BUFFER is available to be looked at; it contains the entire text
|
||||
of the line.
|
||||
LINE_BUFFER is available to be looked at; it contains the entire
|
||||
text of the line.
|
||||
|
||||
POINT is the offset in that line of the cursor. You
|
||||
should pretend that the line ends at POINT. */
|
||||
@ -795,14 +810,17 @@ complete_line_internal (const char *text, char *line_buffer, int point,
|
||||
char **
|
||||
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". */
|
||||
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
|
||||
@ -819,26 +837,26 @@ gdb_completion_word_break_characters (void)
|
||||
return rl_completer_word_break_characters;
|
||||
}
|
||||
|
||||
/* Generate completions one by one for the completer. Each time we are
|
||||
called return another potential completion to the caller.
|
||||
line_completion just completes on commands or passes the buck to the
|
||||
command's completer function, the stuff specific to symbol completion
|
||||
is in make_symbol_completion_list.
|
||||
/* Generate completions one by one for the completer. Each time we
|
||||
are called return another potential completion to the caller.
|
||||
line_completion just completes on commands or passes the buck to
|
||||
the command's completer function, the stuff specific to symbol
|
||||
completion is in make_symbol_completion_list.
|
||||
|
||||
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
|
||||
calling this completion function. When zero, then we need to initialize,
|
||||
otherwise the initialization has already taken place and we can just
|
||||
return the next potential completion string.
|
||||
MATCHES is the number of matches that have currently been collected
|
||||
from calling this completion function. When zero, then we need to
|
||||
initialize, otherwise the initialization has already taken place
|
||||
and we can just return the next potential completion string.
|
||||
|
||||
LINE_BUFFER is available to be looked at; it contains the entire text
|
||||
of the line. POINT is the offset in that line of the cursor. You
|
||||
should pretend that the line ends at POINT.
|
||||
LINE_BUFFER is available to be looked at; it contains the entire
|
||||
text of the line. POINT is the offset in that line of the cursor.
|
||||
You should pretend that the line ends at POINT.
|
||||
|
||||
Returns NULL if there are no more completions, else a pointer to a string
|
||||
which is a possible completion, it is the caller's responsibility to
|
||||
free the string. */
|
||||
Returns NULL if there are no more completions, else a pointer to a
|
||||
string which is a possible completion, it is the caller's
|
||||
responsibility to free the string. */
|
||||
|
||||
static char *
|
||||
line_completion_function (const char *text, int matches,
|
||||
@ -850,15 +868,16 @@ line_completion_function (const char *text, int matches,
|
||||
|
||||
if (matches == 0)
|
||||
{
|
||||
/* The caller is beginning to accumulate a new set of completions, so
|
||||
we need to find all of them now, and cache them for returning one at
|
||||
a time on future calls. */
|
||||
/* The caller is beginning to accumulate a new set of
|
||||
completions, so we need to find all of them now, and cache
|
||||
them for returning one at a time on future calls. */
|
||||
|
||||
if (list)
|
||||
{
|
||||
/* Free the storage used by LIST, but not by the strings inside.
|
||||
This is because rl_complete_internal () frees the strings.
|
||||
As complete_line may abort by calling `error' clear LIST now. */
|
||||
/* Free the storage used by LIST, but not by the strings
|
||||
inside. This is because rl_complete_internal () frees
|
||||
the strings. As complete_line may abort by calling
|
||||
`error' clear LIST now. */
|
||||
xfree (list);
|
||||
list = NULL;
|
||||
}
|
||||
@ -866,11 +885,11 @@ line_completion_function (const char *text, int matches,
|
||||
list = complete_line (text, line_buffer, point);
|
||||
}
|
||||
|
||||
/* If we found a list of potential completions during initialization then
|
||||
dole them out one at a time. The vector of completions is NULL
|
||||
terminated, so after returning the last one, return NULL (and continue
|
||||
to do so) each time we are called after that, until a new list is
|
||||
available. */
|
||||
/* If we found a list of potential completions during initialization
|
||||
then dole them out one at a time. The vector of completions is
|
||||
NULL terminated, so after returning the last one, return NULL
|
||||
(and continue to do so) each time we are called after that, until
|
||||
a new list is available. */
|
||||
|
||||
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
|
||||
for figuring out whether to insert a quote. */
|
||||
if (output == NULL)
|
||||
/* Make sure the word break characters are set back to normal for the
|
||||
next time that readline tries to complete something. */
|
||||
/* Make sure the word break characters are set back to normal for
|
||||
the next time that readline tries to complete something. */
|
||||
rl_completer_word_break_characters =
|
||||
current_language->la_word_break_characters();
|
||||
#endif
|
||||
@ -926,7 +945,7 @@ skip_quoted_chars (char *str, char *quotechars, char *breakchars)
|
||||
}
|
||||
else if (strchr (quotechars, *scan))
|
||||
{
|
||||
/* Found start of a quoted string. */
|
||||
/* Found start of a quoted string. */
|
||||
quote_char = *scan;
|
||||
}
|
||||
else if (strchr (breakchars, *scan))
|
||||
|
@ -17,19 +17,27 @@
|
||||
#if !defined (COMPLETER_H)
|
||||
#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);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Machine independent GDB support for core files on systems using "regsets".
|
||||
|
||||
Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003, 2007, 2008,
|
||||
2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003, 2007,
|
||||
2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -59,7 +59,9 @@
|
||||
|
||||
static void
|
||||
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)
|
||||
{
|
||||
gdb_gregset_t gregset;
|
||||
@ -86,7 +88,8 @@ fetch_core_registers (struct regcache *regcache,
|
||||
{
|
||||
memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
|
||||
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;
|
||||
|
||||
|
@ -52,9 +52,10 @@ static void call_extra_exec_file_hooks (char *filename);
|
||||
|
||||
typedef void (*hook_type) (char *);
|
||||
|
||||
hook_type deprecated_exec_file_display_hook; /* the original hook */
|
||||
static hook_type *exec_file_extra_hooks; /* array of additional hooks */
|
||||
static int exec_file_hook_count = 0; /* size of array */
|
||||
hook_type deprecated_exec_file_display_hook; /* The original hook. */
|
||||
static hook_type *exec_file_extra_hooks; /* Array of additional
|
||||
hooks. */
|
||||
static int exec_file_hook_count = 0; /* Size of array. */
|
||||
|
||||
/* Binary file diddling handle for the core file. */
|
||||
|
||||
@ -70,7 +71,7 @@ struct target_ops *core_target;
|
||||
void
|
||||
core_file_command (char *filename, int from_tty)
|
||||
{
|
||||
dont_repeat (); /* Either way, seems bogus. */
|
||||
dont_repeat (); /* Either way, seems bogus. */
|
||||
|
||||
if (core_target == NULL)
|
||||
error (_("GDB can't read core files on this machine."));
|
||||
@ -106,11 +107,13 @@ specify_exec_file_hook (void (*hook) (char *))
|
||||
if (deprecated_exec_file_display_hook != NULL)
|
||||
{
|
||||
/* 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 this is the first extra hook, initialize the hook array. */
|
||||
exec_file_extra_hooks = (hook_type *) xmalloc (sizeof (hook_type));
|
||||
/* If this is the first extra hook, initialize the hook
|
||||
array. */
|
||||
exec_file_extra_hooks = (hook_type *)
|
||||
xmalloc (sizeof (hook_type));
|
||||
exec_file_extra_hooks[0] = deprecated_exec_file_display_hook;
|
||||
deprecated_exec_file_display_hook = call_extra_exec_file_hooks;
|
||||
exec_file_hook_count = 1;
|
||||
@ -120,9 +123,9 @@ specify_exec_file_hook (void (*hook) (char *))
|
||||
Yes, it's inefficient to grow it by one each time but since
|
||||
this is hardly ever called it's not a big deal. */
|
||||
exec_file_hook_count++;
|
||||
new_array =
|
||||
(hook_type *) xrealloc (exec_file_extra_hooks,
|
||||
exec_file_hook_count * sizeof (hook_type));
|
||||
new_array = (hook_type *)
|
||||
xrealloc (exec_file_extra_hooks,
|
||||
exec_file_hook_count * sizeof (hook_type));
|
||||
exec_file_extra_hooks = new_array;
|
||||
exec_file_extra_hooks[exec_file_hook_count - 1] = hook;
|
||||
}
|
||||
@ -155,11 +158,11 @@ reopen_exec_file (void)
|
||||
struct stat st;
|
||||
struct cleanup *cleanups;
|
||||
|
||||
/* Don't do anything if there isn't an exec file. */
|
||||
/* Don't do anything if there isn't an exec file. */
|
||||
if (exec_bfd == NULL)
|
||||
return;
|
||||
|
||||
/* If the timestamp of the exec file has changed, reopen it. */
|
||||
/* If the timestamp of the exec file has changed, reopen it. */
|
||||
filename = xstrdup (bfd_get_filename (exec_bfd));
|
||||
cleanups = make_cleanup (xfree, filename);
|
||||
res = stat (filename, &st);
|
||||
@ -265,7 +268,7 @@ struct captured_read_memory_integer_arguments
|
||||
};
|
||||
|
||||
/* Helper function for gdb_read_memory_integer(). DATA must be a
|
||||
pointer to a captured_read_memory_integer_arguments struct.
|
||||
pointer to a captured_read_memory_integer_arguments struct.
|
||||
Return 1 if successful. Note that the catch_errors() interface
|
||||
will return 0 if an error occurred while reading memory. This
|
||||
choice of return code is so that we can distinguish between
|
||||
@ -274,7 +277,8 @@ struct captured_read_memory_integer_arguments
|
||||
static int
|
||||
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;
|
||||
int len = args->len;
|
||||
enum bfd_endian byte_order = args->byte_order;
|
||||
@ -301,7 +305,7 @@ safe_read_memory_integer (CORE_ADDR memaddr, int len,
|
||||
args.byte_order = byte_order;
|
||||
|
||||
status = catch_errors (do_captured_read_memory_integer, &args,
|
||||
"", RETURN_MASK_ALL);
|
||||
"", RETURN_MASK_ALL);
|
||||
if (status)
|
||||
*return_value = args.result;
|
||||
|
||||
@ -309,7 +313,8 @@ safe_read_memory_integer (CORE_ADDR memaddr, int len,
|
||||
}
|
||||
|
||||
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)];
|
||||
|
||||
@ -318,7 +323,8 @@ read_memory_integer (CORE_ADDR memaddr, int len, enum bfd_endian byte_order)
|
||||
}
|
||||
|
||||
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)];
|
||||
|
||||
@ -362,9 +368,11 @@ read_memory_typed_address (CORE_ADDR addr, struct type *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
|
||||
write_memory (CORE_ADDR memaddr, const bfd_byte *myaddr, int len)
|
||||
write_memory (CORE_ADDR memaddr,
|
||||
const bfd_byte *myaddr, int len)
|
||||
{
|
||||
int status;
|
||||
|
||||
@ -373,7 +381,8 @@ write_memory (CORE_ADDR memaddr, const bfd_byte *myaddr, int len)
|
||||
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
|
||||
write_memory_unsigned_integer (CORE_ADDR addr, int len,
|
||||
enum bfd_endian byte_order,
|
||||
@ -385,7 +394,8 @@ write_memory_unsigned_integer (CORE_ADDR addr, int 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
|
||||
write_memory_signed_integer (CORE_ADDR addr, int len,
|
||||
enum bfd_endian byte_order,
|
||||
@ -405,15 +415,19 @@ char *gnutarget;
|
||||
static char *gnutarget_string;
|
||||
static void
|
||||
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
|
||||
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)
|
||||
gnutarget = NULL;
|
||||
|
113
gdb/corelow.c
113
gdb/corelow.c
@ -59,8 +59,8 @@
|
||||
|
||||
static struct core_fns *core_file_fns = NULL;
|
||||
|
||||
/* The core_fns for a core file handler that is prepared to read the core
|
||||
file currently open on core_bfd. */
|
||||
/* The core_fns for a core file handler that is prepared to read the
|
||||
core file currently open on core_bfd. */
|
||||
|
||||
static struct core_fns *core_vec = NULL;
|
||||
|
||||
@ -105,10 +105,10 @@ static struct target_ops core_ops;
|
||||
/* An arbitrary identifier for the core inferior. */
|
||||
#define CORELOW_PID 1
|
||||
|
||||
/* Link a new core_fns into the global core_file_fns list. Called on gdb
|
||||
startup by the _initialize routine in each core file register reader, to
|
||||
register information about each format the the reader is prepared to
|
||||
handle. */
|
||||
/* Link a new core_fns into the global core_file_fns list. Called on
|
||||
gdb startup by the _initialize routine in each core file register
|
||||
reader, to register information about each format the the reader is
|
||||
prepared to handle. */
|
||||
|
||||
void
|
||||
deprecated_add_core_fns (struct core_fns *cf)
|
||||
@ -119,7 +119,7 @@ deprecated_add_core_fns (struct core_fns *cf)
|
||||
|
||||
/* The default function that core file handlers can use to examine a
|
||||
core file BFD and decide whether or not to accept the job of
|
||||
reading the core file. */
|
||||
reading the core file. */
|
||||
|
||||
int
|
||||
default_core_sniffer (struct core_fns *our_fns, bfd *abfd)
|
||||
@ -133,7 +133,7 @@ default_core_sniffer (struct core_fns *our_fns, bfd *abfd)
|
||||
/* Walk through the list of core functions to find a set that can
|
||||
handle the core file open on ABFD. Default to the first one in the
|
||||
list if nothing matches. Returns pointer to set that is
|
||||
selected. */
|
||||
selected. */
|
||||
|
||||
static struct core_fns *
|
||||
sniff_core_bfd (bfd *abfd)
|
||||
@ -142,7 +142,8 @@ sniff_core_bfd (bfd *abfd)
|
||||
struct core_fns *yummy = NULL;
|
||||
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))
|
||||
return NULL;
|
||||
|
||||
@ -173,7 +174,7 @@ sniff_core_bfd (bfd *abfd)
|
||||
|
||||
/* The default is to reject every core file format we see. Either
|
||||
BFD has to recognize it, or we have to provide a function in the
|
||||
core file handler that recognizes it. */
|
||||
core file handler that recognizes it. */
|
||||
|
||||
int
|
||||
default_check_format (bfd *abfd)
|
||||
@ -181,7 +182,7 @@ default_check_format (bfd *abfd)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Attempt to recognize core file formats that BFD rejects. */
|
||||
/* Attempt to recognize core file formats that BFD rejects. */
|
||||
|
||||
static int
|
||||
gdb_check_format (bfd *abfd)
|
||||
@ -198,8 +199,8 @@ gdb_check_format (bfd *abfd)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Discard all vestiges of any previous core file and mark data and stack
|
||||
spaces as empty. */
|
||||
/* Discard all vestiges of any previous core file and mark data and
|
||||
stack spaces as empty. */
|
||||
|
||||
static void
|
||||
core_close (int quitting)
|
||||
@ -209,11 +210,12 @@ core_close (int quitting)
|
||||
if (core_bfd)
|
||||
{
|
||||
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);
|
||||
|
||||
/* Clear out solib state while the bfd is still open. See
|
||||
comments in clear_solib in solib.c. */
|
||||
/* Clear out solib state while the bfd is still open. See
|
||||
comments in clear_solib in solib.c. */
|
||||
clear_solib ();
|
||||
|
||||
xfree (core_data->sections);
|
||||
@ -236,8 +238,8 @@ core_close_cleanup (void *ignore)
|
||||
core_close (0/*ignored*/);
|
||||
}
|
||||
|
||||
/* Look for sections whose names start with `.reg/' so that we can extract the
|
||||
list of threads in a core file. */
|
||||
/* Look for sections whose names start with `.reg/' so that we can
|
||||
extract the list of threads in a core file. */
|
||||
|
||||
static void
|
||||
add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
|
||||
@ -271,8 +273,8 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
|
||||
/* Warning, Will Robinson, looking at BFD private data! */
|
||||
|
||||
if (reg_sect != NULL
|
||||
&& asect->filepos == reg_sect->filepos) /* Did we find .reg? */
|
||||
inferior_ptid = ptid; /* Yes, make it current */
|
||||
&& asect->filepos == reg_sect->filepos) /* Did we find .reg? */
|
||||
inferior_ptid = ptid; /* Yes, make it current. */
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
filename = temp;
|
||||
}
|
||||
@ -326,15 +329,16 @@ core_open (char *filename, int from_tty)
|
||||
&& !gdb_check_format (temp_bfd))
|
||||
{
|
||||
/* Do it after the err msg */
|
||||
/* FIXME: should be checking for errors from bfd_close (for one thing,
|
||||
on error it does not free all the storage associated with the
|
||||
bfd). */
|
||||
/* FIXME: should be checking for errors from bfd_close (for one
|
||||
thing, on error it does not free all the storage associated
|
||||
with the bfd). */
|
||||
make_cleanup_bfd_close (temp_bfd);
|
||||
error (_("\"%s\" is not a core dump: %s"),
|
||||
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 */
|
||||
unpush_target (&core_ops);
|
||||
@ -358,7 +362,8 @@ core_open (char *filename, int from_tty)
|
||||
|
||||
/* Find the data section */
|
||||
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"),
|
||||
bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
|
||||
|
||||
@ -391,7 +396,7 @@ core_open (char *filename, int from_tty)
|
||||
|
||||
/* Build up thread list from BFD sections, and possibly set the
|
||||
current thread to the .reg/NN section matching the .reg
|
||||
section. */
|
||||
section. */
|
||||
bfd_map_over_sections (core_bfd, add_to_thread_list,
|
||||
bfd_get_section_by_name (core_bfd, ".reg"));
|
||||
|
||||
@ -430,16 +435,17 @@ core_open (char *filename, int from_tty)
|
||||
siggy = bfd_core_file_failing_signal (core_bfd);
|
||||
if (siggy > 0)
|
||||
{
|
||||
/* NOTE: target_signal_from_host() converts a target signal value
|
||||
into gdb's internal signal value. Unfortunately gdb's internal
|
||||
value is called ``target_signal'' and this function got the
|
||||
name ..._from_host(). */
|
||||
/* NOTE: target_signal_from_host() converts a target signal
|
||||
value into gdb's internal signal value. Unfortunately gdb's
|
||||
internal value is called ``target_signal'' and this function
|
||||
got the name ..._from_host(). */
|
||||
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));
|
||||
|
||||
printf_filtered (_("Program terminated with signal %d, %s.\n"), siggy,
|
||||
target_signal_to_string (sig));
|
||||
printf_filtered (_("Program terminated with signal %d, %s.\n"),
|
||||
siggy, target_signal_to_string (sig));
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
||||
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
|
||||
get_core_register_section (struct regcache *regcache,
|
||||
@ -510,7 +517,8 @@ get_core_register_section (struct regcache *regcache,
|
||||
xfree (section_name);
|
||||
|
||||
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
|
||||
section_name = xstrdup (name);
|
||||
|
||||
@ -518,7 +526,8 @@ get_core_register_section (struct regcache *regcache,
|
||||
if (! section)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -536,7 +545,8 @@ get_core_register_section (struct regcache *regcache,
|
||||
{
|
||||
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 (required)
|
||||
@ -558,7 +568,8 @@ get_core_register_section (struct regcache *regcache,
|
||||
|
||||
/* Get the registers out of a core file. This is the machine-
|
||||
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. */
|
||||
|
||||
@ -628,7 +639,7 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
|
||||
{
|
||||
struct spuid_list *list = list_p;
|
||||
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;
|
||||
|
||||
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
|
||||
core_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
const char *annex, gdb_byte *readbuf,
|
||||
const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
|
||||
const gdb_byte *writebuf, ULONGEST offset,
|
||||
LONGEST len)
|
||||
{
|
||||
switch (object)
|
||||
{
|
||||
@ -693,7 +705,8 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
if (readbuf)
|
||||
{
|
||||
/* 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;
|
||||
bfd_size_type size;
|
||||
@ -736,7 +749,8 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
if (readbuf && annex)
|
||||
{
|
||||
/* 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;
|
||||
bfd_size_type size;
|
||||
@ -781,15 +795,17 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
|
||||
|
||||
default:
|
||||
if (ops->beneath != NULL)
|
||||
return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
|
||||
readbuf, writebuf, offset, len);
|
||||
return ops->beneath->to_xfer_partial (ops->beneath, object,
|
||||
annex, readbuf,
|
||||
writebuf, offset, len);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
30
gdb/cp-abi.c
30
gdb/cp-abi.c
@ -70,25 +70,30 @@ is_operator_name (const char *name)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (current_cp_abi.baseclass_offset == NULL)
|
||||
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 *
|
||||
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)
|
||||
{
|
||||
if ((current_cp_abi.virtual_fn_field) == 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 *
|
||||
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 gdb_exception e;
|
||||
@ -105,7 +110,8 @@ value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (current_cp_abi.print_method_ptr == NULL)
|
||||
@ -131,7 +137,8 @@ cplus_make_method_ptr (struct type *type, gdb_byte *contents,
|
||||
}
|
||||
|
||||
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)
|
||||
return 0;
|
||||
@ -139,7 +146,8 @@ cplus_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
|
||||
}
|
||||
|
||||
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)
|
||||
error (_("GDB does not support pointers to methods on this target"));
|
||||
@ -241,7 +249,8 @@ list_cp_abis (int from_tty)
|
||||
int i;
|
||||
|
||||
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++)
|
||||
{
|
||||
char pad[14];
|
||||
@ -305,5 +314,6 @@ Set the ABI used for inspecting C++ objects.\n\
|
||||
&setlist);
|
||||
|
||||
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);
|
||||
}
|
||||
|
72
gdb/cp-abi.h
72
gdb/cp-abi.h
@ -69,7 +69,8 @@ enum dtor_kinds {
|
||||
`delete'. */
|
||||
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
|
||||
};
|
||||
|
||||
@ -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
|
||||
type within *VALUEP. */
|
||||
extern struct value *value_virtual_fn_field (struct value **valuep,
|
||||
struct fn_field *f, int j,
|
||||
struct type *type, int offset);
|
||||
struct fn_field *f,
|
||||
int j,
|
||||
struct type *type,
|
||||
int offset);
|
||||
|
||||
|
||||
/* 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
|
||||
provide the corresponding piece of information. */
|
||||
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
|
||||
the INDEXth baseclass of class TYPE,
|
||||
@ -141,39 +145,44 @@ extern struct type *value_rtti_type (struct value *value,
|
||||
The result is the offset of the baseclass value relative
|
||||
to (the address of)(ARG) + OFFSET.
|
||||
|
||||
-1 is returned on error. */
|
||||
-1 is returned on error. */
|
||||
|
||||
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
|
||||
pattern representing the pointer to method. TYPE is the pointer 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Return the method which should be called by applying METHOD_PTR
|
||||
to *THIS_P, and adjust *THIS_P if necessary. */
|
||||
/* Return the method which should be called by applying METHOD_PTR to
|
||||
*THIS_P, and adjust *THIS_P if necessary. */
|
||||
struct value *cplus_method_ptr_to_value (struct value **this_p,
|
||||
struct value *method_ptr);
|
||||
|
||||
/* Create the byte pattern in CONTENTS representing a pointer of
|
||||
type TYPE to member function at ADDRESS (if IS_VIRTUAL is 0)
|
||||
or with virtual table offset ADDRESS (if IS_VIRTUAL is 1).
|
||||
This is the opposite of cplus_method_ptr_to_value. */
|
||||
/* Create the byte pattern in CONTENTS representing a pointer of type
|
||||
TYPE to member function at ADDRESS (if IS_VIRTUAL is 0) or with
|
||||
virtual table offset ADDRESS (if IS_VIRTUAL is 1). This is the
|
||||
opposite of cplus_method_ptr_to_value. */
|
||||
void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS,
|
||||
CORE_ADDR address, int is_virtual);
|
||||
|
||||
/* Determine if we are currently in a C++ thunk. If so, get the address
|
||||
of the routine we are thunking to and continue to there instead. */
|
||||
/* Determine if we are currently in a C++ thunk. If so, get the
|
||||
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
|
||||
instead of value. */
|
||||
/* Return non-zero if an argument of type TYPE should be passed by
|
||||
reference instead of value. */
|
||||
extern int cp_pass_by_reference (struct type *type);
|
||||
|
||||
struct cp_abi_ops
|
||||
@ -182,22 +191,29 @@ struct cp_abi_ops
|
||||
const char *longname;
|
||||
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 dtor_kinds (*is_destructor_name) (const char *name);
|
||||
int (*is_vtable_name) (const char *name);
|
||||
int (*is_operator_name) (const char *name);
|
||||
struct value *(*virtual_fn_field) (struct value **arg1p, struct fn_field * f,
|
||||
int j, struct type * type, int offset);
|
||||
struct type *(*rtti_type) (struct value *v, int *full, int *top,
|
||||
int *using_enc);
|
||||
struct value *(*virtual_fn_field) (struct value **arg1p,
|
||||
struct fn_field * f,
|
||||
int j, struct type * type,
|
||||
int offset);
|
||||
struct type *(*rtti_type) (struct value *v, int *full,
|
||||
int *top, int *using_enc);
|
||||
int (*baseclass_offset) (struct type *type, int index,
|
||||
const bfd_byte *valaddr, CORE_ADDR address);
|
||||
void (*print_method_ptr) (const gdb_byte *contents, struct type *type,
|
||||
const bfd_byte *valaddr,
|
||||
CORE_ADDR address);
|
||||
void (*print_method_ptr) (const gdb_byte *contents,
|
||||
struct type *type,
|
||||
struct ui_file *stream);
|
||||
int (*method_ptr_size) (struct type *);
|
||||
void (*make_method_ptr) (struct type *, gdb_byte *, CORE_ADDR, int);
|
||||
struct value * (*method_ptr_to_value) (struct value **, struct value *);
|
||||
void (*make_method_ptr) (struct type *, gdb_byte *,
|
||||
CORE_ADDR, int);
|
||||
struct value * (*method_ptr_to_value) (struct value **,
|
||||
struct value *);
|
||||
CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
|
||||
int (*pass_by_reference) (struct type *type);
|
||||
};
|
||||
|
@ -99,7 +99,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
|
||||
"(anonymous namespace)",
|
||||
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;
|
||||
|
||||
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
|
||||
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
|
||||
scope. If ALIAS is NULL then the namespace is known by its original name.
|
||||
DECLARATION is the name if the imported 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. */
|
||||
/* Add a using directive to using_directives. If the using directive
|
||||
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 scope. If ALIAS is NULL then the namespace is known
|
||||
by its original name. DECLARATION is the name if the imported
|
||||
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
|
||||
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
|
||||
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,
|
||||
DOMAIN says what kind of symbols we're looking for, and if SYMTAB is
|
||||
non-NULL, we should store the symtab where we found the symbol in it. */
|
||||
DOMAIN says what kind of symbols we're looking for, and if SYMTAB
|
||||
is non-NULL, we should store the symtab where we found the symbol
|
||||
in it. */
|
||||
|
||||
struct symbol *
|
||||
cp_lookup_symbol_nonlocal (const char *name,
|
||||
@ -241,15 +245,17 @@ cp_lookup_symbol_nonlocal (const char *name,
|
||||
struct symbol *sym;
|
||||
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)
|
||||
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
|
||||
cp_lookup_symbol_nonlocal. */
|
||||
/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are
|
||||
as in cp_lookup_symbol_nonlocal. */
|
||||
|
||||
static struct symbol *
|
||||
cp_lookup_symbol_in_namespace (const char *namespace,
|
||||
@ -263,14 +269,14 @@ cp_lookup_symbol_in_namespace (const char *namespace,
|
||||
}
|
||||
else
|
||||
{
|
||||
char *concatenated_name = alloca (strlen (namespace) + 2 +
|
||||
strlen (name) + 1);
|
||||
char *concatenated_name = alloca (strlen (namespace) + 2
|
||||
+ strlen (name) + 1);
|
||||
|
||||
strcpy (concatenated_name, namespace);
|
||||
strcat (concatenated_name, "::");
|
||||
strcat (concatenated_name, name);
|
||||
return lookup_symbol_file (concatenated_name, block,
|
||||
domain, cp_is_anonymous (namespace));
|
||||
return lookup_symbol_file (concatenated_name, block, domain,
|
||||
cp_is_anonymous (namespace));
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,30 +290,30 @@ reset_directive_searched (void *data)
|
||||
direct->searched = 0;
|
||||
}
|
||||
|
||||
/* Search for NAME by applying all import statements belonging
|
||||
to BLOCK which are applicable in SCOPE. If DECLARATION_ONLY the search
|
||||
is restricted to using declarations.
|
||||
/* Search for NAME by applying all import statements belonging to
|
||||
BLOCK which are applicable in SCOPE. If DECLARATION_ONLY the
|
||||
search is restricted to using declarations.
|
||||
Example:
|
||||
|
||||
namespace A{
|
||||
namespace A {
|
||||
int x;
|
||||
}
|
||||
using A::x;
|
||||
|
||||
If SEARCH_PARENTS the search will include imports which are applicable in
|
||||
parents of SCOPE.
|
||||
If SEARCH_PARENTS the search will include imports which are
|
||||
applicable in parents of SCOPE.
|
||||
Example:
|
||||
|
||||
namespace A{
|
||||
namespace A {
|
||||
using namespace X;
|
||||
namespace B{
|
||||
namespace B {
|
||||
using namespace Y;
|
||||
}
|
||||
}
|
||||
|
||||
If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
|
||||
and Y will be considered. If SEARCH_PARENTS is false only the import of Y
|
||||
is considered. */
|
||||
If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of
|
||||
namespaces X and Y will be considered. If SEARCH_PARENTS is false
|
||||
only the import of Y is considered. */
|
||||
|
||||
struct symbol *
|
||||
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. */
|
||||
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)
|
||||
return sym;
|
||||
|
||||
/* Go through the using directives. If any of them add new
|
||||
names to the namespace we're searching in, see if we can find a
|
||||
match by applying them. */
|
||||
/* Go through the using directives. If any of them add new names to
|
||||
the namespace we're searching in, see if we can find a match by
|
||||
applying them. */
|
||||
|
||||
for (current = block_using (block);
|
||||
current != NULL;
|
||||
@ -343,33 +350,35 @@ cp_lookup_symbol_imports (const char *scope,
|
||||
? (strncmp (scope, current->import_dest,
|
||||
strlen (current->import_dest)) == 0
|
||||
&& (len == 0
|
||||
|| scope[len] == ':' || scope[len] == '\0'))
|
||||
|| scope[len] == ':'
|
||||
|| scope[len] == '\0'))
|
||||
: strcmp (scope, current->import_dest) == 0);
|
||||
|
||||
/* If the import destination is the current scope or one of its ancestors then
|
||||
it is applicable. */
|
||||
/* If the import destination is the current scope or one of its
|
||||
ancestors then it is applicable. */
|
||||
if (directive_match && !current->searched)
|
||||
{
|
||||
/* Mark this import as searched so that the recursive call does not
|
||||
search it again. */
|
||||
/* Mark this import as searched so that the recursive call
|
||||
does not search it again. */
|
||||
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
|
||||
declaration (after optional renaming by its alias) with the sought
|
||||
out name. If there is a match pass current->import_src as NAMESPACE
|
||||
to direct the search towards the imported namespace. */
|
||||
/* If there is an import of a single declaration, compare the
|
||||
imported declaration (after optional renaming by its alias)
|
||||
with the sought out name. If there is a match pass
|
||||
current->import_src as NAMESPACE to direct the search
|
||||
towards the imported namespace. */
|
||||
if (current->declaration
|
||||
&& strcmp (name, current->alias ? current->alias
|
||||
: current->declaration) == 0)
|
||||
&& strcmp (name, current->alias
|
||||
? current->alias : current->declaration) == 0)
|
||||
sym = cp_lookup_symbol_in_namespace (current->import_src,
|
||||
current->declaration,
|
||||
block,
|
||||
domain);
|
||||
current->declaration,
|
||||
block, domain);
|
||||
|
||||
/* If this is a DECLARATION_ONLY search or a symbol was found or
|
||||
this import statement was an import declaration, the search
|
||||
of this import is complete. */
|
||||
/* If this is a DECLARATION_ONLY search or a symbol was found
|
||||
or this import statement was an import declaration, the
|
||||
search of this import is complete. */
|
||||
if (declaration_only || sym != NULL || current->declaration)
|
||||
{
|
||||
current->searched = 0;
|
||||
@ -381,26 +390,24 @@ cp_lookup_symbol_imports (const char *scope,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current->alias != NULL && strcmp (name, current->alias) == 0)
|
||||
/* If the import is creating an alias and the alias matches the
|
||||
sought name. Pass current->import_src as the NAME to direct the
|
||||
search towards the aliased namespace. */
|
||||
if (current->alias != NULL
|
||||
&& strcmp (name, current->alias) == 0)
|
||||
/* If the import is creating an alias and the alias matches
|
||||
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,
|
||||
current->import_src,
|
||||
block,
|
||||
domain);
|
||||
current->import_src,
|
||||
block, domain);
|
||||
}
|
||||
else if (current->alias == NULL)
|
||||
{
|
||||
/* If this import statement creates no alias, pass current->inner as
|
||||
NAMESPACE to direct the search towards the imported namespace. */
|
||||
/* If this import statement creates no alias, pass
|
||||
current->inner as NAMESPACE to direct the search
|
||||
towards the imported namespace. */
|
||||
sym = cp_lookup_symbol_imports (current->import_src,
|
||||
name,
|
||||
block,
|
||||
domain,
|
||||
0,
|
||||
0);
|
||||
name, block,
|
||||
domain, 0, 0);
|
||||
}
|
||||
current->searched = 0;
|
||||
discard_cleanups (searched_cleanup);
|
||||
@ -417,7 +424,8 @@ cp_lookup_symbol_imports (const char *scope,
|
||||
NAME. */
|
||||
|
||||
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;
|
||||
|
||||
@ -451,7 +459,8 @@ cp_lookup_symbol_imports_or_template (const char *scope,
|
||||
/* Search the function's template parameters. */
|
||||
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;
|
||||
|
||||
result = search_symbol_list (name,
|
||||
@ -482,15 +491,18 @@ cp_lookup_symbol_imports_or_template (const char *scope,
|
||||
else
|
||||
{
|
||||
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)
|
||||
break;
|
||||
|
||||
result = search_symbol_list (name,
|
||||
TYPE_N_TEMPLATE_ARGUMENTS (context),
|
||||
TYPE_TEMPLATE_ARGUMENTS (context));
|
||||
result
|
||||
= search_symbol_list (name,
|
||||
TYPE_N_TEMPLATE_ARGUMENTS (context),
|
||||
TYPE_TEMPLATE_ARGUMENTS (context));
|
||||
if (result != NULL)
|
||||
return result;
|
||||
}
|
||||
@ -502,9 +514,10 @@ cp_lookup_symbol_imports_or_template (const char *scope,
|
||||
return cp_lookup_symbol_imports (scope, name, block, domain, 1, 1);
|
||||
}
|
||||
|
||||
/* Searches for NAME in the current namespace, and by applying relevant import
|
||||
statements belonging to BLOCK and its parents. SCOPE is the namespace scope
|
||||
of the context in which the search is being evaluated. */
|
||||
/* Searches for NAME in the current namespace, and by applying
|
||||
relevant import statements belonging to BLOCK and its parents.
|
||||
SCOPE is the namespace scope of the context in which the search is
|
||||
being evaluated. */
|
||||
|
||||
struct symbol*
|
||||
cp_lookup_symbol_namespace (const char *scope,
|
||||
@ -515,14 +528,17 @@ cp_lookup_symbol_namespace (const char *scope,
|
||||
struct symbol *sym;
|
||||
|
||||
/* 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)
|
||||
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)
|
||||
{
|
||||
sym = cp_lookup_symbol_imports (scope, name, block, domain, 0, 1);
|
||||
sym = cp_lookup_symbol_imports (scope, name, block,
|
||||
domain, 0, 1);
|
||||
|
||||
if (sym)
|
||||
return sym;
|
||||
@ -571,7 +587,8 @@ lookup_namespace_scope (const char *name,
|
||||
new_scope_len += 2;
|
||||
}
|
||||
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)
|
||||
return sym;
|
||||
}
|
||||
@ -582,7 +599,8 @@ lookup_namespace_scope (const char *name,
|
||||
namespace = alloca (scope_len + 1);
|
||||
strncpy (namespace, scope, scope_len);
|
||||
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
|
||||
@ -664,24 +682,26 @@ cp_lookup_nested_type (struct type *parent_type,
|
||||
lookup_symbol_namespace works when looking them up. */
|
||||
|
||||
const char *parent_name = TYPE_TAG_NAME (parent_type);
|
||||
struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name,
|
||||
nested_name,
|
||||
block,
|
||||
VAR_DOMAIN);
|
||||
struct symbol *sym
|
||||
= cp_lookup_symbol_in_namespace (parent_name, nested_name,
|
||||
block, VAR_DOMAIN);
|
||||
char *concatenated_name;
|
||||
|
||||
if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|
||||
return SYMBOL_TYPE (sym);
|
||||
|
||||
/* Now search all static file-level symbols. Not strictly correct,
|
||||
but more useful than an error. We do not try to guess any imported
|
||||
namespace as even the fully specified namespace seach is is already
|
||||
not C++ compliant and more assumptions could make it too magic. */
|
||||
/* Now search all static file-level symbols. Not strictly
|
||||
correct, but more useful than an error. We do not try to
|
||||
guess any imported namespace as even the fully specified
|
||||
namespace seach is is already not C++ compliant and more
|
||||
assumptions could make it too magic. */
|
||||
|
||||
concatenated_name = alloca (strlen (parent_name) + 2
|
||||
+ strlen (nested_name) + 1);
|
||||
sprintf (concatenated_name, "%s::%s", parent_name, nested_name);
|
||||
sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
|
||||
sprintf (concatenated_name, "%s::%s",
|
||||
parent_name, nested_name);
|
||||
sym = lookup_static_symbol_aux (concatenated_name,
|
||||
VAR_DOMAIN);
|
||||
if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|
||||
return SYMBOL_TYPE (sym);
|
||||
|
||||
@ -733,11 +753,12 @@ cp_lookup_transparent_type (const char *name)
|
||||
|
||||
/* Lookup the the type definition associated to NAME in
|
||||
namespaces/classes containing SCOPE whose name is strictly longer
|
||||
than LENGTH. LENGTH must be the index of the start of a
|
||||
component of SCOPE. */
|
||||
than LENGTH. LENGTH must be the index of the start of a component
|
||||
of SCOPE. */
|
||||
|
||||
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 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] == ':')
|
||||
{
|
||||
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)
|
||||
return retval;
|
||||
@ -799,7 +821,7 @@ initialize_namespace_symtab (struct objfile *objfile)
|
||||
BLOCKVECTOR_NBLOCKS (bv) = FIRST_LOCAL_BLOCK + 1;
|
||||
BLOCKVECTOR (namespace_symtab) = bv;
|
||||
|
||||
/* Allocate empty GLOBAL_BLOCK and STATIC_BLOCK. */
|
||||
/* Allocate empty GLOBAL_BLOCK and STATIC_BLOCK. */
|
||||
|
||||
bl = allocate_block (&objfile->objfile_obstack);
|
||||
BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack,
|
||||
@ -865,7 +887,8 @@ free_namespace_block (struct symtab *symtab)
|
||||
it shouldn't consist solely of namespaces. */
|
||||
|
||||
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,
|
||||
cp_find_first_component (name),
|
||||
@ -904,7 +927,8 @@ check_possible_namespace_symbols_loop (const char *name, int len,
|
||||
objfile);
|
||||
|
||||
if (!done)
|
||||
done = check_one_possible_namespace_symbol (name, len, objfile);
|
||||
done = check_one_possible_namespace_symbol (name, len,
|
||||
objfile);
|
||||
|
||||
return done;
|
||||
}
|
||||
@ -932,11 +956,13 @@ check_one_possible_namespace_symbol (const char *name, int len,
|
||||
{
|
||||
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);
|
||||
|
||||
sym = obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
|
||||
sym = obstack_alloc (&objfile->objfile_obstack,
|
||||
sizeof (struct symbol));
|
||||
memset (sym, 0, sizeof (struct symbol));
|
||||
SYMBOL_SET_LANGUAGE (sym, language_cplus);
|
||||
/* 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 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));
|
||||
}
|
||||
@ -1002,7 +1029,8 @@ extern initialize_file_ftype _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."),
|
||||
&maint_cplus_cmd_list);
|
||||
}
|
||||
|
161
gdb/cp-support.c
161
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);
|
||||
|
||||
/* Operator validation.
|
||||
NOTE: Multi-byte operators (usually the assignment variety operator)
|
||||
must appear before the single byte version, i.e., "+=" before "+". */
|
||||
NOTE: Multi-byte operators (usually the assignment variety
|
||||
operator) must appear before the single byte version, i.e., "+="
|
||||
before "+". */
|
||||
static const char *operator_tokens[] =
|
||||
{
|
||||
"++", "+=", "+", "->*", "->", "--", "-=", "-", "*=", "*", "/=", "/",
|
||||
"%=", "%", "!=", "==", "!", "&&", "<<=", "<<", ">>=", ">>",
|
||||
"<=", "<", ">=", ">", "~", "&=", "&", "|=", "||", "|", "^=", "^",
|
||||
"=", "()", "[]", ",", "new", "delete"
|
||||
"++", "+=", "+", "->*", "->", "--", "-=", "-", "*=", "*",
|
||||
"/=", "/", "%=", "%", "!=", "==", "!", "&&", "<<=", "<<",
|
||||
">>=", ">>", "<=", "<", ">=", ">", "~", "&=", "&", "|=",
|
||||
"||", "|", "^=", "^", "=", "()", "[]", ",", "new", "delete"
|
||||
/* new[] and delete[] require special whitespace handling */
|
||||
};
|
||||
|
||||
@ -146,11 +147,11 @@ cp_canonicalize_string (const char *string)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Convert a mangled name to a demangle_component tree. *MEMORY is set to the
|
||||
block of used memory that should be freed when finished with the tree.
|
||||
DEMANGLED_P is set to the char * that should be freed when finished with
|
||||
the tree, or NULL if none was needed. OPTIONS will be passed to the
|
||||
demangler. */
|
||||
/* Convert a mangled name to a demangle_component tree. *MEMORY is
|
||||
set to the block of used memory that should be freed when finished
|
||||
with the tree. DEMANGLED_P is set to the char * that should be
|
||||
freed when finished with the tree, or NULL if none was needed.
|
||||
OPTIONS will be passed to the demangler. */
|
||||
|
||||
static struct demangle_component *
|
||||
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. */
|
||||
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)
|
||||
{
|
||||
*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);
|
||||
if (demangled_name == 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);
|
||||
|
||||
if (ret == NULL)
|
||||
@ -199,14 +203,15 @@ cp_class_name_from_physname (const char *physname)
|
||||
struct demangle_component *ret_comp, *prev_comp, *cur_comp;
|
||||
int done;
|
||||
|
||||
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage,
|
||||
&demangled_name);
|
||||
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI,
|
||||
&storage, &demangled_name);
|
||||
if (ret_comp == NULL)
|
||||
return NULL;
|
||||
|
||||
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)
|
||||
switch (ret_comp->type)
|
||||
{
|
||||
@ -233,9 +238,9 @@ cp_class_name_from_physname (const char *physname)
|
||||
if (ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE)
|
||||
ret_comp = d_left (ret_comp);
|
||||
|
||||
/* What we have now should be a name, possibly qualified. Additional
|
||||
qualifiers could live in the left subtree or the right subtree. Find
|
||||
the last piece. */
|
||||
/* What we have now should be a name, possibly qualified.
|
||||
Additional qualifiers could live in the left subtree or the right
|
||||
subtree. Find the last piece. */
|
||||
done = 0;
|
||||
prev_comp = NULL;
|
||||
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. */
|
||||
*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);
|
||||
}
|
||||
|
||||
@ -276,9 +282,10 @@ cp_class_name_from_physname (const char *physname)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return the child of COMP which is the basename of a method, variable,
|
||||
et cetera. All scope qualifiers are discarded, but template arguments
|
||||
will be included. The component tree may be modified. */
|
||||
/* Return the child of COMP which is the basename of a method,
|
||||
variable, et cetera. All scope qualifiers are discarded, but
|
||||
template arguments will be included. The component tree may be
|
||||
modified. */
|
||||
|
||||
static struct demangle_component *
|
||||
unqualified_name_from_comp (struct demangle_component *comp)
|
||||
@ -342,8 +349,8 @@ method_name_from_physname (const char *physname)
|
||||
char *demangled_name = NULL, *ret;
|
||||
struct demangle_component *ret_comp;
|
||||
|
||||
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage,
|
||||
&demangled_name);
|
||||
ret_comp = mangled_name_to_comp (physname, DMGL_ANSI,
|
||||
&storage, &demangled_name);
|
||||
if (ret_comp == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -351,7 +358,8 @@ method_name_from_physname (const char *physname)
|
||||
|
||||
ret = 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);
|
||||
|
||||
xfree (storage);
|
||||
@ -551,7 +559,8 @@ cp_find_first_component_aux (const char *name, int permissive)
|
||||
case 'o':
|
||||
/* Operator names can screw up the recursion. */
|
||||
if (operator_possible
|
||||
&& strncmp (name + index, "operator", LENGTH_OF_OPERATOR) == 0)
|
||||
&& strncmp (name + index, "operator",
|
||||
LENGTH_OF_OPERATOR) == 0)
|
||||
{
|
||||
index += LENGTH_OF_OPERATOR;
|
||||
while (ISSPACE(name[index]))
|
||||
@ -641,20 +650,22 @@ cp_entire_prefix_len (const char *name)
|
||||
|
||||
/* Test to see if SYM is a symbol that we haven't seen corresponding
|
||||
to a function named OLOAD_NAME. If so, add it to the current
|
||||
completion list. */
|
||||
completion list. */
|
||||
|
||||
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 i;
|
||||
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)
|
||||
return;
|
||||
|
||||
/* skip any symbols that we've already considered. */
|
||||
/* skip any symbols that we've already considered. */
|
||||
for (i = 0; i < sym_return_val_index; ++i)
|
||||
if (strcmp (SYMBOL_LINKAGE_NAME (sym),
|
||||
SYMBOL_LINKAGE_NAME (sym_return_val[i])) == 0)
|
||||
@ -674,12 +685,13 @@ overload_list_add_symbol (struct symbol *sym, const char *oload_name)
|
||||
|
||||
xfree (sym_name);
|
||||
|
||||
/* We have a match for an overload instance, so add SYM to the current list
|
||||
* of overload instances */
|
||||
/* We have a match for an overload instance, so add SYM to the
|
||||
current list of overload instances */
|
||||
if (sym_return_val_index + 3 > sym_return_val_size)
|
||||
{
|
||||
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] = 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
|
||||
types. */
|
||||
/* Search the namespace of the given type and namespace of and public
|
||||
base types. */
|
||||
|
||||
static void
|
||||
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;
|
||||
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_TYPEDEF)
|
||||
{
|
||||
@ -816,13 +829,14 @@ make_symbol_overload_list_adl_namespace (struct type *type,
|
||||
for (i = 0; i < TYPE_N_BASECLASSES (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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds the the overload list overload candidates for FUNC_NAME found through
|
||||
argument dependent lookup. */
|
||||
/* Adds the the overload list overload candidates for FUNC_NAME found
|
||||
through argument dependent lookup. */
|
||||
|
||||
struct symbol **
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
reset_directive_searched (void *data)
|
||||
@ -874,19 +890,22 @@ make_symbol_overload_list_using (const char *func_name,
|
||||
if (current->searched)
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (strcmp (namespace, current->import_dest) == 0)
|
||||
{
|
||||
/* Mark this import as searched so that the recursive call does
|
||||
not search it again. */
|
||||
/* Mark this import as searched so that the recursive call
|
||||
does not search it again. */
|
||||
struct cleanup *old_chain;
|
||||
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;
|
||||
discard_cleanups (old_chain);
|
||||
@ -911,8 +930,8 @@ make_symbol_overload_list_qualified (const char *func_name)
|
||||
struct dict_iterator iter;
|
||||
const struct dictionary *dict;
|
||||
|
||||
/* Look through the partial symtabs for all symbols which begin
|
||||
by matching FUNC_NAME. Make sure we read that symbol table in. */
|
||||
/* Look through the partial symtabs for all symbols which begin by
|
||||
matching FUNC_NAME. Make sure we read that symbol table in. */
|
||||
|
||||
ALL_OBJFILES (objfile)
|
||||
{
|
||||
@ -949,7 +968,7 @@ make_symbol_overload_list_qualified (const char *func_name)
|
||||
}
|
||||
}
|
||||
|
||||
/* Lookup the rtti type for a class name. */
|
||||
/* Lookup the rtti type for a class name. */
|
||||
|
||||
struct type *
|
||||
cp_lookup_rtti_type (const char *name, struct block *block)
|
||||
@ -998,7 +1017,9 @@ static void
|
||||
maint_cplus_command (char *arg, int from_tty)
|
||||
{
|
||||
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.
|
||||
@ -1034,7 +1055,8 @@ extern initialize_file_ftype _initialize_cp_support; /* -Wmissing-prototypes */
|
||||
while (0)
|
||||
|
||||
/* 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
|
||||
cp_validate_operator (const char *input)
|
||||
{
|
||||
@ -1053,13 +1075,15 @@ cp_validate_operator (const char *input)
|
||||
|
||||
p += 8;
|
||||
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)
|
||||
{
|
||||
int length = strlen (operator_tokens[i]);
|
||||
|
||||
/* By using strncmp here, we MUST have operator_tokens ordered!
|
||||
See additional notes where operator_tokens is defined above. */
|
||||
/* By using strncmp here, we MUST have operator_tokens
|
||||
ordered! See additional notes where operator_tokens is
|
||||
defined above. */
|
||||
if (strncmp (p, operator_tokens[i], length) == 0)
|
||||
{
|
||||
const char *op = p;
|
||||
@ -1071,8 +1095,8 @@ cp_validate_operator (const char *input)
|
||||
|| strncmp (op, "delete", 6) == 0)
|
||||
{
|
||||
|
||||
/* Special case: new[] and delete[]. We must be careful
|
||||
to swallow whitespace before/in "[]". */
|
||||
/* Special case: new[] and delete[]. We must be
|
||||
careful to swallow whitespace before/in "[]". */
|
||||
SKIP_SPACE (p);
|
||||
|
||||
if (*p == '[')
|
||||
@ -1093,12 +1117,12 @@ cp_validate_operator (const char *input)
|
||||
|
||||
/* Check input for a conversion operator. */
|
||||
|
||||
/* Skip past base typename */
|
||||
/* Skip past base typename. */
|
||||
while (*p != '*' && *p != '&' && *p != 0 && *p != ' ')
|
||||
++p;
|
||||
SKIP_SPACE (p);
|
||||
|
||||
/* Add modifiers '*'/'&' */
|
||||
/* Add modifiers '*' / '&'. */
|
||||
while (*p == '*' || *p == '&')
|
||||
{
|
||||
++p;
|
||||
@ -1130,12 +1154,19 @@ cp_validate_operator (const char *input)
|
||||
void
|
||||
_initialize_cp_support (void)
|
||||
{
|
||||
add_prefix_cmd ("cplus", class_maintenance, maint_cplus_command,
|
||||
_("C++ maintenance commands."), &maint_cplus_cmd_list,
|
||||
"maintenance cplus ", 0, &maintenancelist);
|
||||
add_alias_cmd ("cp", "cplus", class_maintenance, 1, &maintenancelist);
|
||||
add_prefix_cmd ("cplus", class_maintenance,
|
||||
maint_cplus_command,
|
||||
_("C++ maintenance commands."),
|
||||
&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."),
|
||||
&maint_cplus_cmd_list);
|
||||
}
|
||||
|
@ -37,13 +37,14 @@ struct type;
|
||||
struct demangle_component;
|
||||
|
||||
/* This struct is designed to store data from using directives. It
|
||||
says that names from namespace IMPORT_SRC should be visible within namespace
|
||||
IMPORT_DEST. These form a linked list; NEXT is the next element of the
|
||||
list. If the imported namespace or declaration has been aliased within the
|
||||
IMPORT_DEST namespace, ALIAS is set to a string representing the alias.
|
||||
Otherwise, ALIAS is NULL. DECLARATION is the name of the imported
|
||||
declaration, if this import statement represents one. Otherwise DECLARATION
|
||||
is NULL and this import statement represents a namespace.
|
||||
says that names from namespace IMPORT_SRC should be visible within
|
||||
namespace IMPORT_DEST. These form a linked list; NEXT is the next
|
||||
element of the list. If the imported namespace or declaration has
|
||||
been aliased within the IMPORT_DEST namespace, ALIAS is set to a
|
||||
string representing the alias. Otherwise, ALIAS is NULL.
|
||||
DECLARATION is the name of the imported declaration, if this import
|
||||
statement represents one. Otherwise DECLARATION is NULL and this
|
||||
import statement represents a namespace.
|
||||
|
||||
C++: using namespace A;
|
||||
Fortran: use A
|
||||
@ -66,15 +67,18 @@ struct demangle_component;
|
||||
import_dest = local scope of the import statement even such as ""
|
||||
alias = "LOCALNS"
|
||||
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
|
||||
import_src = "A"
|
||||
import_dest = local scope of the import statement even such as ""
|
||||
alias = "localname"
|
||||
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
|
||||
{
|
||||
@ -86,7 +90,8 @@ struct using_direct
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "language.h"
|
||||
#include "python/python.h"
|
||||
|
||||
/* Controls printing of vtbl's */
|
||||
/* Controls printing of vtbl's. */
|
||||
static void
|
||||
show_vtblprint (struct ui_file *file, int from_tty,
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
@ -79,10 +81,12 @@ static void cp_print_static_field (struct type *, struct value *,
|
||||
struct ui_file *, int,
|
||||
const struct value_print_options *);
|
||||
|
||||
static void cp_print_value (struct type *, struct type *, const gdb_byte *,
|
||||
int, CORE_ADDR, struct ui_file *, int,
|
||||
const struct value *,
|
||||
const struct value_print_options *, struct type **);
|
||||
static void cp_print_value (struct type *, struct type *,
|
||||
const gdb_byte *, int,
|
||||
CORE_ADDR, struct ui_file *,
|
||||
int, const struct value *,
|
||||
const struct value_print_options *,
|
||||
struct type **);
|
||||
|
||||
|
||||
/* GCC versions after 2.4.5 use this. */
|
||||
@ -105,19 +109,19 @@ cp_is_vtbl_ptr_type (struct type *type)
|
||||
int
|
||||
cp_is_vtbl_member (struct type *type)
|
||||
{
|
||||
/* With older versions of g++, the vtbl field pointed to an array
|
||||
of structures. Nowadays it points directly to the structure. */
|
||||
/* With older versions of g++, the vtbl field pointed to an array of
|
||||
structures. Nowadays it points directly to the structure. */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
||||
{
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||
{
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */
|
||||
|| TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */
|
||||
|| TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
|
||||
{
|
||||
/* Virtual functions tables are full of pointers
|
||||
to virtual functions. */
|
||||
to virtual functions. */
|
||||
return cp_is_vtbl_ptr_type (type);
|
||||
}
|
||||
}
|
||||
@ -127,9 +131,10 @@ cp_is_vtbl_member (struct type *type)
|
||||
}
|
||||
else if (TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
|
||||
{
|
||||
/* The type name of the thunk pointer is NULL when using dwarf2.
|
||||
We could test for a pointer to a function, but there is
|
||||
no type info for the virtual table either, so it wont help. */
|
||||
/* The type name of the thunk pointer is NULL when using
|
||||
dwarf2. We could test for a pointer to a function, but
|
||||
there is no type info for the virtual table either, so it
|
||||
wont help. */
|
||||
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
|
||||
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
|
||||
same meanings as in cp_print_value and c_val_print.
|
||||
TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and OPTIONS have the same
|
||||
meanings as in cp_print_value and c_val_print.
|
||||
|
||||
2nd argument REAL_TYPE is used to carry over the type of the derived
|
||||
class across the recursion to base classes.
|
||||
2nd argument REAL_TYPE is used to carry over the type of the
|
||||
derived class across the recursion to base classes.
|
||||
|
||||
DONT_PRINT is an array of baseclass types that we
|
||||
should not print, or zero if called from top level. */
|
||||
DONT_PRINT is an array of baseclass types that we should not print,
|
||||
or zero if called from top level. */
|
||||
|
||||
void
|
||||
cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
const gdb_byte *valaddr, int offset, CORE_ADDR address,
|
||||
struct ui_file *stream, int recurse,
|
||||
const struct value *val,
|
||||
const gdb_byte *valaddr, int offset,
|
||||
CORE_ADDR address, struct ui_file *stream,
|
||||
int recurse, const struct value *val,
|
||||
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 fields_seen = 0;
|
||||
@ -164,12 +171,14 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -187,8 +196,10 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
duplicates of virtual baseclasses. */
|
||||
|
||||
if (n_baseclasses > 0)
|
||||
cp_print_value (type, real_type, valaddr, offset, address, stream,
|
||||
recurse + 1, val, options, dont_print_vb);
|
||||
cp_print_value (type, real_type, valaddr,
|
||||
offset, address, stream,
|
||||
recurse + 1, val, options,
|
||||
dont_print_vb);
|
||||
|
||||
/* Second, print out data fields */
|
||||
|
||||
@ -253,11 +264,13 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
fputs_filtered ("\"( nodef \"", stream);
|
||||
if (field_is_static (&TYPE_FIELD (type, i)))
|
||||
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,
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
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,
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
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)))
|
||||
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,
|
||||
DMGL_PARAMS | DMGL_ANSI);
|
||||
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), ""))
|
||||
fputs_filtered (" = ", stream);
|
||||
annotate_field_value ();
|
||||
@ -283,8 +298,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
{
|
||||
struct value *v;
|
||||
|
||||
/* Bitfields require special handling, especially due to byte
|
||||
order problems. */
|
||||
/* Bitfields require special handling, especially due to
|
||||
byte order problems. */
|
||||
if (TYPE_FIELD_IGNORE (type, i))
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)))
|
||||
{
|
||||
@ -328,8 +345,9 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
if (v == NULL)
|
||||
fputs_filtered ("<optimized out>", stream);
|
||||
else
|
||||
cp_print_static_field (TYPE_FIELD_TYPE (type, i), v,
|
||||
stream, recurse + 1, options);
|
||||
cp_print_static_field (TYPE_FIELD_TYPE (type, i),
|
||||
v, stream, recurse + 1,
|
||||
options);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -337,7 +355,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
|
||||
opts.deref_ref = 0;
|
||||
val_print (TYPE_FIELD_TYPE (type, i),
|
||||
valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
|
||||
valaddr,
|
||||
offset + TYPE_FIELD_BITPOS (type, i) / 8,
|
||||
address,
|
||||
stream, recurse + 1, val, &opts,
|
||||
current_language);
|
||||
@ -351,16 +370,17 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
int obstack_final_size =
|
||||
obstack_object_size (&dont_print_statmem_obstack);
|
||||
|
||||
if (obstack_final_size > statmem_obstack_initial_size) {
|
||||
/* In effect, a pop of the printed-statics stack. */
|
||||
if (obstack_final_size > statmem_obstack_initial_size)
|
||||
{
|
||||
/* In effect, a pop of the printed-statics stack. */
|
||||
|
||||
void *free_to_ptr =
|
||||
obstack_next_free (&dont_print_statmem_obstack) -
|
||||
(obstack_final_size - statmem_obstack_initial_size);
|
||||
void *free_to_ptr =
|
||||
obstack_next_free (&dont_print_statmem_obstack) -
|
||||
(obstack_final_size - statmem_obstack_initial_size);
|
||||
|
||||
obstack_free (&dont_print_statmem_obstack,
|
||||
free_to_ptr);
|
||||
}
|
||||
obstack_free (&dont_print_statmem_obstack,
|
||||
free_to_ptr);
|
||||
}
|
||||
|
||||
if (last_set_recurse != recurse)
|
||||
{
|
||||
@ -370,8 +390,9 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
||||
if (obstack_final_size > stat_array_obstack_initial_size)
|
||||
{
|
||||
void *free_to_ptr =
|
||||
obstack_next_free (&dont_print_stat_array_obstack) -
|
||||
(obstack_final_size - stat_array_obstack_initial_size);
|
||||
obstack_next_free (&dont_print_stat_array_obstack)
|
||||
- (obstack_final_size
|
||||
- stat_array_obstack_initial_size);
|
||||
|
||||
obstack_free (&dont_print_stat_array_obstack,
|
||||
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. */
|
||||
value = value_from_contents_and_address (type, valaddr + offset,
|
||||
address + offset);
|
||||
/* We don't actually care about most of the result here -- just the
|
||||
type. We already have the correct offset, due to how val_print
|
||||
was initially called. */
|
||||
/* We don't actually care about most of the result here -- just
|
||||
the type. We already have the correct offset, due to how
|
||||
val_print was initially called. */
|
||||
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);
|
||||
}
|
||||
|
||||
/* Special val_print routine to avoid printing multiple copies of virtual
|
||||
baseclasses. */
|
||||
/* Special val_print routine to avoid printing multiple copies of
|
||||
virtual baseclasses. */
|
||||
|
||||
static void
|
||||
cp_print_value (struct type *type, struct type *real_type,
|
||||
const gdb_byte *valaddr, int offset, CORE_ADDR address,
|
||||
struct ui_file *stream, int recurse,
|
||||
const struct value *val,
|
||||
const gdb_byte *valaddr, int offset,
|
||||
CORE_ADDR address, struct ui_file *stream,
|
||||
int recurse, const struct value *val,
|
||||
const struct value_print_options *options,
|
||||
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 we're at top level, carve out a completely fresh
|
||||
chunk of the obstack and use that until this particular
|
||||
invocation returns. */
|
||||
/* If we're at top level, carve out a completely fresh chunk of
|
||||
the obstack and use that until this particular invocation
|
||||
returns. */
|
||||
/* Bump up the high-water mark. Now alpha is omega. */
|
||||
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 **) obstack_base (&dont_print_vb_obstack);
|
||||
|
||||
int j = (struct type **) obstack_next_free (&dont_print_vb_obstack)
|
||||
- first_dont_print;
|
||||
int j = (struct type **)
|
||||
obstack_next_free (&dont_print_vb_obstack) - first_dont_print;
|
||||
|
||||
while (--j >= 0)
|
||||
if (baseclass == first_dont_print[j])
|
||||
@ -486,20 +507,22 @@ cp_print_value (struct type *type, struct type *real_type,
|
||||
thisoffset = offset;
|
||||
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;
|
||||
|
||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||
{
|
||||
/* The virtual base class pointer might have been
|
||||
clobbered by the user program. Make sure that it
|
||||
still points to a valid memory location. */
|
||||
/* The virtual base class pointer might have been clobbered
|
||||
by the user program. Make sure that it still points to a
|
||||
valid memory location. */
|
||||
|
||||
if (boffset != -1
|
||||
&& ((boffset + offset) < 0
|
||||
|| (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));
|
||||
|
||||
base_valaddr = buf;
|
||||
@ -517,15 +540,15 @@ cp_print_value (struct type *type, struct type *real_type,
|
||||
else
|
||||
base_valaddr = valaddr;
|
||||
|
||||
/* now do the printing */
|
||||
/* Now do the printing. */
|
||||
if (options->pretty)
|
||||
{
|
||||
fprintf_filtered (stream, "\n");
|
||||
print_spaces_filtered (2 * recurse, stream);
|
||||
}
|
||||
fputs_filtered ("<", stream);
|
||||
/* Not sure what the best notation is in the case where there is no
|
||||
baseclass name. */
|
||||
/* Not sure what the best notation is in the case where there is
|
||||
no baseclass name. */
|
||||
fputs_filtered (basename ? basename : "", 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,
|
||||
thisoffset + boffset,
|
||||
address,
|
||||
stream, recurse, val,
|
||||
options,
|
||||
stream, recurse,
|
||||
val, options,
|
||||
current_language);
|
||||
|
||||
if (!result)
|
||||
@ -571,11 +594,10 @@ cp_print_value (struct type *type, struct type *real_type,
|
||||
}
|
||||
}
|
||||
|
||||
/* Print value of a static member.
|
||||
To avoid infinite recursion when printing a class that contains
|
||||
a static instance of the class, we keep the addresses of all printed
|
||||
static member classes in an obstack and refuse to print them more
|
||||
than once.
|
||||
/* Print value of a static member. To avoid infinite recursion when
|
||||
printing a class that contains a static instance of the class, we
|
||||
keep the addresses of all printed static member classes in an
|
||||
obstack and refuse to print them more than once.
|
||||
|
||||
VAL contains the value to print, TYPE, STREAM, RECURSE, and OPTIONS
|
||||
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),
|
||||
value_contents_for_printing (val),
|
||||
value_embedded_offset (val), addr,
|
||||
stream, recurse,
|
||||
val, options, NULL, 1);
|
||||
stream, recurse, val,
|
||||
options, NULL, 1);
|
||||
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 *));
|
||||
}
|
||||
|
||||
opts = *options;
|
||||
opts.deref_ref = 0;
|
||||
val_print (type, value_contents_for_printing (val),
|
||||
value_embedded_offset (val), value_address (val),
|
||||
stream, recurse,
|
||||
val, &opts, current_language);
|
||||
value_embedded_offset (val),
|
||||
value_address (val),
|
||||
stream, recurse, val,
|
||||
&opts, current_language);
|
||||
}
|
||||
|
||||
|
||||
/* Find the field in *DOMAIN, or its non-virtual base classes, with bit offset
|
||||
OFFSET. Set *DOMAIN to the containing type and *FIELDNO to the containing
|
||||
field number. If OFFSET is not exactly at the start of some field, set
|
||||
*DOMAIN to NULL. */
|
||||
/* Find the field in *DOMAIN, or its non-virtual base classes, with
|
||||
bit offset OFFSET. Set *DOMAIN to the containing type and *FIELDNO
|
||||
to the containing field number. If OFFSET is not exactly at the
|
||||
start of some field, set *DOMAIN to NULL. */
|
||||
|
||||
static void
|
||||
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;
|
||||
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.
|
||||
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,
|
||||
&setprintlist, &showprintlist);
|
||||
|
||||
obstack_begin (&dont_print_stat_array_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 *));
|
||||
obstack_begin (&dont_print_stat_array_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…
x
Reference in New Issue
Block a user