yann@96
|
1 |
This patch needs to be submitted for the FSF. Also, there may be testcases
|
yann@96
|
2 |
already in the GDB testsuite (currently disabled) that it would probably fix.
|
yann@96
|
3 |
|
yann@96
|
4 |
Index: gdb-6.3/gdb/infcall.c
|
yann@96
|
5 |
===================================================================
|
yann@96
|
6 |
--- gdb-6.3.orig/gdb/infcall.c 2004-10-08 04:15:56.000000000 -0400
|
yann@96
|
7 |
+++ gdb-6.3/gdb/infcall.c 2004-11-10 12:30:07.000000000 -0500
|
yann@96
|
8 |
@@ -36,6 +36,7 @@
|
yann@96
|
9 |
#include "gdb_string.h"
|
yann@96
|
10 |
#include "infcall.h"
|
yann@96
|
11 |
#include "dummy-frame.h"
|
yann@96
|
12 |
+#include "cp-abi.h"
|
yann@96
|
13 |
|
yann@96
|
14 |
/* NOTE: cagney/2003-04-16: What's the future of this code?
|
yann@96
|
15 |
|
yann@96
|
16 |
@@ -297,8 +298,8 @@ call_function_by_hand (struct value *fun
|
yann@96
|
17 |
{
|
yann@96
|
18 |
CORE_ADDR sp;
|
yann@96
|
19 |
CORE_ADDR dummy_addr;
|
yann@96
|
20 |
- struct type *value_type;
|
yann@96
|
21 |
- unsigned char struct_return;
|
yann@96
|
22 |
+ struct type *value_type, *target_value_type;
|
yann@96
|
23 |
+ unsigned char struct_return = 0, cp_struct_return = 0;
|
yann@96
|
24 |
CORE_ADDR struct_addr = 0;
|
yann@96
|
25 |
struct regcache *retbuf;
|
yann@96
|
26 |
struct cleanup *retbuf_cleanup;
|
yann@96
|
27 |
@@ -312,6 +313,7 @@ call_function_by_hand (struct value *fun
|
yann@96
|
28 |
struct regcache *caller_regcache;
|
yann@96
|
29 |
struct cleanup *caller_regcache_cleanup;
|
yann@96
|
30 |
struct frame_id dummy_id;
|
yann@96
|
31 |
+ struct cleanup *args_cleanup;
|
yann@96
|
32 |
|
yann@96
|
33 |
if (!target_has_execution)
|
yann@96
|
34 |
noprocess ();
|
yann@96
|
35 |
@@ -410,10 +412,31 @@ call_function_by_hand (struct value *fun
|
yann@96
|
36 |
using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
|
yann@96
|
37 |
}
|
yann@96
|
38 |
|
yann@96
|
39 |
- /* Are we returning a value using a structure return or a normal
|
yann@96
|
40 |
- value return? */
|
yann@96
|
41 |
+ /* Are we returning a value using a structure return (passing a
|
yann@96
|
42 |
+ hidden argument pointing to storage) or a normal value return?
|
yann@96
|
43 |
+ There are two cases: C++ ABI mandated structure return and
|
yann@96
|
44 |
+ target ABI structure return. The variable STRUCT_RETURN only
|
yann@96
|
45 |
+ describes the latter. The C++ version is handled by passing
|
yann@96
|
46 |
+ the return location as the first parameter to the function,
|
yann@96
|
47 |
+ even preceding "this". This is different from the target
|
yann@96
|
48 |
+ ABI version, which is target-specific; for instance, on ia64
|
yann@96
|
49 |
+ the first argument is passed in out0 but the hidden structure
|
yann@96
|
50 |
+ return pointer would normally be passed in r8. */
|
yann@96
|
51 |
|
yann@96
|
52 |
- struct_return = using_struct_return (value_type, using_gcc);
|
yann@96
|
53 |
+ if (current_language->la_language == language_cplus
|
yann@96
|
54 |
+ && cp_pass_by_reference (value_type))
|
yann@96
|
55 |
+ {
|
yann@96
|
56 |
+ cp_struct_return = 1;
|
yann@96
|
57 |
+
|
yann@96
|
58 |
+ /* Tell the target specific argument pushing routine not to
|
yann@96
|
59 |
+ expect a value. */
|
yann@96
|
60 |
+ target_value_type = builtin_type_void;
|
yann@96
|
61 |
+ }
|
yann@96
|
62 |
+ else
|
yann@96
|
63 |
+ {
|
yann@96
|
64 |
+ struct_return = using_struct_return (value_type, using_gcc);
|
yann@96
|
65 |
+ target_value_type = value_type;
|
yann@96
|
66 |
+ }
|
yann@96
|
67 |
|
yann@96
|
68 |
/* Determine the location of the breakpoint (and possibly other
|
yann@96
|
69 |
stuff) that the called function will return to. The SPARC, for a
|
yann@96
|
70 |
@@ -432,7 +455,7 @@ call_function_by_hand (struct value *fun
|
yann@96
|
71 |
if (INNER_THAN (1, 2))
|
yann@96
|
72 |
{
|
yann@96
|
73 |
sp = push_dummy_code (current_gdbarch, sp, funaddr,
|
yann@96
|
74 |
- using_gcc, args, nargs, value_type,
|
yann@96
|
75 |
+ using_gcc, args, nargs, target_value_type,
|
yann@96
|
76 |
&real_pc, &bp_addr);
|
yann@96
|
77 |
dummy_addr = sp;
|
yann@96
|
78 |
}
|
yann@96
|
79 |
@@ -440,7 +463,7 @@ call_function_by_hand (struct value *fun
|
yann@96
|
80 |
{
|
yann@96
|
81 |
dummy_addr = sp;
|
yann@96
|
82 |
sp = push_dummy_code (current_gdbarch, sp, funaddr,
|
yann@96
|
83 |
- using_gcc, args, nargs, value_type,
|
yann@96
|
84 |
+ using_gcc, args, nargs, target_value_type,
|
yann@96
|
85 |
&real_pc, &bp_addr);
|
yann@96
|
86 |
}
|
yann@96
|
87 |
break;
|
yann@96
|
88 |
@@ -507,9 +530,15 @@ call_function_by_hand (struct value *fun
|
yann@96
|
89 |
param_type = TYPE_FIELD_TYPE (ftype, i);
|
yann@96
|
90 |
else
|
yann@96
|
91 |
param_type = NULL;
|
yann@96
|
92 |
-
|
yann@96
|
93 |
+
|
yann@96
|
94 |
args[i] = value_arg_coerce (args[i], param_type, prototyped);
|
yann@96
|
95 |
|
yann@96
|
96 |
+ /* FIXME: Is current_language the right language? */
|
yann@96
|
97 |
+ if (current_language->la_language == language_cplus
|
yann@96
|
98 |
+ && param_type != NULL
|
yann@96
|
99 |
+ && cp_pass_by_reference (param_type))
|
yann@96
|
100 |
+ args[i] = value_addr (args[i]);
|
yann@96
|
101 |
+
|
yann@96
|
102 |
/* elz: this code is to handle the case in which the function
|
yann@96
|
103 |
to be called has a pointer to function as parameter and the
|
yann@96
|
104 |
corresponding actual argument is the address of a function
|
yann@96
|
105 |
@@ -607,7 +636,7 @@ You must use a pointer to function type
|
yann@96
|
106 |
stack, if necessary. Make certain that the value is correctly
|
yann@96
|
107 |
aligned. */
|
yann@96
|
108 |
|
yann@96
|
109 |
- if (struct_return)
|
yann@96
|
110 |
+ if (struct_return || cp_struct_return)
|
yann@96
|
111 |
{
|
yann@96
|
112 |
int len = TYPE_LENGTH (value_type);
|
yann@96
|
113 |
if (INNER_THAN (1, 2))
|
yann@96
|
114 |
@@ -632,6 +661,22 @@ You must use a pointer to function type
|
yann@96
|
115 |
}
|
yann@96
|
116 |
}
|
yann@96
|
117 |
|
yann@96
|
118 |
+ if (cp_struct_return)
|
yann@96
|
119 |
+ {
|
yann@96
|
120 |
+ struct value **new_args;
|
yann@96
|
121 |
+
|
yann@96
|
122 |
+ /* Add the new argument to the front of the argument list. */
|
yann@96
|
123 |
+ new_args = xmalloc (sizeof (struct value *) * (nargs + 1));
|
yann@96
|
124 |
+ new_args[0] = value_from_pointer (lookup_pointer_type (value_type),
|
yann@96
|
125 |
+ struct_addr);
|
yann@96
|
126 |
+ memcpy (&new_args[1], &args[0], sizeof (struct value *) * nargs);
|
yann@96
|
127 |
+ args = new_args;
|
yann@96
|
128 |
+ nargs++;
|
yann@96
|
129 |
+ args_cleanup = make_cleanup (xfree, args);
|
yann@96
|
130 |
+ }
|
yann@96
|
131 |
+ else
|
yann@96
|
132 |
+ args_cleanup = make_cleanup (null_cleanup, NULL);
|
yann@96
|
133 |
+
|
yann@96
|
134 |
/* Create the dummy stack frame. Pass in the call dummy address as,
|
yann@96
|
135 |
presumably, the ABI code knows where, in the call dummy, the
|
yann@96
|
136 |
return address should be pointed. */
|
yann@96
|
137 |
@@ -649,6 +694,8 @@ You must use a pointer to function type
|
yann@96
|
138 |
else
|
yann@96
|
139 |
error ("This target does not support function calls");
|
yann@96
|
140 |
|
yann@96
|
141 |
+ do_cleanups (args_cleanup);
|
yann@96
|
142 |
+
|
yann@96
|
143 |
/* Set up a frame ID for the dummy frame so we can pass it to
|
yann@96
|
144 |
set_momentary_breakpoint. We need to give the breakpoint a frame
|
yann@96
|
145 |
ID so that the breakpoint code can correctly re-identify the
|
yann@96
|
146 |
@@ -839,11 +886,7 @@ the function call).", name);
|
yann@96
|
147 |
/* Figure out the value returned by the function, return that. */
|
yann@96
|
148 |
{
|
yann@96
|
149 |
struct value *retval;
|
yann@96
|
150 |
- if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
|
yann@96
|
151 |
- /* If the function returns void, don't bother fetching the
|
yann@96
|
152 |
- return value. */
|
yann@96
|
153 |
- retval = allocate_value (value_type);
|
yann@96
|
154 |
- else if (struct_return)
|
yann@96
|
155 |
+ if (struct_return || cp_struct_return)
|
yann@96
|
156 |
/* NOTE: cagney/2003-09-27: This assumes that PUSH_DUMMY_CALL
|
yann@96
|
157 |
has correctly stored STRUCT_ADDR in the target. In the past
|
yann@96
|
158 |
that hasn't been the case, the old MIPS PUSH_ARGUMENTS
|
yann@96
|
159 |
@@ -853,6 +896,10 @@ the function call).", name);
|
yann@96
|
160 |
"struct return convention", check that PUSH_DUMMY_CALL isn't
|
yann@96
|
161 |
playing tricks. */
|
yann@96
|
162 |
retval = value_at (value_type, struct_addr, NULL);
|
yann@96
|
163 |
+ else if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
|
yann@96
|
164 |
+ /* If the function returns void, don't bother fetching the
|
yann@96
|
165 |
+ return value. */
|
yann@96
|
166 |
+ retval = allocate_value (value_type);
|
yann@96
|
167 |
else
|
yann@96
|
168 |
{
|
yann@96
|
169 |
/* This code only handles "register convention". */
|
yann@96
|
170 |
Index: gdb-6.3/gdb/cp-abi.h
|
yann@96
|
171 |
===================================================================
|
yann@96
|
172 |
--- gdb-6.3.orig/gdb/cp-abi.h 2003-04-12 13:41:25.000000000 -0400
|
yann@96
|
173 |
+++ gdb-6.3/gdb/cp-abi.h 2004-11-10 12:30:07.000000000 -0500
|
yann@96
|
174 |
@@ -1,7 +1,7 @@
|
yann@96
|
175 |
/* Abstraction of various C++ ABI's we support, and the info we need
|
yann@96
|
176 |
to get from them.
|
yann@96
|
177 |
Contributed by Daniel Berlin <dberlin@redhat.com>
|
yann@96
|
178 |
- Copyright 2001 Free Software Foundation, Inc.
|
yann@96
|
179 |
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
yann@96
|
180 |
|
yann@96
|
181 |
This file is part of GDB.
|
yann@96
|
182 |
|
yann@96
|
183 |
@@ -145,6 +145,10 @@ extern struct type *value_rtti_type (str
|
yann@96
|
184 |
extern int baseclass_offset (struct type *type, int index, char *valaddr,
|
yann@96
|
185 |
CORE_ADDR address);
|
yann@96
|
186 |
|
yann@96
|
187 |
+/* Return non-zero if an argument of type TYPE should be passed by reference
|
yann@96
|
188 |
+ instead of value. */
|
yann@96
|
189 |
+extern int cp_pass_by_reference (struct type *type);
|
yann@96
|
190 |
+
|
yann@96
|
191 |
struct cp_abi_ops
|
yann@96
|
192 |
{
|
yann@96
|
193 |
const char *shortname;
|
yann@96
|
194 |
@@ -162,6 +166,7 @@ struct cp_abi_ops
|
yann@96
|
195 |
int *using_enc);
|
yann@96
|
196 |
int (*baseclass_offset) (struct type *type, int index, char *valaddr,
|
yann@96
|
197 |
CORE_ADDR address);
|
yann@96
|
198 |
+ int (*pass_by_reference) (struct type *type);
|
yann@96
|
199 |
};
|
yann@96
|
200 |
|
yann@96
|
201 |
|
yann@96
|
202 |
Index: gdb-6.3/gdb/cp-abi.c
|
yann@96
|
203 |
===================================================================
|
yann@96
|
204 |
--- gdb-6.3.orig/gdb/cp-abi.c 2003-11-26 17:04:00.000000000 -0500
|
yann@96
|
205 |
+++ gdb-6.3/gdb/cp-abi.c 2004-11-10 12:30:07.000000000 -0500
|
yann@96
|
206 |
@@ -1,5 +1,5 @@
|
yann@96
|
207 |
/* Generic code for supporting multiple C++ ABI's
|
yann@96
|
208 |
- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
|
yann@96
|
209 |
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
yann@96
|
210 |
|
yann@96
|
211 |
This file is part of GDB.
|
yann@96
|
212 |
|
yann@96
|
213 |
@@ -94,6 +94,14 @@ value_rtti_type (struct value *v, int *f
|
yann@96
|
214 |
return (*current_cp_abi.rtti_type) (v, full, top, using_enc);
|
yann@96
|
215 |
}
|
yann@96
|
216 |
|
yann@96
|
217 |
+int
|
yann@96
|
218 |
+cp_pass_by_reference (struct type *type)
|
yann@96
|
219 |
+{
|
yann@96
|
220 |
+ if ((current_cp_abi.pass_by_reference) == NULL)
|
yann@96
|
221 |
+ return 0;
|
yann@96
|
222 |
+ return (*current_cp_abi.pass_by_reference) (type);
|
yann@96
|
223 |
+}
|
yann@96
|
224 |
+
|
yann@96
|
225 |
/* Set the current C++ ABI to SHORT_NAME. */
|
yann@96
|
226 |
|
yann@96
|
227 |
static int
|
yann@96
|
228 |
Index: gdb-6.3/gdb/gnu-v3-abi.c
|
yann@96
|
229 |
===================================================================
|
yann@96
|
230 |
--- gdb-6.3.orig/gdb/gnu-v3-abi.c 2004-03-15 15:38:08.000000000 -0500
|
yann@96
|
231 |
+++ gdb-6.3/gdb/gnu-v3-abi.c 2004-11-10 12:30:07.000000000 -0500
|
yann@96
|
232 |
@@ -1,7 +1,7 @@
|
yann@96
|
233 |
/* Abstraction of GNU v3 abi.
|
yann@96
|
234 |
Contributed by Jim Blandy <jimb@redhat.com>
|
yann@96
|
235 |
|
yann@96
|
236 |
- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
|
yann@96
|
237 |
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
yann@96
|
238 |
|
yann@96
|
239 |
This file is part of GDB.
|
yann@96
|
240 |
|
yann@96
|
241 |
@@ -419,6 +419,84 @@ gnuv3_baseclass_offset (struct type *typ
|
yann@96
|
242 |
return base_offset;
|
yann@96
|
243 |
}
|
yann@96
|
244 |
|
yann@96
|
245 |
+/* Return nonzero if a type should be passed by reference.
|
yann@96
|
246 |
+
|
yann@96
|
247 |
+ The rule in the v3 ABI document comes from section 3.1.1. If the
|
yann@96
|
248 |
+ type has a non-trivial copy constructor or destructor, then the
|
yann@96
|
249 |
+ caller must make a copy (by calling the copy constructor if there
|
yann@96
|
250 |
+ is one or perform the copy itself otherwise), pass the address of
|
yann@96
|
251 |
+ the copy, and then destroy the temporary (if necessary).
|
yann@96
|
252 |
+
|
yann@96
|
253 |
+ For return values with non-trivial copy constructors or
|
yann@96
|
254 |
+ destructors, space will be allocated in the caller, and a pointer
|
yann@96
|
255 |
+ will be passed as the first argument (preceding "this").
|
yann@96
|
256 |
+
|
yann@96
|
257 |
+ We don't have a bulletproof mechanism for determining whether a
|
yann@96
|
258 |
+ constructor or destructor is trivial. For GCC and DWARF2 debug
|
yann@96
|
259 |
+ information, we can check the artificial flag.
|
yann@96
|
260 |
+
|
yann@96
|
261 |
+ We don't do anything with the constructors or destructors yet,
|
yann@96
|
262 |
+ but we have to get the argument passing right anyway. */
|
yann@96
|
263 |
+static int
|
yann@96
|
264 |
+gnuv3_pass_by_reference (struct type *type)
|
yann@96
|
265 |
+{
|
yann@96
|
266 |
+ int fieldnum, fieldelem, basenum;
|
yann@96
|
267 |
+
|
yann@96
|
268 |
+ CHECK_TYPEDEF (type);
|
yann@96
|
269 |
+
|
yann@96
|
270 |
+ /* We're only interested in things that can have methods. */
|
yann@96
|
271 |
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
yann@96
|
272 |
+ && TYPE_CODE (type) != TYPE_CODE_CLASS
|
yann@96
|
273 |
+ && TYPE_CODE (type) != TYPE_CODE_UNION)
|
yann@96
|
274 |
+ return 0;
|
yann@96
|
275 |
+
|
yann@96
|
276 |
+ for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++)
|
yann@96
|
277 |
+ for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum);
|
yann@96
|
278 |
+ fieldelem++)
|
yann@96
|
279 |
+ {
|
yann@96
|
280 |
+ struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, fieldnum);
|
yann@96
|
281 |
+ char *name = TYPE_FN_FIELDLIST_NAME (type, fieldnum);
|
yann@96
|
282 |
+ struct type *fieldtype = TYPE_FN_FIELD_TYPE (fn, fieldelem);
|
yann@96
|
283 |
+
|
yann@96
|
284 |
+ /* If this function is marked as artificial, it is compiler-generated,
|
yann@96
|
285 |
+ and we assume it is trivial. */
|
yann@96
|
286 |
+ if (TYPE_FN_FIELD_ARTIFICIAL (fn, fieldelem))
|
yann@96
|
287 |
+ continue;
|
yann@96
|
288 |
+
|
yann@96
|
289 |
+ /* If we've found a destructor, we must pass this by reference. */
|
yann@96
|
290 |
+ if (name[0] == '~')
|
yann@96
|
291 |
+ return 1;
|
yann@96
|
292 |
+
|
yann@96
|
293 |
+ /* If the mangled name of this method doesn't indicate that it
|
yann@96
|
294 |
+ is a constructor, we're not interested.
|
yann@96
|
295 |
+
|
yann@96
|
296 |
+ FIXME drow/2004-05-27: We could do this using the name of
|
yann@96
|
297 |
+ the method and the name of the class instead of dealing
|
yann@96
|
298 |
+ with the mangled name. We don't have a convenient function
|
yann@96
|
299 |
+ to strip off both leading scope qualifiers and trailing
|
yann@96
|
300 |
+ template arguments yet. */
|
yann@96
|
301 |
+ if (!is_constructor_name (TYPE_FN_FIELD_PHYSNAME (fn, fieldelem)))
|
yann@96
|
302 |
+ continue;
|
yann@96
|
303 |
+
|
yann@96
|
304 |
+ /* If this method takes two arguments, and the second argument is
|
yann@96
|
305 |
+ a reference to this class, then it is a copy constructor. */
|
yann@96
|
306 |
+ if (TYPE_NFIELDS (fieldtype) == 2
|
yann@96
|
307 |
+ && TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF
|
yann@96
|
308 |
+ && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype, 1))) == type)
|
yann@96
|
309 |
+ return 1;
|
yann@96
|
310 |
+ }
|
yann@96
|
311 |
+
|
yann@96
|
312 |
+ /* Even if all the constructors and destructors were artificial, one
|
yann@96
|
313 |
+ of them may have invoked a non-artificial constructor or
|
yann@96
|
314 |
+ destructor in a base class. If any base class needs to be passed
|
yann@96
|
315 |
+ by reference, so does this class. */
|
yann@96
|
316 |
+ for (basenum = 0; basenum < TYPE_N_BASECLASSES (type); basenum++)
|
yann@96
|
317 |
+ if (gnuv3_pass_by_reference (TYPE_BASECLASS (type, basenum)))
|
yann@96
|
318 |
+ return 1;
|
yann@96
|
319 |
+
|
yann@96
|
320 |
+ return 0;
|
yann@96
|
321 |
+}
|
yann@96
|
322 |
+
|
yann@96
|
323 |
static void
|
yann@96
|
324 |
init_gnuv3_ops (void)
|
yann@96
|
325 |
{
|
yann@96
|
326 |
@@ -434,6 +512,7 @@ init_gnuv3_ops (void)
|
yann@96
|
327 |
gnu_v3_abi_ops.rtti_type = gnuv3_rtti_type;
|
yann@96
|
328 |
gnu_v3_abi_ops.virtual_fn_field = gnuv3_virtual_fn_field;
|
yann@96
|
329 |
gnu_v3_abi_ops.baseclass_offset = gnuv3_baseclass_offset;
|
yann@96
|
330 |
+ gnu_v3_abi_ops.pass_by_reference = gnuv3_pass_by_reference;
|
yann@96
|
331 |
}
|
yann@96
|
332 |
|
yann@96
|
333 |
extern initialize_file_ftype _initialize_gnu_v3_abi; /* -Wmissing-prototypes */
|
yann@96
|
334 |
Index: gdb-6.3/gdb/hpacc-abi.c
|
yann@96
|
335 |
===================================================================
|
yann@96
|
336 |
--- gdb-6.3.orig/gdb/hpacc-abi.c 2003-06-08 14:27:13.000000000 -0400
|
yann@96
|
337 |
+++ gdb-6.3/gdb/hpacc-abi.c 2004-11-10 12:30:07.000000000 -0500
|
yann@96
|
338 |
@@ -3,7 +3,7 @@
|
yann@96
|
339 |
Most of the real code is from HP, i've just fiddled it to fit in
|
yann@96
|
340 |
the C++ ABI abstraction framework.
|
yann@96
|
341 |
|
yann@96
|
342 |
- Copyright 2001 Free Software Foundation, Inc.
|
yann@96
|
343 |
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
|
yann@96
|
344 |
|
yann@96
|
345 |
This file is part of GDB.
|
yann@96
|
346 |
|
yann@96
|
347 |
Index: gdb-6.3/gdb/Makefile.in
|
yann@96
|
348 |
===================================================================
|
yann@96
|
349 |
--- gdb-6.3.orig/gdb/Makefile.in 2004-11-10 12:30:06.000000000 -0500
|
yann@96
|
350 |
+++ gdb-6.3/gdb/Makefile.in 2004-11-10 12:30:07.000000000 -0500
|
yann@96
|
351 |
@@ -2073,7 +2073,7 @@ ia64-tdep.o: ia64-tdep.c $(defs_h) $(inf
|
yann@96
|
352 |
infcall.o: infcall.c $(defs_h) $(breakpoint_h) $(target_h) $(regcache_h) \
|
yann@96
|
353 |
$(inferior_h) $(gdb_assert_h) $(block_h) $(gdbcore_h) $(language_h) \
|
yann@96
|
354 |
$(objfiles_h) $(gdbcmd_h) $(command_h) $(gdb_string_h) $(infcall_h) \
|
yann@96
|
355 |
- $(dummy_frame_h)
|
yann@96
|
356 |
+ $(dummy_frame_h) $(cp_abi_h)
|
yann@96
|
357 |
inf-child.o: inf-child.c $(defs_h) $(regcache_h) $(memattr_h) $(symtab_h) \
|
yann@96
|
358 |
$(target_h) $(inferior_h) $(gdb_string_h)
|
yann@96
|
359 |
infcmd.o: infcmd.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
yann@96
|
360 |
Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp
|
yann@96
|
361 |
===================================================================
|
yann@96
|
362 |
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
yann@96
|
363 |
+++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.exp 2004-11-11 09:48:00.498518899 -0500
|
yann@96
|
364 |
@@ -0,0 +1,38 @@
|
yann@96
|
365 |
+# This testcase is part of GDB, the GNU debugger.
|
yann@96
|
366 |
+
|
yann@96
|
367 |
+# Copyright 2004 Free Software Foundation, Inc.
|
yann@96
|
368 |
+
|
yann@96
|
369 |
+# This program is free software; you can redistribute it and/or modify
|
yann@96
|
370 |
+# it under the terms of the GNU General Public License as published by
|
yann@96
|
371 |
+# the Free Software Foundation; either version 2 of the License, or
|
yann@96
|
372 |
+# (at your option) any later version.
|
yann@96
|
373 |
+#
|
yann@96
|
374 |
+# This program is distributed in the hope that it will be useful,
|
yann@96
|
375 |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yann@96
|
376 |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
yann@96
|
377 |
+# GNU General Public License for more details.
|
yann@96
|
378 |
+#
|
yann@96
|
379 |
+# You should have received a copy of the GNU General Public License
|
yann@96
|
380 |
+# along with this program; if not, write to the Free Software
|
yann@96
|
381 |
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
yann@96
|
382 |
+
|
yann@96
|
383 |
+# Check that GDB can call C++ functions whose parameters have
|
yann@96
|
384 |
+# object type, but are passed by reference.
|
yann@96
|
385 |
+
|
yann@96
|
386 |
+set testfile "pass-by-ref"
|
yann@96
|
387 |
+set srcfile ${testfile}.cc
|
yann@96
|
388 |
+set binfile ${objdir}/${subdir}/${testfile}
|
yann@96
|
389 |
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
|
yann@96
|
390 |
+ return -1
|
yann@96
|
391 |
+}
|
yann@96
|
392 |
+
|
yann@96
|
393 |
+gdb_exit
|
yann@96
|
394 |
+gdb_start
|
yann@96
|
395 |
+gdb_reinitialize_dir $srcdir/$subdir
|
yann@96
|
396 |
+gdb_load ${binfile}
|
yann@96
|
397 |
+
|
yann@96
|
398 |
+if ![runto_main] then {
|
yann@96
|
399 |
+ return -1
|
yann@96
|
400 |
+}
|
yann@96
|
401 |
+
|
yann@96
|
402 |
+gdb_test "print foo (global_obj)" " = 3" "call function"
|
yann@96
|
403 |
Index: gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc
|
yann@96
|
404 |
===================================================================
|
yann@96
|
405 |
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
yann@96
|
406 |
+++ gdb-6.3/gdb/testsuite/gdb.cp/pass-by-ref.cc 2004-11-11 09:44:17.815014667 -0500
|
yann@96
|
407 |
@@ -0,0 +1,57 @@
|
yann@96
|
408 |
+/* This testcase is part of GDB, the GNU debugger.
|
yann@96
|
409 |
+
|
yann@96
|
410 |
+ Copyright 2004 Free Software Foundation, Inc.
|
yann@96
|
411 |
+
|
yann@96
|
412 |
+ This program is free software; you can redistribute it and/or modify
|
yann@96
|
413 |
+ it under the terms of the GNU General Public License as published by
|
yann@96
|
414 |
+ the Free Software Foundation; either version 2 of the License, or
|
yann@96
|
415 |
+ (at your option) any later version.
|
yann@96
|
416 |
+
|
yann@96
|
417 |
+ This program is distributed in the hope that it will be useful,
|
yann@96
|
418 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yann@96
|
419 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
yann@96
|
420 |
+ GNU General Public License for more details.
|
yann@96
|
421 |
+
|
yann@96
|
422 |
+ You should have received a copy of the GNU General Public License
|
yann@96
|
423 |
+ along with this program; if not, write to the Free Software
|
yann@96
|
424 |
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
yann@96
|
425 |
+ USA. */
|
yann@96
|
426 |
+
|
yann@96
|
427 |
+class Obj {
|
yann@96
|
428 |
+public:
|
yann@96
|
429 |
+ Obj ();
|
yann@96
|
430 |
+ Obj (const Obj &);
|
yann@96
|
431 |
+ ~Obj ();
|
yann@96
|
432 |
+ int var[2];
|
yann@96
|
433 |
+};
|
yann@96
|
434 |
+
|
yann@96
|
435 |
+int foo (Obj arg)
|
yann@96
|
436 |
+{
|
yann@96
|
437 |
+ return arg.var[0] + arg.var[1];
|
yann@96
|
438 |
+}
|
yann@96
|
439 |
+
|
yann@96
|
440 |
+Obj::Obj ()
|
yann@96
|
441 |
+{
|
yann@96
|
442 |
+ var[0] = 1;
|
yann@96
|
443 |
+ var[1] = 2;
|
yann@96
|
444 |
+}
|
yann@96
|
445 |
+
|
yann@96
|
446 |
+Obj::Obj (const Obj &obj)
|
yann@96
|
447 |
+{
|
yann@96
|
448 |
+ var[0] = obj.var[0];
|
yann@96
|
449 |
+ var[1] = obj.var[1];
|
yann@96
|
450 |
+}
|
yann@96
|
451 |
+
|
yann@96
|
452 |
+Obj::~Obj ()
|
yann@96
|
453 |
+{
|
yann@96
|
454 |
+
|
yann@96
|
455 |
+}
|
yann@96
|
456 |
+
|
yann@96
|
457 |
+Obj global_obj;
|
yann@96
|
458 |
+
|
yann@96
|
459 |
+int
|
yann@96
|
460 |
+main ()
|
yann@96
|
461 |
+{
|
yann@96
|
462 |
+ int bar = foo (global_obj);
|
yann@96
|
463 |
+ return bar;
|
yann@96
|
464 |
+}
|