gdb: Introduce new language field la_is_string_type_p
This commit is preparation work for the next commit, and by itself makes no user visible change to GDB. I've split this work into a separate commit in order to make code review easier. This commit adds a new field 'la_is_string_type_p' to the language struct, this predicate will return true if a type is a string type for the given language. Some languages already have a "is this a string" predicate that I was able to reuse, while for other languages I've had to add a new predicate. In this case I took inspiration from the value printing code for that language - what different conditions would result in printing something as a string. A default "is this a string" method has also been added that looks for TYPE_CODE_STRING, this is the fallback I've used for a couple of languages. In this commit I add the new field and initialise it for each language, however at this stage the new field is never used. gdb/ChangeLog: * ada-lang.c (ada_language_defn): Initialise new field. * c-lang.c (c_is_string_type_p): New function. (c_language_defn): Initialise new field. (cplus_language_defn): Initialise new field. (asm_language_defn): Initialise new field. (minimal_language_defn): Initialise new field. * c-lang.h (c_is_string_type_p): Declare new function. * d-lang.c (d_language_defn): Initialise new field. * f-lang.c (f_is_string_type_p): New function. (f_language_defn): Initialise new field. * go-lang.c (go_is_string_type_p): New function. (go_language_defn): Initialise new field. * language.c (default_is_string_type_p): New function. (unknown_language_defn): Initialise new field. (auto_language_defn): Initialise new field. * language.h (struct language_defn) <la_is_string_type_p>: New member variable. (default_is_string_type_p): Declare new function. * m2-lang.c (m2_language_defn): Initialise new field. * objc-lang.c (objc_language_defn): Initialise new field. * opencl-lang.c (opencl_language_defn): Initialise new field. * p-lang.c (pascal_is_string_type_p): New function. (pascal_language_defn): Initialise new field. * rust-lang.c (rust_is_string_type_p): New function. (rust_language_defn): Initialise new field.
This commit is contained in:
parent
721b08c686
commit
4be290b251
@ -1,3 +1,31 @@
|
||||
2019-04-29 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* ada-lang.c (ada_language_defn): Initialise new field.
|
||||
* c-lang.c (c_is_string_type_p): New function.
|
||||
(c_language_defn): Initialise new field.
|
||||
(cplus_language_defn): Initialise new field.
|
||||
(asm_language_defn): Initialise new field.
|
||||
(minimal_language_defn): Initialise new field.
|
||||
* c-lang.h (c_is_string_type_p): Declare new function.
|
||||
* d-lang.c (d_language_defn): Initialise new field.
|
||||
* f-lang.c (f_is_string_type_p): New function.
|
||||
(f_language_defn): Initialise new field.
|
||||
* go-lang.c (go_is_string_type_p): New function.
|
||||
(go_language_defn): Initialise new field.
|
||||
* language.c (default_is_string_type_p): New function.
|
||||
(unknown_language_defn): Initialise new field.
|
||||
(auto_language_defn): Initialise new field.
|
||||
* language.h (struct language_defn) <la_is_string_type_p>: New
|
||||
member variable.
|
||||
(default_is_string_type_p): Declare new function.
|
||||
* m2-lang.c (m2_language_defn): Initialise new field.
|
||||
* objc-lang.c (objc_language_defn): Initialise new field.
|
||||
* opencl-lang.c (opencl_language_defn): Initialise new field.
|
||||
* p-lang.c (pascal_is_string_type_p): New function.
|
||||
(pascal_language_defn): Initialise new field.
|
||||
* rust-lang.c (rust_is_string_type_p): New function.
|
||||
(rust_language_defn): Initialise new field.
|
||||
|
||||
2019-04-29 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||
|
||||
* language.h (struct language_defn) <la_struct_too_deep_ellipsis>:
|
||||
|
@ -14390,6 +14390,7 @@ extern const struct language_defn ada_language_defn = {
|
||||
&ada_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
ada_is_string_type,
|
||||
"(...)" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
40
gdb/c-lang.c
40
gdb/c-lang.c
@ -715,6 +715,42 @@ c_watch_location_expression (struct type *type, CORE_ADDR addr)
|
||||
(xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr)));
|
||||
}
|
||||
|
||||
/* See c-lang.h. */
|
||||
|
||||
bool
|
||||
c_is_string_type_p (struct type *type)
|
||||
{
|
||||
type = check_typedef (type);
|
||||
while (TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
{
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
type = check_typedef (type);
|
||||
}
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
{
|
||||
/* See if target type looks like a string. */
|
||||
struct type *array_target_type = TYPE_TARGET_TYPE (type);
|
||||
return (TYPE_LENGTH (type) > 0
|
||||
&& TYPE_LENGTH (array_target_type) > 0
|
||||
&& c_textual_element_type (array_target_type, 0));
|
||||
}
|
||||
case TYPE_CODE_STRING:
|
||||
return true;
|
||||
case TYPE_CODE_PTR:
|
||||
{
|
||||
struct type *element_type = TYPE_TARGET_TYPE (type);
|
||||
return c_textual_element_type (element_type, 0);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Table mapping opcodes into strings for printing operators
|
||||
and precedences of the operators. */
|
||||
@ -874,6 +910,7 @@ extern const struct language_defn c_language_defn =
|
||||
&c_varobj_ops,
|
||||
c_get_compile_context,
|
||||
c_compute_program,
|
||||
c_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
@ -1019,6 +1056,7 @@ extern const struct language_defn cplus_language_defn =
|
||||
&cplus_varobj_ops,
|
||||
cplus_get_compile_context,
|
||||
cplus_compute_program,
|
||||
c_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
@ -1073,6 +1111,7 @@ extern const struct language_defn asm_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
c_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
@ -1127,5 +1166,6 @@ extern const struct language_defn minimal_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
c_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
@ -148,6 +148,11 @@ extern int cp_is_vtbl_ptr_type (struct type *);
|
||||
|
||||
extern int cp_is_vtbl_member (struct type *);
|
||||
|
||||
/* Return true if TYPE is a string type. Unlike DEFAULT_IS_STRING_TYPE_P
|
||||
this will detect arrays of characters not just TYPE_CODE_STRING. */
|
||||
|
||||
extern bool c_is_string_type_p (struct type *type);
|
||||
|
||||
/* These are in c-valprint.c. */
|
||||
|
||||
extern int c_textual_element_type (struct type *, char);
|
||||
|
@ -251,6 +251,7 @@ extern const struct language_defn d_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
c_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
12
gdb/f-lang.c
12
gdb/f-lang.c
@ -308,6 +308,17 @@ evaluate_subexp_f (struct type *expect_type, struct expression *exp,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Return true if TYPE is a string. */
|
||||
|
||||
static bool
|
||||
f_is_string_type_p (struct type *type)
|
||||
{
|
||||
type = check_typedef (type);
|
||||
return (TYPE_CODE (type) == TYPE_CODE_STRING
|
||||
|| (TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||||
&& TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CHAR));
|
||||
}
|
||||
|
||||
static const char *f_extensions[] =
|
||||
{
|
||||
".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP",
|
||||
@ -378,6 +389,7 @@ extern const struct language_defn f_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
f_is_string_type_p,
|
||||
"(...)" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
@ -130,6 +130,16 @@ go_classify_struct_type (struct type *type)
|
||||
return GO_TYPE_NONE;
|
||||
}
|
||||
|
||||
/* Return true if TYPE is a string. */
|
||||
|
||||
static bool
|
||||
go_is_string_type_p (struct type *type)
|
||||
{
|
||||
type = check_typedef (type);
|
||||
return (TYPE_CODE (type) == TYPE_CODE_STRUCT
|
||||
&& go_classify_struct_type (type) == GO_TYPE_STRING);
|
||||
}
|
||||
|
||||
/* Subroutine of unpack_mangled_go_symbol to simplify it.
|
||||
Given "[foo.]bar.baz", store "bar" in *PACKAGEP and "baz" in *OBJECTP.
|
||||
We stomp on the last '.' to nul-terminate "bar".
|
||||
@ -612,6 +622,7 @@ extern const struct language_defn go_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
go_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
@ -723,6 +723,20 @@ default_symbol_name_matcher (const char *symbol_search_name,
|
||||
|
||||
/* See language.h. */
|
||||
|
||||
bool
|
||||
default_is_string_type_p (struct type *type)
|
||||
{
|
||||
type = check_typedef (type);
|
||||
while (TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
{
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
type = check_typedef (type);
|
||||
}
|
||||
return (TYPE_CODE (type) == TYPE_CODE_STRING);
|
||||
}
|
||||
|
||||
/* See language.h. */
|
||||
|
||||
symbol_name_matcher_ftype *
|
||||
get_symbol_name_matcher (const language_defn *lang,
|
||||
const lookup_name_info &lookup_name)
|
||||
@ -877,6 +891,7 @@ const struct language_defn unknown_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
default_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
@ -928,6 +943,7 @@ const struct language_defn auto_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
default_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
@ -450,6 +450,9 @@ struct language_defn
|
||||
const struct block *expr_block,
|
||||
CORE_ADDR expr_pc);
|
||||
|
||||
/* Return true if TYPE is a string type. */
|
||||
bool (*la_is_string_type_p) (struct type *type);
|
||||
|
||||
/* This string is used by the 'set print max-depth' setting. When GDB
|
||||
replaces a struct or union (during value printing) that is "too
|
||||
deep" this string is displayed instead. */
|
||||
@ -575,6 +578,10 @@ extern enum language set_language (enum language);
|
||||
|
||||
extern int pointer_type (struct type *);
|
||||
|
||||
/* Return true if TYPE is a string type, otherwise return false. This
|
||||
default implementation only detects TYPE_CODE_STRING. */
|
||||
extern bool default_is_string_type_p (struct type *type);
|
||||
|
||||
/* Error messages */
|
||||
|
||||
extern void range_error (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
|
||||
|
@ -174,6 +174,27 @@ m2_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string,
|
||||
fputs_filtered ("...", stream);
|
||||
}
|
||||
|
||||
/* Return true if TYPE is a string. */
|
||||
|
||||
static bool
|
||||
m2_is_string_type_p (struct type *type)
|
||||
{
|
||||
type = check_typedef (type);
|
||||
if (TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||||
&& TYPE_LENGTH (type) > 0
|
||||
&& TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
|
||||
{
|
||||
struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
|
||||
if (TYPE_LENGTH (elttype) == 1
|
||||
&& (TYPE_CODE (elttype) == TYPE_CODE_INT
|
||||
|| TYPE_CODE (elttype) == TYPE_CODE_CHAR))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct value *
|
||||
evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
|
||||
int *pos, enum noside noside)
|
||||
@ -399,6 +420,7 @@ extern const struct language_defn m2_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
m2_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
@ -409,6 +409,7 @@ extern const struct language_defn objc_language_defn = {
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
c_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
@ -1087,6 +1087,7 @@ extern const struct language_defn opencl_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
c_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
||||
|
11
gdb/p-lang.c
11
gdb/p-lang.c
@ -150,6 +150,16 @@ is_pascal_string_type (struct type *type,int *length_pos,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is a wrapper around IS_PASCAL_STRING_TYPE that returns true if TYPE
|
||||
is a string. */
|
||||
|
||||
static bool
|
||||
pascal_is_string_type_p (struct type *type)
|
||||
{
|
||||
return is_pascal_string_type (type, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr) > 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
|
||||
@ -460,5 +470,6 @@ extern const struct language_defn pascal_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
pascal_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
@ -226,6 +226,26 @@ rust_chartype_p (struct type *type)
|
||||
&& TYPE_UNSIGNED (type));
|
||||
}
|
||||
|
||||
/* Return true if TYPE is a string type. */
|
||||
|
||||
static bool
|
||||
rust_is_string_type_p (struct type *type)
|
||||
{
|
||||
LONGEST low_bound, high_bound;
|
||||
|
||||
type = check_typedef (type);
|
||||
return ((TYPE_CODE (type) == TYPE_CODE_STRING)
|
||||
|| (TYPE_CODE (type) == TYPE_CODE_PTR
|
||||
&& (TYPE_CODE (TYPE_TARGET_TYPE (type)) == 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) == TYPE_CODE_STRUCT
|
||||
&& !rust_enum_p (type)
|
||||
&& rust_slice_type_p (type)
|
||||
&& strcmp (TYPE_NAME (type), "&str") == 0));
|
||||
}
|
||||
|
||||
/* If VALUE represents a trait object pointer, return the underlying
|
||||
pointer with the correct (i.e., runtime) type. Otherwise, return
|
||||
NULL. */
|
||||
@ -2142,5 +2162,6 @@ extern const struct language_defn rust_language_defn =
|
||||
&default_varobj_ops,
|
||||
NULL,
|
||||
NULL,
|
||||
rust_is_string_type_p,
|
||||
"{...}" /* la_struct_too_deep_ellipsis */
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user