📄 700-debian_cp-pass-by-reference.patch
字号:
Contributed by Jim Blandy <jimb@redhat.com> - Copyright 2001, 2002, 2003 Free Software Foundation, Inc.+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -419,6 +419,84 @@ gnuv3_baseclass_offset (struct type *typ return base_offset; } +/* Return nonzero if a type should be passed by reference.++ 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+ caller must make a copy (by calling the copy constructor if there+ is one or perform the copy itself otherwise), pass the address of+ the copy, and then destroy the temporary (if necessary).++ For return values with non-trivial copy constructors or+ destructors, space will be allocated in the caller, and a pointer+ will be passed as the first argument (preceding "this").++ We don't have a bulletproof mechanism for determining whether a+ constructor or destructor is trivial. For GCC and DWARF2 debug+ information, we can check the artificial flag.++ We don't do anything with the constructors or destructors yet,+ but we have to get the argument passing right anyway. */+static int+gnuv3_pass_by_reference (struct type *type)+{+ int fieldnum, fieldelem, basenum;++ CHECK_TYPEDEF (type);++ /* We're only interested in things that can have methods. */+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT+ && TYPE_CODE (type) != TYPE_CODE_CLASS+ && TYPE_CODE (type) != TYPE_CODE_UNION)+ return 0;++ for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)+ for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);+ fieldelem++)+ {+ struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, fieldnum);+ char *name = TYPE_FN_FIELDLIST_NAME (type, fieldnum);+ struct type *fieldtype = TYPE_FN_FIELD_TYPE (fn, fieldelem);++ /* If this function is marked as artificial, it is compiler-generated,+ and we assume it is trivial. */+ if (TYPE_FN_FIELD_ARTIFICIAL (fn, fieldelem))+ continue;++ /* If we've found a destructor, we must pass this by reference. */+ if (name[0] == '~')+ return 1;++ /* If the mangled name of this method doesn't indicate that it+ is a constructor, we're not interested.++ FIXME drow/2004-05-27: We could do this using the name of+ the method and the name of the class instead of dealing+ with the mangled name. We don't have a convenient function+ to strip off both leading scope qualifiers and trailing+ template arguments yet. */+ if (!is_constructor_name (TYPE_FN_FIELD_PHYSNAME (fn, fieldelem)))+ continue;++ /* If this method takes two arguments, and the second argument is+ a reference to this class, then it is a copy constructor. */+ if (TYPE_NFIELDS (fieldtype) == 2+ && TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF+ && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype, 1))) == type)+ return 1;+ }++ /* Even if all the constructors and destructors were artificial, one+ of them may have invoked a non-artificial constructor or+ destructor in a base class. If any base class needs to be passed+ by reference, so does this class. */+ for (basenum = 0; basenum < TYPE_N_BASECLASSES (type); basenum++)+ if (gnuv3_pass_by_reference (TYPE_BASECLASS (type, basenum)))+ return 1;++ return 0;+}+ static void init_gnuv3_ops (void) {@@ -434,6 +512,7 @@ init_gnuv3_ops (void) gnu_v3_abi_ops.rtti_type = gnuv3_rtti_type; gnu_v3_abi_ops.virtual_fn_field = gnuv3_virtual_fn_field; gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset;+ gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference; } extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */Index: gdb-6.3/gdb/hpacc-abi.c===================================================================--- gdb-6.3.orig/gdb/hpacc-abi.c 2003-06-08 14:27:13.000000000 -0400+++ gdb-6.3/gdb/hpacc-abi.c 2004-11-10 12:30:07.000000000 -0500@@ -3,7 +3,7 @@ Most of the real code is from HP, i've just fiddled it to fit in the C++ ABI abstraction framework. - Copyright 2001 Free Software Foundation, Inc.+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. Index: gdb-6.3/gdb/Makefile.in===================================================================--- gdb-6.3.orig/gdb/Makefile.in 2004-11-10 12:30:06.000000000 -0500+++ gdb-6.3/gdb/Makefile.in 2004-11-10 12:30:07.000000000 -0500@@ -2073,7 +2073,7 @@ ia64-tdep.o: ia64-tdep.c $(defs_h) $(inf infcall.o: infcall.c $(defs_h) $(breakpoint_h) $(target_h) $(regcache_h) \ $(inferior_h) $(gdb_assert_h) $(block_h) $(gdbcore_h) $(language_h) \ $(objfiles_h) $(gdbcmd_h) $(command_h) $(gdb_string_h) $(infcall_h) \- $(dummy_frame_h)+ $(dummy_frame_h) $(cp_abi_h) inf-child.o: inf-child.c $(defs_h) $(regcache_h) $(memattr_h) $(symtab_h) \ $(target_h) $(inferior_h) $(gdb_string_h) infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp===================================================================--- /dev/null 1970-01-01 00:00:00.000000000 +0000+++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp 2004-11-11 09:48:00.498518899 -0500@@ -0,0 +1,38 @@+# This testcase is part of GDB, the GNU debugger.++# Copyright 2004 Free Software Foundation, Inc.++# This program is free software; you can redistribute it and/or modify+# it under the terms of the GNU General Public License as published by+# the Free Software Foundation; either version 2 of the License, or+# (at your option) any later version.+#+# This program is distributed in the hope that it will be useful,+# but WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+# GNU General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program; if not, write to the Free Software+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++# Check that GDB can call C++ functions whose parameters have+# object type, but are passed by reference.++set testfile "pass-by-ref"+set srcfile ${testfile}.cc+set binfile ${objdir}/${subdir}/${testfile}+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {+ return -1+}++gdb_exit+gdb_start+gdb_reinitialize_dir $srcdir/$subdir+gdb_load ${binfile}++if ![runto_main] then {+ return -1+}++gdb_test "print foo (global_obj)" " = 3" "call function"Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc===================================================================--- /dev/null 1970-01-01 00:00:00.000000000 +0000+++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc 2004-11-11 09:44:17.815014667 -0500@@ -0,0 +1,57 @@+/* This testcase is part of GDB, the GNU debugger.++ Copyright 2004 Free Software Foundation, Inc.++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.+ + You should have received a copy of the GNU General Public License+ along with this program; if not, write to the Free Software+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,+ USA. */++class Obj {+public:+ Obj ();+ Obj (const Obj &);+ ~Obj ();+ int var[2];+};++int foo (Obj arg)+{+ return arg.var[0] + arg.var[1];+}++Obj::Obj ()+{+ var[0] = 1;+ var[1] = 2;+}++Obj::Obj (const Obj &obj)+{+ var[0] = obj.var[0];+ var[1] = obj.var[1];+}++Obj::~Obj ()+{++}++Obj global_obj;++int+main ()+{+ int bar = foo (global_obj);+ return bar;+}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -