diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-10-30 20:40:59 +0000 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2020-11-12 23:36:25 +0000 |
commit | 7bea47f0012c208d935c50d3b7ce9af7d34482b7 (patch) | |
tree | 2af27e112306612fdb6c55597687ef6640f312e0 /gdb/rust-lang.c | |
parent | bf6e5d01d7b149e116a008bd4348983c6f56e9ba (diff) | |
download | gdb-7bea47f0012c208d935c50d3b7ce9af7d34482b7.zip gdb-7bea47f0012c208d935c50d3b7ce9af7d34482b7.tar.gz gdb-7bea47f0012c208d935c50d3b7ce9af7d34482b7.tar.bz2 |
gdb: rewrite how per language primitive types are managed
Consider the following GDB session:
$ gdb
(gdb) set language c
(gdb) ptype void
type = void
(gdb) set language fortran
(gdb) ptype void
No symbol table is loaded. Use the "file" command.
(gdb)
With no symbol file loaded GDB and the language set to C GDB knows
about the type void, while when the language is set to Fortran GDB
doesn't know about the void, why is that?
In f-lang.c, f_language::language_arch_info, we do have this line:
lai->primitive_type_vector [f_primitive_type_void]
= builtin->builtin_void;
where we add the void type to the list of primitive types that GDB
should always know about, so what's going wrong?
It turns out that the primitive types are stored in a C style array,
indexed by an enum, so Fortran uses `enum f_primitive_types'. The
array is allocated and populated in each languages language_arch_info
member function. The array is allocated with an extra entry at the
end which is left as a NULL value, and this indicates the end of the
array of types.
Unfortunately for Fortran, a type is not assigned for each element in
the enum. As a result the final populated array has gaps in it, gaps
which are initialised to NULL, and so every time we iterate over the
list (for Fortran) we stop early, and never reach the void type.
This has been the case since 2007 when this functionality was added to
GDB in commit cad351d11d6c3f6487cd.
Obviously I could just fix Fortran by ensuring that either the enum is
trimmed, or we create types for the missing types. However, I think a
better approach would be to move to C++ data structures and removed
the fixed enum indexing into the array approach.
After this commit the primitive types are pushed into a vector, and
GDB just iterates over the vector in the obvious way when it needs to
hunt for a type. After this commit all the currently defined
primitive types can be found when the language is set to Fortran, for
example:
$ gdb
(gdb) set language fortran
(gdb) ptype void
type = void
(gdb)
A new test checks this functionality.
I didn't see any other languages with similar issues, but I could have
missed something.
gdb/ChangeLog:
* ada-exp.y (find_primitive_type): Make parameter const.
* ada-lang.c (enum ada_primitive_types): Delete.
(ada_language::language_arch_info): Update.
* c-lang.c (enum c_primitive_types): Delete.
(c_language_arch_info): Update.
(enum cplus_primitive_types): Delete.
(cplus_language::language_arch_info): Update.
* d-lang.c (enum d_primitive_types): Delete.
(d_language::language_arch_info): Update.
* f-lang.c (enum f_primitive_types): Delete.
(f_language::language_arch_info): Update.
* go-lang.c (enum go_primitive_types): Delete.
(go_language::language_arch_info): Update.
* language.c (auto_or_unknown_language::language_arch_info):
Update.
(language_gdbarch_post_init): Use obstack_new, use array indexing.
(language_string_char_type): Add header comment, call function in
language_arch_info.
(language_bool_type): Likewise
(language_arch_info::bool_type): Define.
(language_lookup_primitive_type_1): Delete.
(language_lookup_primitive_type): Rewrite as a templated function
to call function in language_arch_info, then instantiate twice.
(language_arch_info::type_and_symbol::alloc_type_symbol): Define.
(language_arch_info::lookup_primitive_type_and_symbol): Define.
(language_arch_info::lookup_primitive_type): Define twice with
different signatures.
(language_arch_info::lookup_primitive_type_as_symbol): Define.
(language_lookup_primitive_type_as_symbol): Rewrite to call a
member function in language_arch_info.
* language.h (language_arch_info): Complete rewrite.
(language_lookup_primitive_type): Make templated.
* m2-lang.c (enum m2_primitive_types): Delete.
(m2_language::language_arch_info): Update.
* opencl-lang.c (OCL_P_TYPE): Delete.
(enum opencl_primitive_types): Delete.
(opencl_type_data): Delete.
(builtin_opencl_type): Delete.
(lookup_opencl_vector_type): Update.
(opencl_language::language_arch_info): Update, lots of content
moved from...
(build_opencl_types): ...here. This function is now deleted.
(_initialize_opencl_language): Delete.
* p-lang.c (enum pascal_primitive_types): Delete.
(pascal_language::language_arch_info): Update.
* rust-lang.c (enum rust_primitive_types): Delete.
(rust_language::language_arch_info): Update.
gdb/testsuite/ChangeLog:
* gdb.fortran/types.exp: Add more tests.
Diffstat (limited to 'gdb/rust-lang.c')
-rw-r--r-- | gdb/rust-lang.c | 78 |
1 files changed, 29 insertions, 49 deletions
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index a50f3b7..407be56 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -961,27 +961,6 @@ rust_slice_type (const char *name, struct type *elt_type, return type; } -enum rust_primitive_types -{ - rust_primitive_bool, - rust_primitive_char, - rust_primitive_i8, - rust_primitive_u8, - rust_primitive_i16, - rust_primitive_u16, - rust_primitive_i32, - rust_primitive_u32, - rust_primitive_i64, - rust_primitive_u64, - rust_primitive_isize, - rust_primitive_usize, - rust_primitive_f32, - rust_primitive_f64, - rust_primitive_unit, - rust_primitive_str, - nr_rust_primitive_types -}; - /* A helper for rust_evaluate_subexp that handles OP_FUNCALL. */ @@ -1927,39 +1906,40 @@ public: { const struct builtin_type *builtin = builtin_type (gdbarch); - struct type **types - = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_rust_primitive_types + 1, - struct type *); - - types[rust_primitive_bool] = arch_boolean_type (gdbarch, 8, 1, "bool"); - types[rust_primitive_char] = arch_character_type (gdbarch, 32, 1, "char"); - types[rust_primitive_i8] = arch_integer_type (gdbarch, 8, 0, "i8"); - types[rust_primitive_u8] = arch_integer_type (gdbarch, 8, 1, "u8"); - types[rust_primitive_i16] = arch_integer_type (gdbarch, 16, 0, "i16"); - types[rust_primitive_u16] = arch_integer_type (gdbarch, 16, 1, "u16"); - types[rust_primitive_i32] = arch_integer_type (gdbarch, 32, 0, "i32"); - types[rust_primitive_u32] = arch_integer_type (gdbarch, 32, 1, "u32"); - types[rust_primitive_i64] = arch_integer_type (gdbarch, 64, 0, "i64"); - types[rust_primitive_u64] = arch_integer_type (gdbarch, 64, 1, "u64"); + /* 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); - types[rust_primitive_isize] = arch_integer_type (gdbarch, length, 0, "isize"); - types[rust_primitive_usize] = arch_integer_type (gdbarch, length, 1, "usize"); - - types[rust_primitive_f32] = arch_float_type (gdbarch, 32, "f32", - floatformats_ieee_single); - types[rust_primitive_f64] = arch_float_type (gdbarch, 64, "f64", - floatformats_ieee_double); + add (arch_integer_type (gdbarch, length, 0, "isize")); + struct type *usize_type + = add (arch_integer_type (gdbarch, length, 1, "usize")); - types[rust_primitive_unit] = arch_integer_type (gdbarch, 0, 1, "()"); + 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, types[rust_primitive_u8], NULL); - types[rust_primitive_str] = rust_slice_type ("&str", tem, - types[rust_primitive_usize]); + struct type *tem = make_cv_type (1, 0, u8_type, NULL); + add (rust_slice_type ("&str", tem, usize_type)); - lai->primitive_type_vector = types; - lai->bool_type_default = types[rust_primitive_bool]; - lai->string_char_type = types[rust_primitive_u8]; + lai->set_bool_type (bool_type); + lai->set_string_char_type (u8_type); } /* See language.h. */ |