summaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
authorBruno Larsen <blarsen@redhat.com>2022-10-05 14:22:56 +0200
committerBruno Larsen <blarsen@redhat.com>2022-11-10 14:51:49 +0100
commit041de3d73aa121f2ff0c077213598963bfb34b79 (patch)
tree5d6224170af2d32f340a3c28f06f30cff3bd39d5 /gdb/valops.c
parent2acccd0a59af7a04e341d31f68b370486d5fc474 (diff)
downloadbinutils-gdb-041de3d73aa121f2ff0c077213598963bfb34b79.tar.gz
gdb/c++: Improve error messages in overload resolution
When resolving overloaded functions, GDB relies on knowing relationships between types, i.e. if a type inherits from another. However, some compilers may not add complete information for given types as a way to reduce unnecessary debug information. In these cases, GDB would just say that it couldn't resolve the method or function, with no extra information. The problem is that sometimes the user may not know that the type information is incomplete, and may just assume that there is a bug in GDB. To improve the user experience, we attempt to detect if the overload match failed because of an incomplete type, and warn the user of this. This commit also adds a testcase confirming that the message is only triggered in the correct scenario. This test was not developed as an expansion of gdb.cp/overload.cc because it needed the dwarf assembler, and porting all of overload.cc seemed unnecessary. Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index ecfceed199a..2b789cd76f4 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -41,6 +41,7 @@
#include "extension.h"
#include "gdbtypes.h"
#include "gdbsupport/byte-vector.h"
+#include "typeprint.h"
/* Local functions. */
@@ -2617,6 +2618,49 @@ value_find_oload_method_list (struct value **argp, const char *method,
basetype, boffset);
}
+/* Helper function for find_overload_match. If no matches were
+ found, this function may generate a hint for the user that some
+ of the relevant types are incomplete, so GDB can't evaluate
+ type relationships to properly evaluate overloads.
+
+ If no incomplete types are present, an empty string is returned. */
+static std::string
+incomplete_type_hint (gdb::array_view<value *> args)
+{
+ int incomplete_types = 0;
+ std::string incomplete_arg_names;
+ for (const struct value *arg : args)
+ {
+ struct type *t = value_type (arg);
+ while (t->code () == TYPE_CODE_PTR)
+ t = t->target_type ();
+ if (t->is_stub ())
+ {
+ string_file buffer;
+ if (incomplete_types > 0)
+ incomplete_arg_names += ", ";
+
+ current_language->print_type (value_type (arg), "", &buffer,
+ -1, 0, &type_print_raw_options);
+
+ incomplete_types++;
+ incomplete_arg_names += buffer.string ();
+ }
+ }
+ std::string hint;
+ if (incomplete_types > 1)
+ hint = string_printf (_("\nThe types: '%s' aren't fully known to GDB."
+ " Please cast them directly to the desired"
+ " typed in the function call."),
+ incomplete_arg_names.c_str ());
+ else if (incomplete_types == 1)
+ hint = string_printf (_("\nThe type: '%s' isn't fully known to GDB."
+ " Please cast it directly to the desired"
+ " typed in the function call."),
+ incomplete_arg_names.c_str ());
+ return hint;
+}
+
/* Given an array of arguments (ARGS) (which includes an entry for
"this" in the case of C++ methods), the NAME of a function, and
whether it's a method or not (METHOD), find the best function that
@@ -2933,14 +2977,15 @@ find_overload_match (gdb::array_view<value *> args,
if (match_quality == INCOMPATIBLE)
{
+ std::string hint = incomplete_type_hint (args);
if (method == METHOD)
- error (_("Cannot resolve method %s%s%s to any overloaded instance"),
+ error (_("Cannot resolve method %s%s%s to any overloaded instance.%s"),
obj_type_name,
(obj_type_name && *obj_type_name) ? "::" : "",
- name);
+ name, hint.c_str ());
else
- error (_("Cannot resolve function %s to any overloaded instance"),
- func_name);
+ error (_("Cannot resolve function %s to any overloaded instance.%s"),
+ func_name, hint.c_str ());
}
else if (match_quality == NON_STANDARD)
{