summaryrefslogtreecommitdiff
path: root/gdb/gnu-v3-abi.c
diff options
context:
space:
mode:
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2019-12-20 17:43:06 +0100
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2019-12-20 17:43:06 +0100
commit9d084466d740e40c655609f9c04b3bb2b9b9ca76 (patch)
tree210f4ac3ac14359576fce5bda16bd3522a43c1b1 /gdb/gnu-v3-abi.c
parente35000a7f8be021459102751db7e0b7e2868b57e (diff)
downloadbinutils-gdb-9d084466d740e40c655609f9c04b3bb2b9b9ca76.tar.gz
infcall, c++: allow more info to be computed for pass-by-reference values
In C++, call-by-value arguments that cannot be trivially copied are implicitly passed by reference. When making an infcall, GDB needs to find out if an argument is pass-by-reference or not, so that the correct semantics can be followed. This patch enriches the information computed by the language ops for pass-by-reference arguments. Instead of a plain binary result, the computed information now includes whether the argument is - copy constructible - destructible - trivially copyable - trivially copy constructible - trivially destructible This information is stored in a struct named 'language_pass_by_ref_info'. This patch paves the way for GDB's infcall mechanism to call the copy ctor and the destructor of a pass-by-ref argument appropriately. gdb/ChangeLog: 2019-12-20 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * language.h (struct language_pass_by_ref_info): New struct. (struct language_defn)<la_pass_by_reference>: Change the signature to return a language_pass_by_ref_info instead of an int. (language_pass_by_reference): Ditto. (default_pass_by_reference): Ditto. Adjust the users listed below. * arch-utils.c (default_return_in_first_hidden_param_p): Update. * cp-abi.c (cp_pass_by_reference): Update. * cp-abi.h (cp_pass_by_reference): Update declaration. (struct cp_abi_ops)<pass_by_reference>: Update. * gnu-v3-abi.c (gnuv3_pass_by_reference): Update. * infcall.c (call_function_by_hand_dummy): Update. * language.c (language_pass_by_reference): Update. (default_pass_by_reference): Update. * tic6x-tdep.c (tic6x_return_value): Update. Change-Id: Ib1c1f87f2490a5737c469f7b7185ddc7f6a164cb
Diffstat (limited to 'gdb/gnu-v3-abi.c')
-rw-r--r--gdb/gnu-v3-abi.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index d630ec07b11..35197e56334 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -1230,7 +1230,7 @@ gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
return real_stop_pc;
}
-/* Return nonzero if a type should be passed by reference.
+/* Return pass-by-reference information for the given TYPE.
The rule in the v3 ABI document comes from section 3.1.1. If the
type has a non-trivial copy constructor or destructor, then the
@@ -1248,22 +1248,33 @@ gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
We don't do anything with the constructors or destructors,
but we have to get the argument passing right anyway. */
-static int
+
+static struct language_pass_by_ref_info
gnuv3_pass_by_reference (struct type *type)
{
int fieldnum, fieldelem;
type = check_typedef (type);
+ /* Start with the default values. */
+ struct language_pass_by_ref_info info
+ = default_pass_by_reference (type);
+
+ /* FIXME: Currently, this implementation only fills in the
+ 'trivially-copyable' field to preserve GDB's existing behavior. */
+
/* We're only interested in things that can have methods. */
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION)
- return 0;
+ return info;
/* A dynamic class has a non-trivial copy constructor.
See c++98 section 12.8 Copying class objects [class.copy]. */
if (gnuv3_dynamic_class (type))
- return 1;
+ {
+ info.trivially_copyable = false;
+ return info;
+ }
for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
@@ -1280,7 +1291,10 @@ gnuv3_pass_by_reference (struct type *type)
/* If we've found a destructor, we must pass this by reference. */
if (name[0] == '~')
- return 1;
+ {
+ info.trivially_copyable = false;
+ return info;
+ }
/* If the mangled name of this method doesn't indicate that it
is a constructor, we're not interested.
@@ -1302,11 +1316,13 @@ gnuv3_pass_by_reference (struct type *type)
if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
{
- struct type *arg_target_type;
-
- arg_target_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
+ struct type *arg_target_type
+ = check_typedef (TYPE_TARGET_TYPE (arg_type));
if (class_types_same_p (arg_target_type, type))
- return 1;
+ {
+ info.trivially_copyable = false;
+ return info;
+ }
}
}
}
@@ -1319,11 +1335,18 @@ gnuv3_pass_by_reference (struct type *type)
about recursive loops here, since we are only looking at members
of complete class type. Also ignore any static members. */
for (fieldnum = 0; fieldnum < TYPE_NFIELDS (type); fieldnum++)
- if (! field_is_static (&TYPE_FIELD (type, fieldnum))
- && gnuv3_pass_by_reference (TYPE_FIELD_TYPE (type, fieldnum)))
- return 1;
+ if (!field_is_static (&TYPE_FIELD (type, fieldnum)))
+ {
+ struct language_pass_by_ref_info field_info
+ = gnuv3_pass_by_reference (TYPE_FIELD_TYPE (type, fieldnum));
+ if (!field_info.trivially_copyable)
+ {
+ info.trivially_copyable = false;
+ return info;
+ }
+ }
- return 0;
+ return info;
}
static void