gdb: move pascal_language into p-lang.h

Move the pascal_language class declaration into the p-lang.h header
file.  This allows for the function implementations to be spread over
the different p-*.c files without the need for global trampoline
functions.

As a consequence of this change many of the Pascal value and type
printing helper functions have become member functions within the
pascal_language class.

There should be no user visible changes after this commit.

gdb/ChangeLog:

	* p-exp.y (exp): Update call to pascal_is_string_type.
	(pascal_parse): Rename to...
	(pascal_language::parser): ...this.
	* p-lang.c (is_pascal_string_type): Rename to...
	(pascal_is_string_type): ...this.
	(pascal_one_char): Rename to...
	(pascal_language::print_one_char): ...this.
	(pascal_printchar): Rename to...
	(pascal_language::printchar): ...this.  Update call to
	print_one_char member function.
	(pascal_op_print_tab): Rename to...
	(pascal_language::op_print_tab): ...this.
	(class pascal_language): Moved to p-lang.h.
	(pascal_language::language_arch_info): Function implementation
	moved out of class declaration.
	(pascal_language::printstr): Likewise.
	* p-lang.h (pascal_parse): Delete declaration.
	(pascal_is_string_type): Declare.
	(pascal_print_type): Delete declaration.
	(pascal_print_typedef): Delete declaration.
	(pascal_value_print_inner): Delete declaration.
	(pascal_value_print): Delete declaration.
	(pascal_type_print_method_args): Delete declaration.
	(is_pascal_string_type): Delete declaration.
	(pascal_printchar): Delete declaration.
	(pascal_builtin_types): Delete declaration.
	(pascal_type_print_base): Delete declaration.
	(pascal_type_print_varspec_prefix): Delete declaration.
	(class pascal_language): Moved here from p-lang.c.
	* p-typeprint.c (pascal_type_print_varspec_suffix): Delete
	declaration.
	(pascal_type_print_derivation_info): Delete declaration.
	(pascal_print_type): Rename to...
	(pascal_language::print_type): ...this.  Update calls to member
	functions.
	(pascal_print_typedef): Rename to...
	(pascal_language::print_typedef): ...this.  Update calls to member
	functions.
	(pascal_type_print_derivation_info): Rename to...
	(pascal_language::type_print_derivation_info): ...this.
	(pascal_type_print_method_args): Rename to...
	(pascal_language::type_print_method_args): ...this.
	(pascal_type_print_varspec_prefix): Rename to...
	(pascal_language::type_print_varspec_prefix): ...this.  Update
	calls to member functions.
	(pascal_print_func_args): Rename to...
	(pascal_language::print_func_args): ...this.  Update calls to
	member functions.
	(pascal_type_print_func_varspec_suffix): Rename to...
	(pascal_language::type_print_func_varspec_suffix): ...this.
	Update calls to member functions.
	(pascal_type_print_varspec_suffix): Rename to...
	(pascal_language::type_print_varspec_suffix): ...this.  Update
	calls to member functions.
	(pascal_type_print_base): Rename to...
	(pascal_language::type_print_base): ...this.  Update calls to
	member functions.
	* p-valprint.c (pascal_value_print_inner): Rename to...
	(pascal_language::value_print_inner): ...this.  Update calls to
	member functions.
	(pascal_value_print): Rename to...
	(pascal_language::value_print): ...this.  Update calls to member
	functions.
This commit is contained in:
Andrew Burgess
2020-10-28 18:10:01 +00:00
parent 82fc57fd6b
commit 46157d77c3
6 changed files with 514 additions and 444 deletions

View File

@@ -84,20 +84,11 @@ pascal_main_name (void)
return NULL;
}
/* Determines if type TYPE is a pascal string type.
Returns a positive value if the type is a known pascal string type.
This function is used by p-valprint.c code to allow better string display.
If it is a pascal string type, then it also sets info needed
to get the length and the data of the string
length_pos, length_size and string_pos are given in bytes.
char_size gives the element size in bytes.
FIXME: if the position or the size of these fields
are not multiple of TARGET_CHAR_BIT then the results are wrong
but this does not happen for Free Pascal nor for GPC. */
/* See p-lang.h. */
int
is_pascal_string_type (struct type *type,int *length_pos,
int *length_size, int *string_pos,
struct type **char_type,
pascal_is_string_type (struct type *type,int *length_pos, int *length_size,
int *string_pos, struct type **char_type,
const char **arrayname)
{
if (type != NULL && type->code () == TYPE_CODE_STRUCT)
@@ -152,14 +143,11 @@ is_pascal_string_type (struct type *type,int *length_pos,
return 0;
}
static void pascal_one_char (int, struct ui_file *, int *);
/* See p-lang.h. */
/* Print the character C on STREAM as part of the contents of a literal
string.
In_quotes is reset to 0 if a char is written with #4 notation. */
static void
pascal_one_char (int c, struct ui_file *stream, int *in_quotes)
void
pascal_language::print_one_char (int c, struct ui_file *stream,
int *in_quotes) const
{
if (c == '\'' || ((unsigned int) c <= 0xff && (PRINT_LITERAL_FORM (c))))
{
@@ -182,12 +170,15 @@ pascal_one_char (int c, struct ui_file *stream, int *in_quotes)
}
}
/* See language.h. */
void
pascal_printchar (int c, struct type *type, struct ui_file *stream)
pascal_language::printchar (int c, struct type *type,
struct ui_file *stream) const
{
int in_quotes = 0;
pascal_one_char (c, stream, &in_quotes);
print_one_char (c, stream, &in_quotes);
if (in_quotes)
fputs_filtered ("'", stream);
}
@@ -197,7 +188,7 @@ pascal_printchar (int c, struct type *type, struct ui_file *stream)
/* Table mapping opcodes into strings for printing operators
and precedences of the operators. */
const struct op_print pascal_op_print_tab[] =
const struct op_print pascal_language::op_print_tab[] =
{
{",", BINOP_COMMA, PREC_COMMA, 0},
{":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
@@ -228,249 +219,138 @@ const struct op_print pascal_op_print_tab[] =
};
/* Class representing the Pascal language. */
/* See language.h. */
class pascal_language : public language_defn
void pascal_language::language_arch_info
(struct gdbarch *gdbarch, struct language_arch_info *lai) const
{
public:
pascal_language ()
: language_defn (language_pascal)
{ /* Nothing. */ }
const struct builtin_type *builtin = builtin_type (gdbarch);
/* See language.h. */
const char *name () const override
{ return "pascal"; }
/* See language.h. */
const char *natural_name () const override
{ return "Pascal"; }
/* See language.h. */
const std::vector<const char *> &filename_extensions () const override
/* Helper function to allow shorter lines below. */
auto add = [&] (struct type * t)
{
static const std::vector<const char *> extensions
= { ".pas", ".p", ".pp" };
return extensions;
}
lai->add_primitive_type (t);
};
/* See language.h. */
void language_arch_info (struct gdbarch *gdbarch,
struct language_arch_info *lai) const override
{
const struct builtin_type *builtin = builtin_type (gdbarch);
add (builtin->builtin_int);
add (builtin->builtin_long);
add (builtin->builtin_short);
add (builtin->builtin_char);
add (builtin->builtin_float);
add (builtin->builtin_double);
add (builtin->builtin_void);
add (builtin->builtin_long_long);
add (builtin->builtin_signed_char);
add (builtin->builtin_unsigned_char);
add (builtin->builtin_unsigned_short);
add (builtin->builtin_unsigned_int);
add (builtin->builtin_unsigned_long);
add (builtin->builtin_unsigned_long_long);
add (builtin->builtin_long_double);
add (builtin->builtin_complex);
add (builtin->builtin_double_complex);
/* Helper function to allow shorter lines below. */
auto add = [&] (struct type * t)
lai->set_string_char_type (builtin->builtin_char);
lai->set_bool_type (builtin->builtin_bool, "boolean");
}
/* See language.h. */
void
pascal_language::printstr (struct ui_file *stream, struct type *elttype,
const gdb_byte *string, unsigned int length,
const char *encoding, int force_ellipses,
const struct value_print_options *options) const
{
enum bfd_endian byte_order = type_byte_order (elttype);
unsigned int i;
unsigned int things_printed = 0;
int in_quotes = 0;
int need_comma = 0;
int width;
/* Preserve ELTTYPE's original type, just set its LENGTH. */
check_typedef (elttype);
width = TYPE_LENGTH (elttype);
/* 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. */
if ((!force_ellipses) && length > 0
&& extract_unsigned_integer (string + (length - 1) * width, width,
byte_order) == 0)
length--;
if (length == 0)
{
lai->add_primitive_type (t);
};
fputs_filtered ("''", stream);
return;
}
add (builtin->builtin_int);
add (builtin->builtin_long);
add (builtin->builtin_short);
add (builtin->builtin_char);
add (builtin->builtin_float);
add (builtin->builtin_double);
add (builtin->builtin_void);
add (builtin->builtin_long_long);
add (builtin->builtin_signed_char);
add (builtin->builtin_unsigned_char);
add (builtin->builtin_unsigned_short);
add (builtin->builtin_unsigned_int);
add (builtin->builtin_unsigned_long);
add (builtin->builtin_unsigned_long_long);
add (builtin->builtin_long_double);
add (builtin->builtin_complex);
add (builtin->builtin_double_complex);
for (i = 0; i < length && things_printed < options->print_max; ++i)
{
/* Position of the character we are examining
to see whether it is repeated. */
unsigned int rep1;
/* Number of repetitions we have detected so far. */
unsigned int reps;
unsigned long int current_char;
lai->set_string_char_type (builtin->builtin_char);
lai->set_bool_type (builtin->builtin_bool, "boolean");
}
QUIT;
/* See language.h. */
if (need_comma)
{
fputs_filtered (", ", stream);
need_comma = 0;
}
void print_type (struct type *type, const char *varstring,
struct ui_file *stream, int show, int level,
const struct type_print_options *flags) const override
{
pascal_print_type (type, varstring, stream, show, level, flags);
}
current_char = extract_unsigned_integer (string + i * width, width,
byte_order);
/* See language.h. */
rep1 = i + 1;
reps = 1;
while (rep1 < length
&& extract_unsigned_integer (string + rep1 * width, width,
byte_order) == current_char)
{
++rep1;
++reps;
}
void value_print (struct value *val, struct ui_file *stream,
const struct value_print_options *options) const override
{
return pascal_value_print (val, stream, options);
}
if (reps > options->repeat_count_threshold)
{
if (in_quotes)
{
fputs_filtered ("', ", stream);
in_quotes = 0;
}
printchar (current_char, elttype, stream);
fprintf_filtered (stream, " %p[<repeats %u times>%p]",
metadata_style.style ().ptr (),
reps, nullptr);
i = rep1 - 1;
things_printed += options->repeat_count_threshold;
need_comma = 1;
}
else
{
if ((!in_quotes) && (PRINT_LITERAL_FORM (current_char)))
{
fputs_filtered ("'", stream);
in_quotes = 1;
}
print_one_char (current_char, stream, &in_quotes);
++things_printed;
}
}
/* See language.h. */
/* Terminate the quotes if necessary. */
if (in_quotes)
fputs_filtered ("'", stream);
void value_print_inner
(struct value *val, struct ui_file *stream, int recurse,
const struct value_print_options *options) const override
{
return pascal_value_print_inner (val, stream, recurse, options);
}
/* See language.h. */
int parser (struct parser_state *ps) const override
{
return pascal_parse (ps);
}
/* See language.h. */
void emitchar (int ch, struct type *chtype,
struct ui_file *stream, int quoter) const override
{
int in_quotes = 0;
pascal_one_char (ch, stream, &in_quotes);
if (in_quotes)
fputs_filtered ("'", stream);
}
/* See language.h. */
void printchar (int ch, struct type *chtype,
struct ui_file *stream) const override
{
pascal_printchar (ch, chtype, stream);
}
/* See language.h. */
void printstr (struct ui_file *stream, struct type *elttype,
const gdb_byte *string, unsigned int length,
const char *encoding, int force_ellipses,
const struct value_print_options *options) const override
{
enum bfd_endian byte_order = type_byte_order (elttype);
unsigned int i;
unsigned int things_printed = 0;
int in_quotes = 0;
int need_comma = 0;
int width;
/* Preserve ELTTYPE's original type, just set its LENGTH. */
check_typedef (elttype);
width = TYPE_LENGTH (elttype);
/* 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. */
if ((!force_ellipses) && length > 0
&& extract_unsigned_integer (string + (length - 1) * width, width,
byte_order) == 0)
length--;
if (length == 0)
{
fputs_filtered ("''", stream);
return;
}
for (i = 0; i < length && things_printed < options->print_max; ++i)
{
/* Position of the character we are examining
to see whether it is repeated. */
unsigned int rep1;
/* Number of repetitions we have detected so far. */
unsigned int reps;
unsigned long int current_char;
QUIT;
if (need_comma)
{
fputs_filtered (", ", stream);
need_comma = 0;
}
current_char = extract_unsigned_integer (string + i * width, width,
byte_order);
rep1 = i + 1;
reps = 1;
while (rep1 < length
&& extract_unsigned_integer (string + rep1 * width, width,
byte_order) == current_char)
{
++rep1;
++reps;
}
if (reps > options->repeat_count_threshold)
{
if (in_quotes)
{
fputs_filtered ("', ", stream);
in_quotes = 0;
}
pascal_printchar (current_char, elttype, stream);
fprintf_filtered (stream, " %p[<repeats %u times>%p]",
metadata_style.style ().ptr (),
reps, nullptr);
i = rep1 - 1;
things_printed += options->repeat_count_threshold;
need_comma = 1;
}
else
{
if ((!in_quotes) && (PRINT_LITERAL_FORM (current_char)))
{
fputs_filtered ("'", stream);
in_quotes = 1;
}
pascal_one_char (current_char, stream, &in_quotes);
++things_printed;
}
}
/* Terminate the quotes if necessary. */
if (in_quotes)
fputs_filtered ("'", stream);
if (force_ellipses || i < length)
fputs_filtered ("...", stream);
}
/* See language.h. */
void print_typedef (struct type *type, struct symbol *new_symbol,
struct ui_file *stream) const override
{
pascal_print_typedef (type, new_symbol, stream);
}
/* See language.h. */
bool is_string_type_p (struct type *type) const override
{
return is_pascal_string_type (type, nullptr, nullptr, nullptr,
nullptr, nullptr) > 0;
}
/* See language.h. */
const char *name_of_this () const override
{ return "this"; }
/* See language.h. */
bool range_checking_on_by_default () const override
{ return true; }
/* See language.h. */
const struct op_print *opcode_print_table () const override
{ return pascal_op_print_tab; }
};
if (force_ellipses || i < length)
fputs_filtered ("...", stream);
}
/* Single instance of the Pascal language class. */