public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] gdb: Introduce new language field la_is_string_type_p
@ 2019-04-29 21:03 Andrew Burgess
0 siblings, 0 replies; only message in thread
From: Andrew Burgess @ 2019-04-29 21:03 UTC (permalink / raw)
To: gdb-cvs
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4be290b2517839872ef7de47230be8dbd291a7e5
commit 4be290b2517839872ef7de47230be8dbd291a7e5
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Tue Apr 9 23:06:41 2019 +0100
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.
Diff:
---
gdb/ChangeLog | 28 ++++++++++++++++++++++++++++
gdb/ada-lang.c | 1 +
gdb/c-lang.c | 40 ++++++++++++++++++++++++++++++++++++++++
gdb/c-lang.h | 5 +++++
gdb/d-lang.c | 1 +
gdb/f-lang.c | 12 ++++++++++++
gdb/go-lang.c | 11 +++++++++++
gdb/language.c | 16 ++++++++++++++++
gdb/language.h | 7 +++++++
gdb/m2-lang.c | 22 ++++++++++++++++++++++
gdb/objc-lang.c | 1 +
gdb/opencl-lang.c | 1 +
gdb/p-lang.c | 11 +++++++++++
gdb/rust-lang.c | 21 +++++++++++++++++++++
14 files changed, 177 insertions(+)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0bbe400..432eb7b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,33 @@
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>:
New field.
* ada-lang.c (ada_language_defn): Initialise new field.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 4fcbce7..28ab931 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -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 */
};
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 3be5ef5..aeffefa 100644
--- a/gdb/c-lang.c
+++ b/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;
+}
+
\f
/* 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 */
};
diff --git a/gdb/c-lang.h b/gdb/c-lang.h
index e7b6d5e..70a95ea 100644
--- a/gdb/c-lang.h
+++ b/gdb/c-lang.h
@@ -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);
diff --git a/gdb/d-lang.c b/gdb/d-lang.c
index 751c521..0f8f916 100644
--- a/gdb/d-lang.c
+++ b/gdb/d-lang.c
@@ -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 */
};
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 77eb50a..e501d5c 100644
--- a/gdb/f-lang.c
+++ b/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 */
};
diff --git a/gdb/go-lang.c b/gdb/go-lang.c
index b8617cb..6473468 100644
--- a/gdb/go-lang.c
+++ b/gdb/go-lang.c
@@ -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 */
};
diff --git a/gdb/language.c b/gdb/language.c
index da8dd1b..9d0eb03 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -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 */
};
diff --git a/gdb/language.h b/gdb/language.h
index 261f5a3..e7446ef 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -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);
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 9f2a97d..6fe6289 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -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 */
};
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index af92e55..b25a981 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -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 */
};
diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
index c95bf05..93d8e2f 100644
--- a/gdb/opencl-lang.c
+++ b/gdb/opencl-lang.c
@@ -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 */
};
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index 0b85f70..9b9f19b 100644
--- a/gdb/p-lang.c
+++ b/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 */
};
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index 8faafd4..2fada46 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -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 */
};
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2019-04-29 21:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-29 21:03 [binutils-gdb] gdb: Introduce new language field la_is_string_type_p Andrew Burgess
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).