* [PATCH 0/9] Further language class related changes
@ 2020-11-20 11:54 Andrew Burgess
2020-11-20 11:54 ` [PATCH 1/9] gdb: delete unused function print_char_chars Andrew Burgess
` (9 more replies)
0 siblings, 10 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:54 UTC (permalink / raw)
To: gdb-patches
The changes in this series do two things:
1. Reduce the use of the LA_* macros from language.h, with
LA_EMIT_CHAR being completely removed, and LA_PRINT_STRING being
reduced in usage.
2. Move some additional language classes into the language's header
file. This allows functions defined in different *.c files to be
renamed as language_class::member_function rather than having to
trampoline from the member function to a global.
The patch that's most worth reviewing is, I think #2 where I replace
direct calls to a global function with calls to a language classes
member functions.
All feedback welcome.
Thanks,
Andrew
---
Andrew Burgess (9):
gdb: delete unused function print_char_chars
gdb: avoid accessing global C++ language implementation functions
gdb: rename c_printchar as language_defn::printchar
gdb: remove LA_EMIT_CHAR macro
gdb: move go_language class declaration into header file
gdb: move pascal_language into p-lang.h
gdb/objc: fix bug in objc_language::opcode_print_table
gdb: move rust_language into rust-lang.h
gdb: remove some uses of LA_PRINT_STRING
gdb/ChangeLog | 162 ++++++++++++++
gdb/c-lang.c | 7 +-
gdb/c-lang.h | 2 -
gdb/dwarf2/read.c | 7 +-
gdb/expprint.c | 19 +-
gdb/f-lang.h | 2 +-
gdb/f-valprint.c | 10 +-
gdb/go-exp.y | 4 +-
gdb/go-lang.c | 164 ++++-----------
gdb/go-lang.h | 94 +++++++--
gdb/go-typeprint.c | 6 +-
gdb/go-valprint.c | 5 +-
gdb/guile/scm-pretty-print.c | 4 +-
gdb/language.c | 9 -
gdb/language.h | 2 -
gdb/objc-lang.c | 2 +-
gdb/p-exp.y | 11 +-
gdb/p-lang.c | 384 ++++++++++++---------------------
gdb/p-lang.h | 245 ++++++++++++++++++---
gdb/p-typeprint.c | 214 +++++++------------
gdb/p-valprint.c | 30 ++-
gdb/python/py-prettyprint.c | 4 +-
gdb/rust-exp.y | 2 +-
gdb/rust-lang.c | 397 +++++++++++------------------------
gdb/rust-lang.h | 198 ++++++++++++++++-
gdb/symtab.c | 3 +-
gdb/valprint.c | 37 ----
gdb/valprint.h | 3 -
28 files changed, 1089 insertions(+), 938 deletions(-)
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/9] gdb: delete unused function print_char_chars
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
@ 2020-11-20 11:54 ` Andrew Burgess
2020-11-20 11:54 ` [PATCH 2/9] gdb: avoid accessing global C++ language implementation functions Andrew Burgess
` (8 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:54 UTC (permalink / raw)
To: gdb-patches
Spotted that print_char_chars appears to be unused, delete it. There
should be no user visible changes after this commit.
gdb/ChangeLog:
* valprint.c (print_char_chars): Delete definition.
* valprint.h (print_char_chars): Delete declaration.
---
gdb/ChangeLog | 5 +++++
gdb/valprint.c | 37 -------------------------------------
gdb/valprint.h | 3 ---
3 files changed, 5 insertions(+), 40 deletions(-)
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 38ae0bdf0e2..46ff931fd3d 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -1827,43 +1827,6 @@ print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr,
}
}
-/* VALADDR points to a char integer of LEN bytes.
- Print it out in appropriate language form on stream.
- Omit any leading zero chars. */
-
-void
-print_char_chars (struct ui_file *stream, struct type *type,
- const gdb_byte *valaddr,
- unsigned len, enum bfd_endian byte_order)
-{
- const gdb_byte *p;
-
- if (byte_order == BFD_ENDIAN_BIG)
- {
- p = valaddr;
- while (p < valaddr + len - 1 && *p == 0)
- ++p;
-
- while (p < valaddr + len)
- {
- LA_EMIT_CHAR (*p, type, stream, '\'');
- ++p;
- }
- }
- else
- {
- p = valaddr + len - 1;
- while (p > valaddr && *p == 0)
- --p;
-
- while (p >= valaddr)
- {
- LA_EMIT_CHAR (*p, type, stream, '\'');
- --p;
- }
- }
-}
-
/* Print function pointer with inferior address ADDRESS onto stdio
stream STREAM. */
diff --git a/gdb/valprint.h b/gdb/valprint.h
index ef9ebfa84f0..47f6ed009b9 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -157,9 +157,6 @@ extern void print_decimal_chars (struct ui_file *, const gdb_byte *,
extern void print_hex_chars (struct ui_file *, const gdb_byte *,
unsigned int, enum bfd_endian, bool);
-extern void print_char_chars (struct ui_file *, struct type *,
- const gdb_byte *, unsigned int, enum bfd_endian);
-
extern void print_function_pointer_address (const struct value_print_options *options,
struct gdbarch *gdbarch,
CORE_ADDR address,
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/9] gdb: avoid accessing global C++ language implementation functions
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
2020-11-20 11:54 ` [PATCH 1/9] gdb: delete unused function print_char_chars Andrew Burgess
@ 2020-11-20 11:54 ` Andrew Burgess
2020-12-10 20:47 ` Tom Tromey
2020-11-20 11:54 ` [PATCH 3/9] gdb: rename c_printchar as language_defn::printchar Andrew Burgess
` (7 subsequent siblings)
9 siblings, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:54 UTC (permalink / raw)
To: gdb-patches
The function c_printchar is called from two places; it provides the
implementation of language_defn::printchar and it is called from
dwarf2_compute_name.
It would be nice to rename c_printchar as language_defn::printchar and
so avoid the trampoline.
To achieve this, instead of calling c_printchar directly from the
DWARF code, I lookup the C++ language object and call the printchar
member function.
In a later commit I can then rename c_printchar.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* dwarf2/read.c (dwarf2_compute_name): Call methods on C++
language object instead of calling global functions directly.
---
gdb/ChangeLog | 5 +++++
gdb/dwarf2/read.c | 7 ++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3c598262913..b3e51d49584 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -10464,6 +10464,7 @@ dwarf2_compute_name (const char *name,
struct attribute *attr;
struct die_info *child;
int first = 1;
+ const language_defn *cplus_lang = language_def (cu->language);
die->building_fullname = 1;
@@ -10498,8 +10499,8 @@ dwarf2_compute_name (const char *name,
if (child->tag == DW_TAG_template_type_param)
{
- c_print_type (type, "", &buf, -1, 0, cu->language,
- &type_print_raw_options);
+ cplus_lang->print_type (type, "", &buf, -1, 0,
+ &type_print_raw_options);
continue;
}
@@ -10519,7 +10520,7 @@ dwarf2_compute_name (const char *name,
if (type->has_no_signedness ())
/* GDB prints characters as NUMBER 'CHAR'. If that's
changed, this can use value_print instead. */
- c_printchar (value, type, &buf);
+ cplus_lang->printchar (value, type, &buf);
else
{
struct value_print_options opts;
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/9] gdb: rename c_printchar as language_defn::printchar
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
2020-11-20 11:54 ` [PATCH 1/9] gdb: delete unused function print_char_chars Andrew Burgess
2020-11-20 11:54 ` [PATCH 2/9] gdb: avoid accessing global C++ language implementation functions Andrew Burgess
@ 2020-11-20 11:54 ` Andrew Burgess
2020-11-20 11:54 ` [PATCH 4/9] gdb: remove LA_EMIT_CHAR macro Andrew Burgess
` (6 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:54 UTC (permalink / raw)
To: gdb-patches
This commit removes the global function c_printchar and moves the
implementation into language_defn::printchar.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* c-lang.c (c_printchar): Rename to...
(language_defn::printchar): ...this.
* c-lang.h (c_printchar): Delete declaration.
* language.c (language_defn::printchar): Delete this
implementation. Is now implemented in c-lang.c.
---
gdb/ChangeLog | 8 ++++++++
gdb/c-lang.c | 5 ++++-
gdb/c-lang.h | 2 --
gdb/language.c | 9 ---------
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 624aea52f77..5d696b1b356 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -153,8 +153,11 @@ c_emit_char (int c, struct type *type,
generic_emit_char (c, type, stream, quoter, encoding);
}
+/* See language.h. */
+
void
-c_printchar (int c, struct type *type, struct ui_file *stream)
+language_defn::printchar (int c, struct type *type,
+ struct ui_file * stream) const
{
c_string_type str_type;
diff --git a/gdb/c-lang.h b/gdb/c-lang.h
index 6c5d0d814c4..846faaaaaa2 100644
--- a/gdb/c-lang.h
+++ b/gdb/c-lang.h
@@ -96,8 +96,6 @@ extern struct value *evaluate_subexp_c (struct type *expect_type,
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,
diff --git a/gdb/language.c b/gdb/language.c
index 579cf9198c8..d1bcc738b33 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -677,15 +677,6 @@ language_defn::emitchar (int ch, struct type *chtype,
/* See language.h. */
-void
-language_defn::printchar (int ch, struct type *chtype,
- struct ui_file * stream) const
-{
- c_printchar (ch, chtype, stream);
-}
-
-/* See language.h. */
-
void
language_defn::printstr (struct ui_file *stream, struct type *elttype,
const gdb_byte *string, unsigned int length,
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/9] gdb: remove LA_EMIT_CHAR macro
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
` (2 preceding siblings ...)
2020-11-20 11:54 ` [PATCH 3/9] gdb: rename c_printchar as language_defn::printchar Andrew Burgess
@ 2020-11-20 11:54 ` Andrew Burgess
2020-11-20 11:55 ` [PATCH 5/9] gdb: move go_language class declaration into header file Andrew Burgess
` (5 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:54 UTC (permalink / raw)
To: gdb-patches
Now that every use of the LA_EMIT_CHAR macro is within a language_defn
member function we can simply call the emitchar member function
directly instead of using the LA_EMIT_CHAR macro.
If we are ever inside a language object, for example, cplus_language,
while current_language points at something other than cplus_language
then this commit will result in a change in behaviour. However, I
believe if we did have such a difference then this would be a bug in
GDB. AS such I'm going to claim there _should_ be no user visible
changes from this commit.
gdb/ChangeLog:
* c-lang.c (language_defn::printchar): Call emitchar, not
LA_EMIT_CHAR.
* f-lang.h (f_language::printchar): Likewise.
* language.h (LA_EMIT_CHAR): Delete macro.
* rust-lang.c (rust_language::printchar): Call emitchar, not
LA_EMIT_CHAR.
---
gdb/ChangeLog | 9 +++++++++
gdb/c-lang.c | 2 +-
gdb/f-lang.h | 2 +-
gdb/language.h | 2 --
gdb/rust-lang.c | 2 +-
5 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 5d696b1b356..e983804a9f8 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -178,7 +178,7 @@ language_defn::printchar (int c, struct type *type,
}
fputc_filtered ('\'', stream);
- LA_EMIT_CHAR (c, type, stream, '\'');
+ emitchar (c, type, stream, '\'');
fputc_filtered ('\'', stream);
}
diff --git a/gdb/f-lang.h b/gdb/f-lang.h
index 351f2191c16..51ee6f67d07 100644
--- a/gdb/f-lang.h
+++ b/gdb/f-lang.h
@@ -155,7 +155,7 @@ class f_language : public language_defn
struct ui_file *stream) const override
{
fputs_filtered ("'", stream);
- LA_EMIT_CHAR (ch, chtype, stream, '\'');
+ emitchar (ch, chtype, stream, '\'');
fputs_filtered ("'", stream);
}
diff --git a/gdb/language.h b/gdb/language.h
index 1b602646651..815b1923d58 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -768,8 +768,6 @@ extern enum language set_language (enum language);
#define LA_PRINT_STRING(stream, elttype, string, length, encoding, force_ellipses, options) \
(current_language->printstr (stream, elttype, string, length, \
encoding, force_ellipses,options))
-#define LA_EMIT_CHAR(ch, type, stream, quoter) \
- (current_language->emitchar (ch, type, stream, quoter))
/* Test a character to decide whether it can be printed in literal form
or needs to be printed in another representation. For example,
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index 407be569308..4cfe44a1ad7 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -2069,7 +2069,7 @@ class rust_language : public language_defn
struct ui_file *stream) const override
{
fputs_filtered ("'", stream);
- LA_EMIT_CHAR (ch, chtype, stream, '\'');
+ emitchar (ch, chtype, stream, '\'');
fputs_filtered ("'", stream);
}
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 5/9] gdb: move go_language class declaration into header file
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
` (3 preceding siblings ...)
2020-11-20 11:54 ` [PATCH 4/9] gdb: remove LA_EMIT_CHAR macro Andrew Burgess
@ 2020-11-20 11:55 ` Andrew Burgess
2020-11-20 11:55 ` [PATCH 6/9] gdb: move pascal_language into p-lang.h Andrew Burgess
` (4 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:55 UTC (permalink / raw)
To: gdb-patches
Move the go_language class into go-lang.h, this allows us to have
member functions implemented directly in the different go-*.c files
instead of having to trampoline out to global functions.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* go-exp.y (go_parse): Rename to...
(go_language::parser): ...this.
* go-lang.c (go_demangle): Rename to...
(go_language::demangle_symbol): ...this.
(go_language::expression_ops): Implementation moved here out of
class declaration.
(go_op_print_tab): Rename to...
(go_language::op_print_tab): ...this, update comment.
(class go_language): Declaration moved to go-lang.h.
(go_language::language_arch_info): Implementation moved here out
of class declaration.
* go-lang.h (go_parse): Delete declaration.
(go_demangle): Delete declaration.
(go_print_type): Delete declaration.
(go_value_print_inner): Delete declaration.
(class go_language): Declaration moved here from go-lang.c.
* go-typeprint.c (go_print_type): Rename to...
(go_language::print_type): ...this.
* go-valprint.c (go_value_print_inner): Rename to...
(go_language::value_print_inner): ...this.
* symtab.c (demangle_for_lookup): Call demangle_symbol method on
the go_language object.
---
gdb/ChangeLog | 25 +++++++
gdb/go-exp.y | 4 +-
gdb/go-lang.c | 164 +++++++++++++--------------------------------
gdb/go-lang.h | 94 ++++++++++++++++++++++----
gdb/go-typeprint.c | 6 +-
gdb/go-valprint.c | 5 +-
gdb/symtab.c | 3 +-
7 files changed, 161 insertions(+), 140 deletions(-)
diff --git a/gdb/go-exp.y b/gdb/go-exp.y
index a9118749097..078bdca732c 100644
--- a/gdb/go-exp.y
+++ b/gdb/go-exp.y
@@ -1550,8 +1550,10 @@ yylex (void)
return classify_name (pstate, pstate->expression_context_block);
}
+/* See language.h. */
+
int
-go_parse (struct parser_state *par_state)
+go_language::parser (struct parser_state *par_state) const
{
/* Setting up the parser state. */
scoped_restore pstate_restore = make_scoped_restore (&pstate);
diff --git a/gdb/go-lang.c b/gdb/go-lang.c
index 4547b52219b..eafcfb4676a 100644
--- a/gdb/go-lang.c
+++ b/gdb/go-lang.c
@@ -334,7 +334,7 @@ unpack_mangled_go_symbol (const char *mangled_name,
thus not too much effort is currently put into it. */
char *
-go_demangle (const char *mangled_name, int options)
+go_language::demangle_symbol (const char *mangled_name, int options) const
{
struct obstack tempbuf;
char *result;
@@ -386,6 +386,14 @@ go_demangle (const char *mangled_name, int options)
return result;
}
+/* See language.h. */
+
+const struct exp_descriptor *
+go_language::expression_ops () const
+{
+ return &exp_descriptor_c;
+}
+
/* Given a Go symbol, return its package or NULL if unknown.
Space for the result is malloc'd, caller must free. */
@@ -444,11 +452,11 @@ go_block_package_name (const struct block *block)
return NULL;
}
-/* Table mapping opcodes into strings for printing operators
- and precedences of the operators.
+/* See go-lang.h.
+
TODO(dje): &^ ? */
-static const struct op_print go_op_print_tab[] =
+const struct op_print go_language::op_print_tab[] =
{
{",", BINOP_COMMA, PREC_COMMA, 0},
{"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
@@ -482,125 +490,43 @@ static const struct op_print go_op_print_tab[] =
{NULL, OP_NULL, PREC_SUFFIX, 0}
};
-/* Class representing the Go language. */
+/* See language.h. */
-class go_language : public language_defn
+void
+go_language::language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai) const
{
-public:
- go_language ()
- : language_defn (language_go)
- { /* Nothing. */ }
-
- /* See language.h. */
-
- const char *name () const override
- { return "go"; }
-
- /* See language.h. */
-
- const char *natural_name () const override
- { return "Go"; }
-
- /* See language.h. */
- void language_arch_info (struct gdbarch *gdbarch,
- struct language_arch_info *lai) const override
- {
- const struct builtin_go_type *builtin = builtin_go_type (gdbarch);
-
- /* Helper function to allow shorter lines below. */
- auto add = [&] (struct type * t) -> struct type *
- {
- lai->add_primitive_type (t);
- return t;
- };
-
- add (builtin->builtin_void);
- add (builtin->builtin_char);
- add (builtin->builtin_bool);
- add (builtin->builtin_int);
- add (builtin->builtin_uint);
- add (builtin->builtin_uintptr);
- add (builtin->builtin_int8);
- add (builtin->builtin_int16);
- add (builtin->builtin_int32);
- add (builtin->builtin_int64);
- add (builtin->builtin_uint8);
- add (builtin->builtin_uint16);
- add (builtin->builtin_uint32);
- add (builtin->builtin_uint64);
- add (builtin->builtin_float32);
- add (builtin->builtin_float64);
- add (builtin->builtin_complex64);
- add (builtin->builtin_complex128);
-
- lai->set_string_char_type (builtin->builtin_char);
- lai->set_bool_type (builtin->builtin_bool, "bool");
- }
-
- /* See language.h. */
- bool sniff_from_mangled_name (const char *mangled,
- char **demangled) const override
- {
- *demangled = go_demangle (mangled, 0);
- return *demangled != NULL;
- }
-
- /* See language.h. */
-
- char *demangle_symbol (const char *mangled, int options) const override
- {
- return go_demangle (mangled, options);
- }
+ const struct builtin_go_type *builtin = builtin_go_type (gdbarch);
- /* See language.h. */
-
- 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
- {
- go_print_type (type, varstring, stream, show, level, flags);
- }
-
- /* See language.h. */
-
- void value_print_inner
- (struct value *val, struct ui_file *stream, int recurse,
- const struct value_print_options *options) const override
- {
- return go_value_print_inner (val, stream, recurse, options);
- }
-
- /* See language.h. */
-
- int parser (struct parser_state *ps) const override
- {
- return go_parse (ps);
- }
-
- /* See language.h. */
-
- bool is_string_type_p (struct type *type) const override
+ /* Helper function to allow shorter lines below. */
+ auto add = [&] (struct type * t) -> struct type *
{
- type = check_typedef (type);
- return (type->code () == TYPE_CODE_STRUCT
- && go_classify_struct_type (type) == GO_TYPE_STRING);
- }
-
- /* See language.h. */
-
- bool store_sym_names_in_linkage_form_p () const override
- { return true; }
-
- /* See language.h. */
-
- const struct exp_descriptor *expression_ops () const override
- { return &exp_descriptor_c; }
-
- /* See language.h. */
-
- const struct op_print *opcode_print_table () const override
- { return go_op_print_tab; }
-};
+ lai->add_primitive_type (t);
+ return t;
+ };
+
+ add (builtin->builtin_void);
+ add (builtin->builtin_char);
+ add (builtin->builtin_bool);
+ add (builtin->builtin_int);
+ add (builtin->builtin_uint);
+ add (builtin->builtin_uintptr);
+ add (builtin->builtin_int8);
+ add (builtin->builtin_int16);
+ add (builtin->builtin_int32);
+ add (builtin->builtin_int64);
+ add (builtin->builtin_uint8);
+ add (builtin->builtin_uint16);
+ add (builtin->builtin_uint32);
+ add (builtin->builtin_uint64);
+ add (builtin->builtin_float32);
+ add (builtin->builtin_float64);
+ add (builtin->builtin_complex64);
+ add (builtin->builtin_complex128);
+
+ lai->set_string_char_type (builtin->builtin_char);
+ lai->set_bool_type (builtin->builtin_bool, "bool");
+}
/* Single instance of the Go language class. */
diff --git a/gdb/go-lang.h b/gdb/go-lang.h
index 1f079071995..532b4eb0887 100644
--- a/gdb/go-lang.h
+++ b/gdb/go-lang.h
@@ -56,34 +56,100 @@ enum go_type
GO_TYPE_STRING
};
-/* Defined in go-exp.y. */
-
-extern int go_parse (struct parser_state *);
-
/* Defined in go-lang.c. */
extern const char *go_main_name (void);
extern enum go_type go_classify_struct_type (struct type *type);
-extern char *go_demangle (const char *mangled, int options);
-
extern char *go_symbol_package_name (const struct symbol *sym);
extern char *go_block_package_name (const struct block *block);
extern const struct builtin_go_type *builtin_go_type (struct gdbarch *);
-/* Defined in go-typeprint.c. */
+/* Class representing the Go language. */
+
+class go_language : public language_defn
+{
+public:
+ go_language ()
+ : language_defn (language_go)
+ { /* Nothing. */ }
+
+ /* See language.h. */
+
+ const char *name () const override
+ { return "go"; }
+
+ /* See language.h. */
+
+ const char *natural_name () const override
+ { return "Go"; }
+
+ /* See language.h. */
+
+ void language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai) const override;
+
+ /* See language.h. */
+
+ bool sniff_from_mangled_name (const char *mangled,
+ char **demangled) const override
+ {
+ *demangled = demangle_symbol (mangled, 0);
+ return *demangled != NULL;
+ }
+
+ /* See language.h. */
+
+ char *demangle_symbol (const char *mangled, int options) const override;
+
+ /* See language.h. */
-extern void go_print_type (struct type *type, const char *varstring,
- struct ui_file *stream, int show, int level,
- const struct type_print_options *flags);
+ 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;
-/* Implement la_value_print_inner for Go. */
+ /* See language.h. */
-extern void go_value_print_inner (struct value *value,
- struct ui_file *stream, int recurse,
- const struct value_print_options *options);
+ void value_print_inner
+ (struct value *val, struct ui_file *stream, int recurse,
+ const struct value_print_options *options) const override;
+
+ /* See language.h. */
+
+ int parser (struct parser_state *ps) const override;
+
+ /* See language.h. */
+
+ bool is_string_type_p (struct type *type) const override
+ {
+ type = check_typedef (type);
+ return (type->code () == TYPE_CODE_STRUCT
+ && go_classify_struct_type (type) == GO_TYPE_STRING);
+ }
+
+ /* See language.h. */
+
+ bool store_sym_names_in_linkage_form_p () const override
+ { return true; }
+
+ /* See language.h. */
+
+ const struct exp_descriptor *expression_ops () const override;
+
+ /* See language.h. */
+
+ const struct op_print *opcode_print_table () const override
+ { return op_print_tab; }
+
+private:
+
+ /* Table of opcode data for use by OPCODE_PRINT_TABLE member function. */
+
+ static const struct op_print op_print_tab[];
+
+};
#endif /* !defined (GO_LANG_H) */
diff --git a/gdb/go-typeprint.c b/gdb/go-typeprint.c
index c334914398d..d768498e639 100644
--- a/gdb/go-typeprint.c
+++ b/gdb/go-typeprint.c
@@ -42,9 +42,9 @@
LEVEL indicates level of recursion (for nested definitions). */
void
-go_print_type (struct type *type, const char *varstring,
- struct ui_file *stream, int show, int level,
- const struct type_print_options *flags)
+go_language::print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags) const
{
/* Borrowed from c-typeprint.c. */
if (show > 0)
diff --git a/gdb/go-valprint.c b/gdb/go-valprint.c
index df0c029785d..fdbc5c4e95a 100644
--- a/gdb/go-valprint.c
+++ b/gdb/go-valprint.c
@@ -87,8 +87,9 @@ print_go_string (struct type *type,
/* See go-lang.h. */
void
-go_value_print_inner (struct value *val, struct ui_file *stream,
- int recurse, const struct value_print_options *options)
+go_language::value_print_inner (struct value *val, struct ui_file *stream,
+ int recurse,
+ const struct value_print_options *options) const
{
struct type *type = check_typedef (value_type (val));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index dccc3d1e237..d068e798edf 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1842,7 +1842,8 @@ demangle_for_lookup (const char *name, enum language lang,
}
else if (lang == language_go)
{
- char *demangled_name = go_demangle (name, 0);
+ char *demangled_name
+ = language_def (language_go)->demangle_symbol (name, 0);
if (demangled_name != NULL)
return storage.set_malloc_ptr (demangled_name);
}
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 6/9] gdb: move pascal_language into p-lang.h
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
` (4 preceding siblings ...)
2020-11-20 11:55 ` [PATCH 5/9] gdb: move go_language class declaration into header file Andrew Burgess
@ 2020-11-20 11:55 ` Andrew Burgess
2020-11-20 11:55 ` [PATCH 7/9] gdb/objc: fix bug in objc_language::opcode_print_table Andrew Burgess
` (3 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:55 UTC (permalink / raw)
To: gdb-patches
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.
---
gdb/ChangeLog | 66 ++++++++
gdb/p-exp.y | 11 +-
gdb/p-lang.c | 384 ++++++++++++++++------------------------------
gdb/p-lang.h | 245 +++++++++++++++++++++++++----
gdb/p-typeprint.c | 214 +++++++++-----------------
gdb/p-valprint.c | 22 ++-
6 files changed, 506 insertions(+), 436 deletions(-)
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
index 9caf15f69f5..19ba6e9a5f5 100644
--- a/gdb/p-exp.y
+++ b/gdb/p-exp.y
@@ -303,10 +303,9 @@ exp : field_exp COMPLETE
exp : exp '['
/* We need to save the current_type value. */
{ const char *arrayname;
- int arrayfieldindex;
- arrayfieldindex = is_pascal_string_type (
- current_type, NULL, NULL,
- NULL, NULL, &arrayname);
+ int arrayfieldindex
+ = pascal_is_string_type (current_type, NULL, NULL,
+ NULL, NULL, &arrayname);
if (arrayfieldindex)
{
struct stoken stringsval;
@@ -1729,8 +1728,10 @@ yylex (void)
}
}
+/* See language.h. */
+
int
-pascal_parse (struct parser_state *par_state)
+pascal_language::parser (struct parser_state *par_state) const
{
/* Setting up the parser state. */
scoped_restore pstate_restore = make_scoped_restore (&pstate);
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index 1610c0accae..3e58cccc006 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -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 *);
-
-/* 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. */
+/* See p-lang.h. */
-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[] =
};
\f
-/* 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. */ }
-
- /* 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
- {
- static const std::vector<const char *> extensions
- = { ".pas", ".p", ".pp" };
- return extensions;
- }
-
- /* 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);
-
- /* Helper function to allow shorter lines below. */
- auto add = [&] (struct type * t)
- {
- lai->add_primitive_type (t);
- };
-
- 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);
-
- lai->set_string_char_type (builtin->builtin_char);
- lai->set_bool_type (builtin->builtin_bool, "boolean");
- }
-
- /* See language.h. */
-
- 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);
- }
-
- /* See language.h. */
-
- 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);
- }
-
- /* See language.h. */
-
- 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. */
+ const struct builtin_type *builtin = builtin_type (gdbarch);
- void printchar (int ch, struct type *chtype,
- struct ui_file *stream) const override
+ /* Helper function to allow shorter lines below. */
+ auto add = [&] (struct type * t)
{
- pascal_printchar (ch, chtype, stream);
- }
+ lai->add_primitive_type (t);
+ };
+
+ 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);
+
+ lai->set_string_char_type (builtin->builtin_char);
+ lai->set_bool_type (builtin->builtin_bool, "boolean");
+}
- /* See language.h. */
+/* 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);
- }
+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)
+ {
+ fputs_filtered ("''", stream);
+ return;
+ }
- /* See language.h. */
+ 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;
- bool is_string_type_p (struct type *type) const override
- {
- return is_pascal_string_type (type, nullptr, nullptr, nullptr,
- nullptr, nullptr) > 0;
- }
+ QUIT;
- /* See language.h. */
+ if (need_comma)
+ {
+ fputs_filtered (", ", stream);
+ need_comma = 0;
+ }
- const char *name_of_this () const override
- { return "this"; }
+ 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;
+ }
- bool range_checking_on_by_default () const override
- { return true; }
+ 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);
- 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. */
diff --git a/gdb/p-lang.h b/gdb/p-lang.h
index 3eaad015a6e..3f08a26d2b3 100644
--- a/gdb/p-lang.h
+++ b/gdb/p-lang.h
@@ -25,51 +25,240 @@
struct value;
struct parser_state;
+/* 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. */
+
+extern int pascal_is_string_type (struct type *type,int *length_pos,
+ int *length_size, int *string_pos,
+ struct type **char_type,
+ const char **arrayname);
+
/* Defined in p-lang.c */
+
extern const char *pascal_main_name (void);
-extern int pascal_parse (struct parser_state *); /* Defined in p-exp.y */
+/* These are in p-lang.c: */
-/* Defined in p-typeprint.c */
-extern void pascal_print_type (struct type *, const char *, struct ui_file *,
- int, int, const struct type_print_options *);
+extern int is_pascal_string_type (struct type *, int *, int *, int *,
+ struct type **, const char **);
-extern void pascal_print_typedef (struct type *, struct symbol *,
- struct ui_file *);
+extern int pascal_object_is_vtbl_ptr_type (struct type *);
-/* Implement la_value_print_inner for Pascal. */
+extern int pascal_object_is_vtbl_member (struct type *);
-extern void pascal_value_print_inner (struct value *, struct ui_file *, int,
- const struct value_print_options *);
+/* Class representing the Pascal language. */
-extern void pascal_value_print (struct value *, struct ui_file *,
- const struct value_print_options *);
+class pascal_language : public language_defn
+{
+public:
+ pascal_language ()
+ : language_defn (language_pascal)
+ { /* Nothing. */ }
-extern void pascal_type_print_method_args (const char *, const char *,
- struct ui_file *);
+ /* See language.h. */
-/* These are in p-lang.c: */
+ const char *name () const override
+ { return "pascal"; }
-extern int
- is_pascal_string_type (struct type *, int *, int *, int *,
- struct type **, const char **);
+ /* See language.h. */
-extern void pascal_printchar (int, struct type *, struct ui_file *);
+ const char *natural_name () const override
+ { return "Pascal"; }
-extern struct type **const pascal_builtin_types[];
+ /* See language.h. */
-/* These are in p-typeprint.c: */
+ const std::vector<const char *> &filename_extensions () const override
+ {
+ static const std::vector<const char *> extensions
+ = { ".pas", ".p", ".pp" };
+ return extensions;
+ }
-extern void
- pascal_type_print_base (struct type *, struct ui_file *, int, int,
- const struct type_print_options *);
+ /* See language.h. */
-extern void
- pascal_type_print_varspec_prefix (struct type *, struct ui_file *, int, int,
- const struct type_print_options *);
+ void language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai) const override;
-extern int pascal_object_is_vtbl_ptr_type (struct type *);
+ /* See language.h. */
-extern int pascal_object_is_vtbl_member (struct type *);
+ 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;
+
+ /* See language.h. */
+
+ void value_print (struct value *val, struct ui_file *stream,
+ const struct value_print_options *options) const override;
+
+ /* See language.h. */
+
+ void value_print_inner
+ (struct value *val, struct ui_file *stream, int recurse,
+ const struct value_print_options *options) const override;
+
+ /* See language.h. */
+
+ int parser (struct parser_state *ps) const override;
+
+ /* See language.h. */
+
+ void emitchar (int ch, struct type *chtype,
+ struct ui_file *stream, int quoter) const override
+ {
+ int in_quotes = 0;
+
+ print_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;
+
+ /* 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;
+
+ /* See language.h. */
+
+ void print_typedef (struct type *type, struct symbol *new_symbol,
+ struct ui_file *stream) const override;
+
+ /* See language.h. */
+
+ bool is_string_type_p (struct type *type) const override
+ {
+ return pascal_is_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 op_print_tab; }
+
+private:
+
+ /* Table of opcode data for use by OPCODE_PRINT_TABLE member function. */
+
+ static const struct op_print op_print_tab[];
+
+ /* 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. */
+
+ void print_one_char (int c, struct ui_file *stream, int *in_quotes) const;
+
+ /* Print the name of the type (or the ultimate pointer target,
+ 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;}".
+
+ LEVEL is the number of spaces to indent by.
+ We increase it for some recursive calls. */
+
+ void type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level,
+ const struct type_print_options *flags) const;
+
+
+ /* Print any array sizes, function arguments or close parentheses
+ needed after the variable name (to describe its type).
+ Args work like pascal_type_print_varspec_prefix. */
+
+ void type_print_varspec_suffix (struct type *type, struct ui_file *stream,
+ int show, int passed_a_ptr,
+ int demangled_args,
+ const struct type_print_options *flags) const;
+
+ /* Helper for pascal_language::type_print_varspec_suffix to print the
+ suffix of a function or method. */
+
+ void type_print_func_varspec_suffix
+ (struct type *type, struct ui_file *stream, int show,
+ int passed_a_ptr, int demangled_args,
+ const struct type_print_options *flags) const;
+
+ /* Print any asterisks or open-parentheses needed before the
+ variable name (to describe its type).
+
+ On outermost call, pass 0 for PASSED_A_PTR.
+ On outermost call, SHOW > 0 means should ignore
+ any typename for TYPE and show its details.
+ SHOW is always zero on recursive calls. */
+
+ void type_print_varspec_prefix
+ (struct type *type, struct ui_file *stream, int show,
+ int passed_a_ptr, const struct type_print_options *flags) const;
+
+ /* Print the function args from TYPE (a TYPE_CODE_FUNC) to STREAM taking
+ FLAGS into account where appropriate. */
+
+ void print_func_args (struct type *type, struct ui_file *stream,
+ const struct type_print_options *flags) const;
+
+ /* Print the Pascal method arguments for PHYSNAME and METHODNAME to the
+ file STREAM. */
+
+ void type_print_method_args (const char *physname, const char *methodname,
+ struct ui_file *stream) const;
+
+ /* 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:
+
+ class A { int a; };
+ class B : public A {int b; };
+ class C : public B {int c; };
+
+ Print the type of class C as:
+
+ class C : public B {
+ 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:
+
+ 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. */
+
+ void type_print_derivation_info (struct ui_file *stream,
+ struct type *type) const;
+};
#endif /* P_LANG_H */
diff --git a/gdb/p-typeprint.c b/gdb/p-typeprint.c
index c2c182a9ae9..80b3d4a7667 100644
--- a/gdb/p-typeprint.c
+++ b/gdb/p-typeprint.c
@@ -34,21 +34,12 @@
#include <ctype.h>
#include "cli/cli-style.h"
-static void pascal_type_print_varspec_suffix (struct type *, struct ui_file *,
- int, int, int,
- const struct type_print_options *);
-
-static void pascal_type_print_derivation_info (struct ui_file *,
- struct type *);
-
-\f
-
-/* LEVEL is the depth to indent lines by. */
+/* See language.h. */
void
-pascal_print_type (struct type *type, const char *varstring,
- struct ui_file *stream, int show, int level,
- const struct type_print_options *flags)
+pascal_language::print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags) const
{
enum type_code code;
int demangled_args;
@@ -61,7 +52,7 @@ pascal_print_type (struct type *type, const char *varstring,
if ((code == TYPE_CODE_FUNC
|| code == TYPE_CODE_METHOD))
{
- pascal_type_print_varspec_prefix (type, stream, show, 0, flags);
+ type_print_varspec_prefix (type, stream, show, 0, flags);
}
/* first the name */
fputs_filtered (varstring, stream);
@@ -76,26 +67,24 @@ pascal_print_type (struct type *type, const char *varstring,
if (!(code == TYPE_CODE_FUNC
|| code == TYPE_CODE_METHOD))
{
- pascal_type_print_varspec_prefix (type, stream, show, 0, flags);
+ type_print_varspec_prefix (type, stream, show, 0, flags);
}
- pascal_type_print_base (type, stream, show, level, flags);
+ type_print_base (type, stream, show, level, flags);
/* For demangled function names, we have the arglist as part of the name,
so don't print an additional pair of ()'s. */
demangled_args = varstring ? strchr (varstring, '(') != NULL : 0;
- pascal_type_print_varspec_suffix (type, stream, show, 0, demangled_args,
+ type_print_varspec_suffix (type, stream, show, 0, demangled_args,
flags);
}
-/* Print a typedef using Pascal syntax. TYPE is the underlying type.
- NEW_SYMBOL is the symbol naming the type. STREAM is the stream on
- which to print. */
+/* See language.h. */
void
-pascal_print_typedef (struct type *type, struct symbol *new_symbol,
- struct ui_file *stream)
+pascal_language::print_typedef (struct type *type, struct symbol *new_symbol,
+ struct ui_file *stream) const
{
type = check_typedef (type);
fprintf_filtered (stream, "type ");
@@ -104,32 +93,11 @@ pascal_print_typedef (struct type *type, struct symbol *new_symbol,
fprintf_filtered (stream, ";");
}
-/* 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:
-
- class A { int a; };
- class B : public A {int b; };
- class C : public B {int c; };
-
- Print the type of class C as:
-
- class C : public B {
- 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:
-
- 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. */
+/* See p-lang.h. */
-static void
-pascal_type_print_derivation_info (struct ui_file *stream, struct type *type)
+void
+pascal_language::type_print_derivation_info (struct ui_file *stream,
+ struct type *type) const
{
const char *name;
int i;
@@ -149,11 +117,12 @@ pascal_type_print_derivation_info (struct ui_file *stream, struct type *type)
}
}
-/* Print the Pascal method arguments ARGS to the file STREAM. */
+/* See p-lang.h. */
void
-pascal_type_print_method_args (const char *physname, const char *methodname,
- struct ui_file *stream)
+pascal_language::type_print_method_args (const char *physname,
+ const char *methodname,
+ struct ui_file *stream) const
{
int is_constructor = (startswith (physname, "__ct__"));
int is_destructor = (startswith (physname, "__dt__"));
@@ -195,18 +164,13 @@ pascal_type_print_method_args (const char *physname, const char *methodname,
}
}
-/* Print any asterisks or open-parentheses needed before the
- variable name (to describe its type).
-
- On outermost call, pass 0 for PASSED_A_PTR.
- On outermost call, SHOW > 0 means should ignore
- any typename for TYPE and show its details.
- SHOW is always zero on recursive calls. */
+/* See p-lang.h. */
void
-pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
- int show, int passed_a_ptr,
- const struct type_print_options *flags)
+pascal_language::type_print_varspec_prefix (struct type *type,
+ struct ui_file *stream,
+ int show, int passed_a_ptr,
+ const struct type_print_options *flags) const
{
if (type == 0)
return;
@@ -220,7 +184,7 @@ pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
{
case TYPE_CODE_PTR:
fprintf_filtered (stream, "^");
- pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1,
+ type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1,
flags);
break; /* Pointer should be handled normally
in pascal. */
@@ -241,15 +205,15 @@ pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
if (passed_a_ptr)
{
fprintf_filtered (stream, " ");
- pascal_type_print_base (TYPE_SELF_TYPE (type),
+ type_print_base (TYPE_SELF_TYPE (type),
stream, 0, passed_a_ptr, flags);
fprintf_filtered (stream, "::");
}
break;
case TYPE_CODE_REF:
- pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1,
- flags);
+ type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1,
+ flags);
fprintf_filtered (stream, "&");
break;
@@ -301,14 +265,16 @@ pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream,
gcc -Wall will reveal any types that haven't been handled. */
break;
default:
- error (_("type not handled in pascal_type_print_varspec_prefix()"));
+ gdb_assert_not_reached ("unexpected type");
break;
}
}
-static void
-pascal_print_func_args (struct type *type, struct ui_file *stream,
- const struct type_print_options *flags)
+/* See p-lang.h. */
+
+void
+pascal_language::print_func_args (struct type *type, struct ui_file *stream,
+ const struct type_print_options *flags) const
{
int i, len = type->num_fields ();
@@ -324,12 +290,12 @@ pascal_print_func_args (struct type *type, struct ui_file *stream,
wrap_here (" ");
}
/* Can we find if it is a var parameter ??
- if ( TYPE_FIELD(type, i) == )
- {
- fprintf_filtered (stream, "var ");
- } */
- pascal_print_type (type->field (i).type (), "" /* TYPE_FIELD_NAME
- seems invalid! */
+ if ( TYPE_FIELD(type, i) == )
+ {
+ fprintf_filtered (stream, "var ");
+ } */
+ print_type (type->field (i).type (), "" /* TYPE_FIELD_NAME
+ seems invalid! */
,stream, -1, 0, flags);
}
if (len)
@@ -338,42 +304,41 @@ pascal_print_func_args (struct type *type, struct ui_file *stream,
}
}
-/* Helper for pascal_type_print_varspec_suffix to print the suffix of
- a function or method. */
+/* See p-lang.h. */
-static void
-pascal_type_print_func_varspec_suffix (struct type *type, struct ui_file *stream,
- int show, int passed_a_ptr,
- int demangled_args,
- const struct type_print_options *flags)
+void
+pascal_language::type_print_func_varspec_suffix (struct type *type,
+ struct ui_file *stream,
+ int show, int passed_a_ptr,
+ int demangled_args,
+ const struct type_print_options *flags) const
{
if (TYPE_TARGET_TYPE (type) == NULL
|| TYPE_TARGET_TYPE (type)->code () != TYPE_CODE_VOID)
{
fprintf_filtered (stream, " : ");
- pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
+ type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
stream, 0, 0, flags);
if (TYPE_TARGET_TYPE (type) == NULL)
type_print_unknown_return_type (stream);
else
- pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0,
+ type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0,
flags);
- pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
- passed_a_ptr, 0, flags);
+ type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
+ passed_a_ptr, 0, flags);
}
}
-/* Print any array sizes, function arguments or close parentheses
- needed after the variable name (to describe its type).
- Args work like pascal_type_print_varspec_prefix. */
+/* See p-lang.h. */
-static void
-pascal_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
- int show, int passed_a_ptr,
- int demangled_args,
- const struct type_print_options *flags)
+void
+pascal_language::type_print_varspec_suffix (struct type *type,
+ struct ui_file *stream,
+ int show, int passed_a_ptr,
+ int demangled_args,
+ const struct type_print_options *flags) const
{
if (type == 0)
return;
@@ -393,25 +358,23 @@ pascal_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
case TYPE_CODE_METHOD:
if (passed_a_ptr)
fprintf_filtered (stream, ")");
- pascal_type_print_method_args ("",
- "",
- stream);
- pascal_type_print_func_varspec_suffix (type, stream, show,
+ type_print_method_args ("", "", stream);
+ type_print_func_varspec_suffix (type, stream, show,
passed_a_ptr, 0, flags);
break;
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
- pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type),
- stream, 0, 1, 0, flags);
+ type_print_varspec_suffix (TYPE_TARGET_TYPE (type),
+ stream, 0, 1, 0, flags);
break;
case TYPE_CODE_FUNC:
if (passed_a_ptr)
fprintf_filtered (stream, ")");
if (!demangled_args)
- pascal_print_func_args (type, stream, flags);
- pascal_type_print_func_varspec_suffix (type, stream, show,
+ print_func_args (type, stream, flags);
+ type_print_func_varspec_suffix (type, stream, show,
passed_a_ptr, 0, flags);
break;
@@ -435,30 +398,16 @@ pascal_type_print_varspec_suffix (struct type *type, struct ui_file *stream,
gcc -Wall will report types that may not have been considered. */
break;
default:
- error (_("type not handled in pascal_type_print_varspec_suffix()"));
+ gdb_assert_not_reached ("unexpected type");
break;
}
}
-/* Print the name of the type (or the ultimate pointer target,
- 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;}".
-
- LEVEL is the number of spaces to indent by.
- We increase it for some recursive calls. */
+/* See p-lang.h. */
void
-pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
- int level, const struct type_print_options *flags)
+pascal_language::type_print_base (struct type *type, struct ui_file *stream, int show,
+ int level, const struct type_print_options *flags) const
{
int i;
int len;
@@ -502,27 +451,16 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
case TYPE_CODE_TYPEDEF:
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
- /* case TYPE_CODE_FUNC:
- case TYPE_CODE_METHOD: */
- pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level,
- flags);
+ type_print_base (TYPE_TARGET_TYPE (type), stream, show, level,
+ flags);
break;
case TYPE_CODE_ARRAY:
- /* pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
- stream, 0, 0);
- pascal_type_print_base (TYPE_TARGET_TYPE (type),
- stream, show, level);
- pascal_type_print_varspec_suffix (TYPE_TARGET_TYPE (type),
- stream, 0, 0, 0); */
- pascal_print_type (TYPE_TARGET_TYPE (type), NULL, stream, 0, 0, flags);
+ print_type (TYPE_TARGET_TYPE (type), NULL, stream, 0, 0, flags);
break;
case TYPE_CODE_FUNC:
case TYPE_CODE_METHOD:
- /*
- pascal_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
- only after args !! */
break;
case TYPE_CODE_STRUCT:
if (type->name () != NULL)
@@ -558,7 +496,7 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
}
else if (show > 0 || type->name () == NULL)
{
- pascal_type_print_derivation_info (stream, type);
+ type_print_derivation_info (stream, type);
fprintf_filtered (stream, "\n");
if ((type->num_fields () == 0) && (TYPE_NFN_FIELDS (type) == 0))
@@ -622,7 +560,7 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
print_spaces_filtered (level + 4, stream);
if (field_is_static (&type->field (i)))
fprintf_filtered (stream, "static ");
- pascal_print_type (type->field (i).type (),
+ print_type (type->field (i).type (),
TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4, flags);
if (!field_is_static (&type->field (i))
@@ -719,9 +657,7 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
}
/* This does not work, no idea why !! */
- pascal_type_print_method_args (physname,
- method_name,
- stream);
+ type_print_method_args (physname, method_name, stream);
if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) != 0
&& TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE(f, j))->code () != TYPE_CODE_VOID)
@@ -807,7 +743,7 @@ pascal_type_print_base (struct type *type, struct ui_file *stream, int show,
case TYPE_CODE_SET:
fputs_filtered ("set of ", stream);
- pascal_print_type (type->index_type (), "", stream,
+ print_type (type->index_type (), "", stream,
show - 1, level, flags);
break;
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 428b2efc656..d2eb9c11750 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -64,9 +64,9 @@ static const struct generic_val_print_decorations p_decorations =
/* See p-lang.h. */
void
-pascal_value_print_inner (struct value *val, struct ui_file *stream,
- int recurse,
- const struct value_print_options *options)
+pascal_language::value_print_inner (struct value *val,
+ struct ui_file *stream, int recurse,
+ const struct value_print_options *options) const
{
struct type *type = check_typedef (value_type (val));
@@ -200,8 +200,8 @@ pascal_value_print_inner (struct value *val, struct ui_file *stream,
as GDB does not recognize stabs pascal strings
Pascal strings are mapped to records
with lowercase names PM. */
- if (is_pascal_string_type (elttype, &length_pos, &length_size,
- &string_pos, &char_type, NULL)
+ if (pascal_is_string_type (elttype, &length_pos, &length_size,
+ &string_pos, &char_type, NULL) > 0
&& addr != 0)
{
ULONGEST string_length;
@@ -313,8 +313,8 @@ pascal_value_print_inner (struct value *val, struct ui_file *stream,
}
else
{
- if (is_pascal_string_type (type, &length_pos, &length_size,
- &string_pos, &char_type, NULL))
+ if (pascal_is_string_type (type, &length_pos, &length_size,
+ &string_pos, &char_type, NULL) > 0)
{
len = extract_unsigned_integer (valaddr + length_pos,
length_size, byte_order);
@@ -401,8 +401,8 @@ pascal_value_print_inner (struct value *val, struct ui_file *stream,
\f
void
-pascal_value_print (struct value *val, struct ui_file *stream,
- const struct value_print_options *options)
+pascal_language::value_print (struct value *val, struct ui_file *stream,
+ const struct value_print_options *options) const
{
struct type *type = value_type (val);
struct value_print_options opts = *options;
@@ -498,9 +498,7 @@ pascal_object_is_vtbl_member (struct type *type)
return 0;
}
-/* Mutually recursive subroutines of pascal_object_print_value and
- pascal_value_print to print out a structure's fields:
- pascal_object_print_value_fields and pascal_object_print_value.
+/* Helper function for print pascal objects.
VAL, STREAM, RECURSE, and OPTIONS have the same meanings as in
pascal_object_print_value and c_value_print.
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 7/9] gdb/objc: fix bug in objc_language::opcode_print_table
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
` (5 preceding siblings ...)
2020-11-20 11:55 ` [PATCH 6/9] gdb: move pascal_language into p-lang.h Andrew Burgess
@ 2020-11-20 11:55 ` Andrew Burgess
2020-11-20 11:55 ` [PATCH 8/9] gdb: move rust_language into rust-lang.h Andrew Burgess
` (2 subsequent siblings)
9 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:55 UTC (permalink / raw)
To: gdb-patches
In this commit:
commit b7c6e27dbbbbe678b2e2f0bf617605e055e1b378
Date: Tue Aug 4 17:07:59 2020 +0100
gdb: Convert language_data::la_op_print_tab to a method
A bug was introduced, the objc language now returns the wrong op_print
table. Fixed in this commit.
gdb/ChangeLog:
* objc-lang.c (objc_language::opcode_print_table): Return
objc_op_print_tab.
---
gdb/ChangeLog | 5 +++++
gdb/objc-lang.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 4cd853249aa..4e58c62e4fd 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -424,7 +424,7 @@ class objc_language : public language_defn
/* See language.h. */
const struct op_print *opcode_print_table () const override
- { return c_op_print_tab; }
+ { return objc_op_print_tab; }
};
/* Single instance of the class representing the Objective-C language. */
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 8/9] gdb: move rust_language into rust-lang.h
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
` (6 preceding siblings ...)
2020-11-20 11:55 ` [PATCH 7/9] gdb/objc: fix bug in objc_language::opcode_print_table Andrew Burgess
@ 2020-11-20 11:55 ` Andrew Burgess
2020-11-20 11:55 ` [PATCH 9/9] gdb: remove some uses of LA_PRINT_STRING Andrew Burgess
2020-12-10 16:26 ` [PATCH 0/9] Further language class related changes Andrew Burgess
9 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:55 UTC (permalink / raw)
To: gdb-patches
Move the rust_language class declaration into the rust-lang.h header
file. This allows for the function implementations called directly in
rust-lang.c and rust-exp.y without the need for trampoline functions.
There should be no user visible changes after this commit.
gdb/ChangeLog:
* rust-exp.y (rust_parse): Rename to...
(rust_language::parser): ...this.
* rust-lang.c (-rust_printstr): Rename to...
(rust_language::printstr): ...this.
(rust_value_print_inner): Delete declaration.
(val_print_struct): Rename to...
(rust_language::val_print_struct): ...this. Update calls to
member functions.
(rust_print_enum): Rename to...
(rust_language::print_enum): ...this. Update calls to member
functions.
(rust_value_print_inner): Rename to...
(rust_language::value_print_inner): ...this. Update calls to
member functions.
(exp_descriptor_rust): Rename to...
(rust_language::exp_descriptor_tab): ...this.
(class rust_language): Move to rust-lang.h.
(rust_language::language_arch_info): Implementation moved to here
from class declaration.
(rust_language::print_type): Likewise.
(rust_language::emitchar): Likewise.
(rust_language::is_string_type_p): Likewise.
* rust-lang.h: Add 'demangle.h', 'language.h', 'value.h', and
'c-lang.h' includes.
(rust_parse): Delete declaration.
(class rust_language): Class declaration moved here from
rust-lang.c.
---
gdb/ChangeLog | 30 ++++
gdb/rust-exp.y | 2 +-
gdb/rust-lang.c | 397 +++++++++++++++---------------------------------
gdb/rust-lang.h | 198 +++++++++++++++++++++++-
4 files changed, 346 insertions(+), 281 deletions(-)
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
index 1207d1d6f42..02885006df3 100644
--- a/gdb/rust-exp.y
+++ b/gdb/rust-exp.y
@@ -2540,7 +2540,7 @@ rust_parser::convert_ast_to_expression (const struct rust_op *operation,
/* The parser as exposed to gdb. */
int
-rust_parse (struct parser_state *state)
+rust_language::parser (struct parser_state *state) const
{
int result;
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index 4cfe44a1ad7..10858431490 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -261,13 +261,13 @@ rust_get_trait_object_pointer (struct value *value)
\f
-/* language_defn::printstr implementation for Rust. */
+/* See language.h. */
-static void
-rust_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)
+void
+rust_language::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) const
{
/* Rust always uses UTF-8, but let the caller override this if need
be. */
@@ -294,10 +294,6 @@ rust_printstr (struct ui_file *stream, struct type *type,
\f
-static void rust_value_print_inner (struct value *val, struct ui_file *stream,
- int recurse,
- const struct value_print_options *options);
-
/* Helper function to print a string slice. */
static void
@@ -313,11 +309,12 @@ rust_val_print_str (struct ui_file *stream, struct value *val,
options);
}
-/* rust_val_print helper for structs and untagged unions. */
+/* See rust-lang.h. */
-static void
-val_print_struct (struct value *val, struct ui_file *stream, int recurse,
- const struct value_print_options *options)
+void
+rust_language::val_print_struct
+ (struct value *val, struct ui_file *stream, int recurse,
+ const struct value_print_options *options) const
{
int i;
int first_field;
@@ -387,8 +384,7 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse,
fputs_filtered (": ", stream);
}
- rust_value_print_inner (value_field (val, i), stream, recurse + 1,
- &opts);
+ value_print_inner (value_field (val, i), stream, recurse + 1, &opts);
}
if (options->prettyformat)
@@ -403,11 +399,12 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse,
fputs_filtered ("}", stream);
}
-/* rust_val_print helper for discriminated unions (Rust enums). */
+/* See rust-lang.h. */
-static void
-rust_print_enum (struct value *val, struct ui_file *stream, int recurse,
- const struct value_print_options *options)
+void
+rust_language::print_enum (struct value *val, struct ui_file *stream,
+ int recurse,
+ const struct value_print_options *options) const
{
struct value_print_options opts = *options;
struct type *type = check_typedef (value_type (val));
@@ -465,8 +462,7 @@ rust_print_enum (struct value *val, struct ui_file *stream, int recurse,
styled_string (variable_name_style.style (),
TYPE_FIELD_NAME (variant_type, j)));
- rust_value_print_inner (value_field (val, j), stream, recurse + 1,
- &opts);
+ value_print_inner (value_field (val, j), stream, recurse + 1, &opts);
}
if (is_tuple)
@@ -489,11 +485,12 @@ static const struct generic_val_print_decorations rust_decorations =
"]"
};
-/* la_value_print_inner implementation for Rust. */
-static void
-rust_value_print_inner (struct value *val, struct ui_file *stream,
- int recurse,
- const struct value_print_options *options)
+/* See language.h. */
+
+void
+rust_language::value_print_inner
+ (struct value *val, struct ui_file *stream, int recurse,
+ const struct value_print_options *options) const
{
struct value_print_options opts = *options;
opts.deref_ref = 1;
@@ -556,9 +553,9 @@ rust_value_print_inner (struct value *val, struct ui_file *stream,
byte string, hence the choice of "ASCII" as the
encoding. */
fputs_filtered ("b", stream);
- rust_printstr (stream, TYPE_TARGET_TYPE (type),
- value_contents_for_printing (val),
- high_bound - low_bound + 1, "ASCII", 0, &opts);
+ printstr (stream, TYPE_TARGET_TYPE (type),
+ value_contents_for_printing (val),
+ high_bound - low_bound + 1, "ASCII", 0, &opts);
}
break;
@@ -585,7 +582,7 @@ rust_value_print_inner (struct value *val, struct ui_file *stream,
case TYPE_CODE_STRUCT:
if (rust_enum_p (type))
- rust_print_enum (val, stream, recurse, &opts);
+ print_enum (val, stream, recurse, &opts);
else
val_print_struct (val, stream, recurse, &opts);
break;
@@ -1863,7 +1860,7 @@ rust_operator_check (struct expression *exp, int pos,
\f
-static const struct exp_descriptor exp_descriptor_rust =
+const struct exp_descriptor rust_language::exp_descriptor_tab =
{
rust_print_subexp,
rust_operator_length,
@@ -1873,262 +1870,108 @@ static const struct exp_descriptor exp_descriptor_rust =
rust_evaluate_subexp
};
-/* Class representing the Rust language. */
+/* See language.h. */
-class rust_language : public language_defn
+void
+rust_language::language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai) const
{
-public:
- rust_language ()
- : language_defn (language_rust)
- { /* Nothing. */ }
-
- /* See language.h. */
-
- const char *name () const override
- { return "rust"; }
-
- /* See language.h. */
-
- const char *natural_name () const override
- { return "Rust"; }
-
- /* See language.h. */
-
- const std::vector<const char *> &filename_extensions () const override
- {
- static const std::vector<const char *> extensions = { ".rs" };
- return extensions;
- }
-
- /* 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);
-
- /* Helper function to allow shorter lines below. */
- auto add = [&] (struct type * t) -> struct type *
- {
- lai->add_primitive_type (t);
- return t;
- };
-
- struct type *bool_type
- = add (arch_boolean_type (gdbarch, 8, 1, "bool"));
- add (arch_character_type (gdbarch, 32, 1, "char"));
- add (arch_integer_type (gdbarch, 8, 0, "i8"));
- struct type *u8_type
- = add (arch_integer_type (gdbarch, 8, 1, "u8"));
- add (arch_integer_type (gdbarch, 16, 0, "i16"));
- add (arch_integer_type (gdbarch, 16, 1, "u16"));
- add (arch_integer_type (gdbarch, 32, 0, "i32"));
- add (arch_integer_type (gdbarch, 32, 1, "u32"));
- add (arch_integer_type (gdbarch, 64, 0, "i64"));
- add (arch_integer_type (gdbarch, 64, 1, "u64"));
-
- unsigned int length = 8 * TYPE_LENGTH (builtin->builtin_data_ptr);
- add (arch_integer_type (gdbarch, length, 0, "isize"));
- struct type *usize_type
- = add (arch_integer_type (gdbarch, length, 1, "usize"));
-
- add (arch_float_type (gdbarch, 32, "f32", floatformats_ieee_single));
- add (arch_float_type (gdbarch, 64, "f64", floatformats_ieee_double));
- add (arch_integer_type (gdbarch, 0, 1, "()"));
-
- struct type *tem = make_cv_type (1, 0, u8_type, NULL);
- add (rust_slice_type ("&str", tem, usize_type));
-
- lai->set_bool_type (bool_type);
- lai->set_string_char_type (u8_type);
- }
-
- /* See language.h. */
- bool sniff_from_mangled_name (const char *mangled,
- char **demangled) const override
- {
- *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
- return *demangled != NULL;
- }
-
- /* See language.h. */
-
- char *demangle_symbol (const char *mangled, int options) const override
- {
- return gdb_demangle (mangled, options);
- }
-
- /* See language.h. */
-
- 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
- {
- print_offset_data podata;
- rust_internal_print_type (type, varstring, stream, show, level,
- flags, false, &podata);
- }
-
- /* See language.h. */
-
- gdb::unique_xmalloc_ptr<char> watch_location_expression
- (struct type *type, CORE_ADDR addr) const override
- {
- type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
- std::string name = type_to_string (type);
- return gdb::unique_xmalloc_ptr<char>
- (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr),
- name.c_str ()));
- }
-
- /* See language.h. */
-
- void value_print_inner
- (struct value *val, struct ui_file *stream, int recurse,
- const struct value_print_options *options) const override
- {
- return rust_value_print_inner (val, stream, recurse, options);
- }
-
- /* See language.h. */
-
- struct block_symbol lookup_symbol_nonlocal
- (const char *name, const struct block *block,
- const domain_enum domain) const override
- {
- struct block_symbol result = {};
-
- if (symbol_lookup_debug)
- {
- fprintf_unfiltered (gdb_stdlog,
- "rust_lookup_symbol_non_local"
- " (%s, %s (scope %s), %s)\n",
- name, host_address_to_string (block),
- block_scope (block), domain_name (domain));
- }
-
- /* Look up bare names in the block's scope. */
- std::string scopedname;
- if (name[cp_find_first_component (name)] == '\0')
- {
- const char *scope = block_scope (block);
-
- if (scope[0] != '\0')
- {
- scopedname = std::string (scope) + "::" + name;
- name = scopedname.c_str ();
- }
- else
- name = NULL;
- }
-
- if (name != NULL)
- {
- result = lookup_symbol_in_static_block (name, block, domain);
- if (result.symbol == NULL)
- result = lookup_global_symbol (name, block, domain);
- }
- return result;
- }
-
- /* See language.h. */
+ const struct builtin_type *builtin = builtin_type (gdbarch);
- int parser (struct parser_state *ps) const override
+ /* Helper function to allow shorter lines below. */
+ auto add = [&] (struct type * t) -> struct type *
{
- return rust_parse (ps);
- }
-
- /* See language.h. */
-
- void emitchar (int ch, struct type *chtype,
- struct ui_file *stream, int quoter) const override
- {
- if (!rust_chartype_p (chtype))
- generic_emit_char (ch, chtype, stream, quoter,
- target_charset (get_type_arch (chtype)));
- else if (ch == '\\' || ch == quoter)
- fprintf_filtered (stream, "\\%c", ch);
- else if (ch == '\n')
- fputs_filtered ("\\n", stream);
- else if (ch == '\r')
- fputs_filtered ("\\r", stream);
- else if (ch == '\t')
- fputs_filtered ("\\t", stream);
- else if (ch == '\0')
- fputs_filtered ("\\0", stream);
- else if (ch >= 32 && ch <= 127 && isprint (ch))
- fputc_filtered (ch, stream);
- else if (ch <= 255)
- fprintf_filtered (stream, "\\x%02x", ch);
- else
- fprintf_filtered (stream, "\\u{%06x}", ch);
- }
-
- /* See language.h. */
-
- void printchar (int ch, struct type *chtype,
- struct ui_file *stream) const override
- {
- fputs_filtered ("'", stream);
- emitchar (ch, chtype, stream, '\'');
- fputs_filtered ("'", 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
- {
- rust_printstr (stream, elttype, string, length, encoding,
- force_ellipses, options);
- }
-
- /* See language.h. */
-
- void print_typedef (struct type *type, struct symbol *new_symbol,
- struct ui_file *stream) const override
- {
- type = check_typedef (type);
- fprintf_filtered (stream, "type %s = ", new_symbol->print_name ());
- type_print (type, "", stream, 0);
- fprintf_filtered (stream, ";");
- }
-
- /* See language.h. */
-
- bool is_string_type_p (struct type *type) const override
- {
- LONGEST low_bound, high_bound;
+ lai->add_primitive_type (t);
+ return t;
+ };
+
+ struct type *bool_type
+ = add (arch_boolean_type (gdbarch, 8, 1, "bool"));
+ add (arch_character_type (gdbarch, 32, 1, "char"));
+ add (arch_integer_type (gdbarch, 8, 0, "i8"));
+ struct type *u8_type
+ = add (arch_integer_type (gdbarch, 8, 1, "u8"));
+ add (arch_integer_type (gdbarch, 16, 0, "i16"));
+ add (arch_integer_type (gdbarch, 16, 1, "u16"));
+ add (arch_integer_type (gdbarch, 32, 0, "i32"));
+ add (arch_integer_type (gdbarch, 32, 1, "u32"));
+ add (arch_integer_type (gdbarch, 64, 0, "i64"));
+ add (arch_integer_type (gdbarch, 64, 1, "u64"));
+
+ unsigned int length = 8 * TYPE_LENGTH (builtin->builtin_data_ptr);
+ add (arch_integer_type (gdbarch, length, 0, "isize"));
+ struct type *usize_type
+ = add (arch_integer_type (gdbarch, length, 1, "usize"));
+
+ add (arch_float_type (gdbarch, 32, "f32", floatformats_ieee_single));
+ add (arch_float_type (gdbarch, 64, "f64", floatformats_ieee_double));
+ add (arch_integer_type (gdbarch, 0, 1, "()"));
+
+ struct type *tem = make_cv_type (1, 0, u8_type, NULL);
+ add (rust_slice_type ("&str", tem, usize_type));
+
+ lai->set_bool_type (bool_type);
+ lai->set_string_char_type (u8_type);
+}
- type = check_typedef (type);
- return ((type->code () == TYPE_CODE_STRING)
- || (type->code () == TYPE_CODE_PTR
- && (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ARRAY
- && rust_u8_type_p (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)))
- && get_array_bounds (TYPE_TARGET_TYPE (type), &low_bound,
- &high_bound)))
- || (type->code () == TYPE_CODE_STRUCT
- && !rust_enum_p (type)
- && rust_slice_type_p (type)
- && strcmp (type->name (), "&str") == 0));
- }
+/* See language.h. */
- /* See language.h. */
+void
+rust_language::print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags) const
+{
+ print_offset_data podata;
+ rust_internal_print_type (type, varstring, stream, show, level,
+ flags, false, &podata);
+}
- bool range_checking_on_by_default () const override
- { return true; }
+/* See language.h. */
- /* See language.h. */
+void
+rust_language::emitchar (int ch, struct type *chtype,
+ struct ui_file *stream, int quoter) const
+{
+ if (!rust_chartype_p (chtype))
+ generic_emit_char (ch, chtype, stream, quoter,
+ target_charset (get_type_arch (chtype)));
+ else if (ch == '\\' || ch == quoter)
+ fprintf_filtered (stream, "\\%c", ch);
+ else if (ch == '\n')
+ fputs_filtered ("\\n", stream);
+ else if (ch == '\r')
+ fputs_filtered ("\\r", stream);
+ else if (ch == '\t')
+ fputs_filtered ("\\t", stream);
+ else if (ch == '\0')
+ fputs_filtered ("\\0", stream);
+ else if (ch >= 32 && ch <= 127 && isprint (ch))
+ fputc_filtered (ch, stream);
+ else if (ch <= 255)
+ fprintf_filtered (stream, "\\x%02x", ch);
+ else
+ fprintf_filtered (stream, "\\u{%06x}", ch);
+}
- const struct exp_descriptor *expression_ops () const override
- { return &exp_descriptor_rust; }
+/* See language.h. */
- /* See language.h. */
+bool
+rust_language::is_string_type_p (struct type *type) const
+{
+ LONGEST low_bound, high_bound;
- const struct op_print *opcode_print_table () const override
- { return c_op_print_tab; }
-};
+ type = check_typedef (type);
+ return ((type->code () == TYPE_CODE_STRING)
+ || (type->code () == TYPE_CODE_PTR
+ && (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ARRAY
+ && rust_u8_type_p (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)))
+ && get_array_bounds (TYPE_TARGET_TYPE (type), &low_bound,
+ &high_bound)))
+ || (type->code () == TYPE_CODE_STRUCT
+ && !rust_enum_p (type)
+ && rust_slice_type_p (type)
+ && strcmp (type->name (), "&str") == 0));
+}
/* Single instance of the Rust language class. */
diff --git a/gdb/rust-lang.h b/gdb/rust-lang.h
index 3ab860e086a..df94fc14563 100644
--- a/gdb/rust-lang.h
+++ b/gdb/rust-lang.h
@@ -20,12 +20,14 @@
#ifndef RUST_LANG_H
#define RUST_LANG_H
+#include "demangle.h"
+#include "language.h"
+#include "value.h"
+#include "c-lang.h"
+
struct parser_state;
struct type;
-/* The la_parser implementation for Rust. */
-extern int rust_parse (struct parser_state *);
-
/* Return true if TYPE is a tuple type; otherwise false. */
extern bool rust_tuple_type_p (struct type *type);
@@ -48,4 +50,194 @@ extern const char *rust_last_path_segment (const char *path);
extern struct type *rust_slice_type (const char *name, struct type *elt_type,
struct type *usize_type);
+/* Class representing the Rust language. */
+
+class rust_language : public language_defn
+{
+public:
+ rust_language ()
+ : language_defn (language_rust)
+ { /* Nothing. */ }
+
+ /* See language.h. */
+
+ const char *name () const override
+ { return "rust"; }
+
+ /* See language.h. */
+
+ const char *natural_name () const override
+ { return "Rust"; }
+
+ /* See language.h. */
+
+ const std::vector<const char *> &filename_extensions () const override
+ {
+ static const std::vector<const char *> extensions = { ".rs" };
+ return extensions;
+ }
+
+ /* See language.h. */
+
+ void language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai) const override;
+
+ /* See language.h. */
+
+ bool sniff_from_mangled_name (const char *mangled,
+ char **demangled) const override
+ {
+ *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+ return *demangled != NULL;
+ }
+
+ /* See language.h. */
+
+ char *demangle_symbol (const char *mangled, int options) const override
+ {
+ return gdb_demangle (mangled, options);
+ }
+
+ /* See language.h. */
+
+ 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;
+
+ /* See language.h. */
+
+ gdb::unique_xmalloc_ptr<char> watch_location_expression
+ (struct type *type, CORE_ADDR addr) const override
+ {
+ type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
+ std::string name = type_to_string (type);
+ return gdb::unique_xmalloc_ptr<char>
+ (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr),
+ name.c_str ()));
+ }
+
+ /* See language.h. */
+
+ void value_print_inner
+ (struct value *val, struct ui_file *stream, int recurse,
+ const struct value_print_options *options) const override;
+
+ /* See language.h. */
+
+ struct block_symbol lookup_symbol_nonlocal
+ (const char *name, const struct block *block,
+ const domain_enum domain) const override
+ {
+ struct block_symbol result = {};
+
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "rust_lookup_symbol_non_local"
+ " (%s, %s (scope %s), %s)\n",
+ name, host_address_to_string (block),
+ block_scope (block), domain_name (domain));
+ }
+
+ /* Look up bare names in the block's scope. */
+ std::string scopedname;
+ if (name[cp_find_first_component (name)] == '\0')
+ {
+ const char *scope = block_scope (block);
+
+ if (scope[0] != '\0')
+ {
+ scopedname = std::string (scope) + "::" + name;
+ name = scopedname.c_str ();
+ }
+ else
+ name = NULL;
+ }
+
+ if (name != NULL)
+ {
+ result = lookup_symbol_in_static_block (name, block, domain);
+ if (result.symbol == NULL)
+ result = lookup_global_symbol (name, block, domain);
+ }
+ return result;
+ }
+
+ /* See language.h. */
+
+ int parser (struct parser_state *ps) const override;
+
+ /* See language.h. */
+
+ void emitchar (int ch, struct type *chtype,
+ struct ui_file *stream, int quoter) const override;
+
+ /* See language.h. */
+
+ void printchar (int ch, struct type *chtype,
+ struct ui_file *stream) const override
+ {
+ fputs_filtered ("'", stream);
+ emitchar (ch, chtype, stream, '\'');
+ fputs_filtered ("'", 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;
+
+ /* See language.h. */
+
+ void print_typedef (struct type *type, struct symbol *new_symbol,
+ struct ui_file *stream) const override
+ {
+ type = check_typedef (type);
+ fprintf_filtered (stream, "type %s = ", new_symbol->print_name ());
+ type_print (type, "", stream, 0);
+ fprintf_filtered (stream, ";");
+ }
+
+ /* See language.h. */
+
+ bool is_string_type_p (struct type *type) const override;
+
+ /* See language.h. */
+
+ bool range_checking_on_by_default () const override
+ { return true; }
+
+ /* See language.h. */
+
+ const struct exp_descriptor *expression_ops () const override
+ { return &exp_descriptor_tab; }
+
+ /* See language.h. */
+
+ const struct op_print *opcode_print_table () const override
+ { return c_op_print_tab; }
+
+private:
+
+ /* Table of expression handling functions for use by EXPRESSION_OPS
+ member function. */
+
+ static const struct exp_descriptor exp_descriptor_tab;
+
+ /* Helper for value_print_inner, arguments are as for that function.
+ Prints structs and untagged unions. */
+
+ void val_print_struct (struct value *val, struct ui_file *stream,
+ int recurse,
+ const struct value_print_options *options) const;
+
+ /* Helper for value_print_inner, arguments are as for that function.
+ Prints discriminated unions (Rust enums). */
+
+ void print_enum (struct value *val, struct ui_file *stream, int recurse,
+ const struct value_print_options *options) const;
+};
+
#endif /* RUST_LANG_H */
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 9/9] gdb: remove some uses of LA_PRINT_STRING
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
` (7 preceding siblings ...)
2020-11-20 11:55 ` [PATCH 8/9] gdb: move rust_language into rust-lang.h Andrew Burgess
@ 2020-11-20 11:55 ` Andrew Burgess
2020-12-10 20:51 ` Tom Tromey
2020-12-10 16:26 ` [PATCH 0/9] Further language class related changes Andrew Burgess
9 siblings, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2020-11-20 11:55 UTC (permalink / raw)
To: gdb-patches
This commit removes some, but not all, uses of LA_PRINT_STRING. In
this commit I've removed those uses where there is an obvious language
object on which I can instead call the printstr method.
In the remaining 3 uses it is harder to know if the correct thing is
to call printstr on the current language, or on a specific language.
Currently obviously, we always call on the current language (as that's
what LA_PRINT_STRING does), and clearly this behaviour is good enough
right now, but is it "right"? I've left them for now and will give
them more thought in the future.
gdb/ChangeLog:
* expprint.c (print_subexp_standard): Replace uses of
LA_PRINT_STRING.
* f-valprint.c (f_language::value_print_inner): Likewise.
* guile/scm-pretty-print.c (ppscm_print_string_repr): Likewise.
* p-valprint.c (pascal_language::value_print_inner): Likewise.
* python/py-prettyprint.c (print_string_repr): Likewise.
---
gdb/ChangeLog | 9 +++++++++
gdb/expprint.c | 19 +++++++++++--------
gdb/f-valprint.c | 10 +++++-----
gdb/guile/scm-pretty-print.c | 4 ++--
gdb/p-valprint.c | 8 ++++----
gdb/python/py-prettyprint.c | 4 ++--
6 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/gdb/expprint.c b/gdb/expprint.c
index 29e6237ab4d..950643a3777 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -226,9 +226,10 @@ print_subexp_standard (struct expression *exp, int *pos,
If necessary, we can temporarily set it to zero, or pass it as an
additional parameter to LA_PRINT_STRING. -fnf */
get_user_print_options (&opts);
- LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
- (gdb_byte *) &exp->elts[pc + 2].string, nargs,
- NULL, 0, &opts);
+ exp->language_defn
+ ->printstr (stream, builtin_type (exp->gdbarch)->builtin_char,
+ (gdb_byte *) &exp->elts[pc + 2].string, nargs,
+ NULL, 0, &opts);
}
return;
@@ -241,9 +242,10 @@ print_subexp_standard (struct expression *exp, int *pos,
(*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
fputs_filtered ("@\"", stream);
get_user_print_options (&opts);
- LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
- (gdb_byte *) &exp->elts[pc + 2].string, nargs,
- NULL, 0, &opts);
+ exp->language_defn
+ ->printstr (stream, builtin_type (exp->gdbarch)->builtin_char,
+ (gdb_byte *) &exp->elts[pc + 2].string, nargs,
+ NULL, 0, &opts);
fputs_filtered ("\"", stream);
}
return;
@@ -325,8 +327,9 @@ print_subexp_standard (struct expression *exp, int *pos,
struct value_print_options opts;
get_user_print_options (&opts);
- LA_PRINT_STRING (stream, builtin_type (exp->gdbarch)->builtin_char,
- (gdb_byte *) tempstr, nargs - 1, NULL, 0, &opts);
+ exp->language_defn
+ ->printstr (stream, builtin_type (exp->gdbarch)->builtin_char,
+ (gdb_byte *) tempstr, nargs - 1, NULL, 0, &opts);
(*pos) = pc;
}
else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index d147caa36fc..63cd9b3bd6b 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -235,8 +235,8 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
{
case TYPE_CODE_STRING:
f77_get_dynamic_length_of_aggregate (type);
- LA_PRINT_STRING (stream, builtin_type (gdbarch)->builtin_char,
- valaddr, TYPE_LENGTH (type), NULL, 0, options);
+ printstr (stream, builtin_type (gdbarch)->builtin_char, valaddr,
+ TYPE_LENGTH (type), NULL, 0, options);
break;
case TYPE_CODE_ARRAY:
@@ -247,9 +247,9 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
struct type *ch_type = TYPE_TARGET_TYPE (type);
f77_get_dynamic_length_of_aggregate (type);
- LA_PRINT_STRING (stream, ch_type, valaddr,
- TYPE_LENGTH (type) / TYPE_LENGTH (ch_type),
- NULL, 0, options);
+ printstr (stream, ch_type, valaddr,
+ TYPE_LENGTH (type) / TYPE_LENGTH (ch_type), NULL, 0,
+ options);
}
break;
diff --git a/gdb/guile/scm-pretty-print.c b/gdb/guile/scm-pretty-print.c
index df09dae434e..061868512d1 100644
--- a/gdb/guile/scm-pretty-print.c
+++ b/gdb/guile/scm-pretty-print.c
@@ -675,8 +675,8 @@ ppscm_print_string_repr (SCM printer, enum display_hint hint,
{
struct type *type = builtin_type (gdbarch)->builtin_char;
- LA_PRINT_STRING (stream, type, (gdb_byte *) string.get (),
- length, NULL, 0, options);
+ language->printstr (stream, type, (gdb_byte *) string.get (),
+ length, NULL, 0, options);
}
else
{
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index d2eb9c11750..496a872fd5e 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -116,8 +116,8 @@ pascal_language::value_print_inner (struct value *val,
len = temp_len;
}
- LA_PRINT_STRING (stream, TYPE_TARGET_TYPE (type),
- valaddr, len, NULL, 0, options);
+ printstr (stream, TYPE_TARGET_TYPE (type), valaddr, len,
+ NULL, 0, options);
i = len;
}
else
@@ -318,8 +318,8 @@ pascal_language::value_print_inner (struct value *val,
{
len = extract_unsigned_integer (valaddr + length_pos,
length_size, byte_order);
- LA_PRINT_STRING (stream, char_type, valaddr + string_pos,
- len, NULL, 0, options);
+ printstr (stream, char_type, valaddr + string_pos, len,
+ NULL, 0, options);
}
else
pascal_object_print_value_fields (val, stream, recurse,
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index 8eaa41fb187..6300cb0bc57 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -318,8 +318,8 @@ print_string_repr (PyObject *printer, const char *hint,
type = builtin_type (gdbarch)->builtin_char;
if (hint && !strcmp (hint, "string"))
- LA_PRINT_STRING (stream, type, (gdb_byte *) output,
- length, NULL, 0, options);
+ language->printstr (stream, type, (gdb_byte *) output,
+ length, NULL, 0, options);
else
fputs_filtered (output, stream);
}
--
2.25.4
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/9] Further language class related changes
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
` (8 preceding siblings ...)
2020-11-20 11:55 ` [PATCH 9/9] gdb: remove some uses of LA_PRINT_STRING Andrew Burgess
@ 2020-12-10 16:26 ` Andrew Burgess
2020-12-10 20:51 ` Tom Tromey
9 siblings, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2020-12-10 16:26 UTC (permalink / raw)
To: gdb-patches
* Andrew Burgess <andrew.burgess@embecosm.com> [2020-11-20 11:54:55 +0000]:
> The changes in this series do two things:
>
> 1. Reduce the use of the LA_* macros from language.h, with
> LA_EMIT_CHAR being completely removed, and LA_PRINT_STRING being
> reduced in usage.
>
> 2. Move some additional language classes into the language's header
> file. This allows functions defined in different *.c files to be
> renamed as language_class::member_function rather than having to
> trampoline from the member function to a global.
>
> The patch that's most worth reviewing is, I think #2 where I replace
> direct calls to a global function with calls to a language classes
> member functions.
>
> All feedback welcome.
Unless someone shouts out I plan to push this series in the next few
days.
Thanks,
Andrew
>
> Thanks,
> Andrew
>
>
> ---
>
> Andrew Burgess (9):
> gdb: delete unused function print_char_chars
> gdb: avoid accessing global C++ language implementation functions
> gdb: rename c_printchar as language_defn::printchar
> gdb: remove LA_EMIT_CHAR macro
> gdb: move go_language class declaration into header file
> gdb: move pascal_language into p-lang.h
> gdb/objc: fix bug in objc_language::opcode_print_table
> gdb: move rust_language into rust-lang.h
> gdb: remove some uses of LA_PRINT_STRING
>
> gdb/ChangeLog | 162 ++++++++++++++
> gdb/c-lang.c | 7 +-
> gdb/c-lang.h | 2 -
> gdb/dwarf2/read.c | 7 +-
> gdb/expprint.c | 19 +-
> gdb/f-lang.h | 2 +-
> gdb/f-valprint.c | 10 +-
> gdb/go-exp.y | 4 +-
> gdb/go-lang.c | 164 ++++-----------
> gdb/go-lang.h | 94 +++++++--
> gdb/go-typeprint.c | 6 +-
> gdb/go-valprint.c | 5 +-
> gdb/guile/scm-pretty-print.c | 4 +-
> gdb/language.c | 9 -
> gdb/language.h | 2 -
> gdb/objc-lang.c | 2 +-
> gdb/p-exp.y | 11 +-
> gdb/p-lang.c | 384 ++++++++++++---------------------
> gdb/p-lang.h | 245 ++++++++++++++++++---
> gdb/p-typeprint.c | 214 +++++++------------
> gdb/p-valprint.c | 30 ++-
> gdb/python/py-prettyprint.c | 4 +-
> gdb/rust-exp.y | 2 +-
> gdb/rust-lang.c | 397 +++++++++++------------------------
> gdb/rust-lang.h | 198 ++++++++++++++++-
> gdb/symtab.c | 3 +-
> gdb/valprint.c | 37 ----
> gdb/valprint.h | 3 -
> 28 files changed, 1089 insertions(+), 938 deletions(-)
>
> --
> 2.25.4
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/9] gdb: avoid accessing global C++ language implementation functions
2020-11-20 11:54 ` [PATCH 2/9] gdb: avoid accessing global C++ language implementation functions Andrew Burgess
@ 2020-12-10 20:47 ` Tom Tromey
0 siblings, 0 replies; 14+ messages in thread
From: Tom Tromey @ 2020-12-10 20:47 UTC (permalink / raw)
To: Andrew Burgess; +Cc: gdb-patches
>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:
Andrew> The function c_printchar is called from two places; it provides the
Andrew> implementation of language_defn::printchar and it is called from
Andrew> dwarf2_compute_name.
Andrew> It would be nice to rename c_printchar as language_defn::printchar and
Andrew> so avoid the trampoline.
Andrew> To achieve this, instead of calling c_printchar directly from the
Andrew> DWARF code, I lookup the C++ language object and call the printchar
Andrew> member function.
This seems fine to me.
Andrew> if (child->tag == DW_TAG_template_type_param)
Andrew> {
Andrew> - c_print_type (type, "", &buf, -1, 0, cu->language,
Andrew> - &type_print_raw_options);
Andrew> + cplus_lang->print_type (type, "", &buf, -1, 0,
Andrew> + &type_print_raw_options);
Andrew> continue;
Andrew> }
I wish we could just remove this code. Calling the type-printing code,
which may want to resolve types, from the debug-reading code seems like
a bad idea.
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 9/9] gdb: remove some uses of LA_PRINT_STRING
2020-11-20 11:55 ` [PATCH 9/9] gdb: remove some uses of LA_PRINT_STRING Andrew Burgess
@ 2020-12-10 20:51 ` Tom Tromey
0 siblings, 0 replies; 14+ messages in thread
From: Tom Tromey @ 2020-12-10 20:51 UTC (permalink / raw)
To: Andrew Burgess; +Cc: gdb-patches
>>>>> "Andrew" == Andrew Burgess <andrew.burgess@embecosm.com> writes:
Andrew> In the remaining 3 uses it is harder to know if the correct thing is
Andrew> to call printstr on the current language, or on a specific language.
Andrew> Currently obviously, we always call on the current language (as that's
Andrew> what LA_PRINT_STRING does), and clearly this behaviour is good enough
Andrew> right now, but is it "right"? I've left them for now and will give
Andrew> them more thought in the future.
I didn't look to see what is left, or dig into this deeply at all, but I
wanted to mention: it was a relatively common thing for other languages
to depend on the C value-printer in particular, and so that printing
code was written in a funny style where it would sometimes make calls
via current_language to pick up the behavior of that other language in
some cases. These days that would be better expressed by inheritance,
though I realize of course this would be toward the end, and not the
beginning, of the refactorings. (Or even not done at all if possible.)
thanks,
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/9] Further language class related changes
2020-12-10 16:26 ` [PATCH 0/9] Further language class related changes Andrew Burgess
@ 2020-12-10 20:51 ` Tom Tromey
0 siblings, 0 replies; 14+ messages in thread
From: Tom Tromey @ 2020-12-10 20:51 UTC (permalink / raw)
To: Andrew Burgess; +Cc: gdb-patches
Andrew> Unless someone shouts out I plan to push this series in the next few
Andrew> days.
It all looks good to me. Thank you for doing this.
Tom
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2020-12-10 20:51 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-20 11:54 [PATCH 0/9] Further language class related changes Andrew Burgess
2020-11-20 11:54 ` [PATCH 1/9] gdb: delete unused function print_char_chars Andrew Burgess
2020-11-20 11:54 ` [PATCH 2/9] gdb: avoid accessing global C++ language implementation functions Andrew Burgess
2020-12-10 20:47 ` Tom Tromey
2020-11-20 11:54 ` [PATCH 3/9] gdb: rename c_printchar as language_defn::printchar Andrew Burgess
2020-11-20 11:54 ` [PATCH 4/9] gdb: remove LA_EMIT_CHAR macro Andrew Burgess
2020-11-20 11:55 ` [PATCH 5/9] gdb: move go_language class declaration into header file Andrew Burgess
2020-11-20 11:55 ` [PATCH 6/9] gdb: move pascal_language into p-lang.h Andrew Burgess
2020-11-20 11:55 ` [PATCH 7/9] gdb/objc: fix bug in objc_language::opcode_print_table Andrew Burgess
2020-11-20 11:55 ` [PATCH 8/9] gdb: move rust_language into rust-lang.h Andrew Burgess
2020-11-20 11:55 ` [PATCH 9/9] gdb: remove some uses of LA_PRINT_STRING Andrew Burgess
2020-12-10 20:51 ` Tom Tromey
2020-12-10 16:26 ` [PATCH 0/9] Further language class related changes Andrew Burgess
2020-12-10 20:51 ` Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).