From: Siva Chandra <sivachandra@google.com>
To: Tom Tromey <tromey@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [RFC] Extend existing support for evaluating expressions using overloaded operators
Date: Mon, 18 Jun 2012 07:30:00 -0000 [thread overview]
Message-ID: <CAGyQ6gytckT+qW1UhcWq0moDO=qwrCby0KSx3zo2Ye-3uCN4AQ@mail.gmail.com> (raw)
In-Reply-To: <CAGyQ6gzuOgut-sONmqhPScBGqsucVJC=1dkMCtJY7jwq-Kviqg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1745 bytes --]
Siva> I will stage the clean up and extension in multiple patches. Also,
Siva> that way I will get to discuss in smaller pieces as to why the code is
Siva> the way it is.
I have submitted
http://sourceware.org/ml/gdb-patches/2012-06/msg00245.html as the
first cleanup patch. Attached now is a patch which extends the
overloaded operator support. It contains a minor refactoring so that
the overloaded operator support can be extended to cases where the
first operand of a binary operation is a non-struct/non-union. Note
that this patch does not yet extend the support into Python API.
2012-06-18 Siva Chandra Reddy <sivachandra@google.com>
Extend existing support for evaluating expressions using
overloaded operators.
* gdbtypes.c (is_compound_type): New function to test if a type
is a struct or union.
(type_can_have_methods): New function to check if a type can
have methods defined on it.
* gdbtypes.h (is_compound_type, type_can_have_methods): Declare.
* valarith.c (value_user_defined_cpp_op): Make different calls
to 'find_overload_match' based on the type of the first
argument.
(value_x_binop): Extend to handle binary operations which have
either or both operands of a compound value. Pass operands as is
to value_user_defined_op.
(value_x_unop): Pass operand as is to value_user_defined_op.
(binop_types_user_defined_p): Use is_compound_type to include
unions.
testsuite/
* gdb.cp/operator.cc: Add test cases to test overloaded
binary operator evaluation.
* gdb.cp/operator.exp: Add tests to test overloaded binary
operator evaluation.
Thanks,
Siva Chandra
[-- Attachment #2: oprovld_patch_v3.txt --]
[-- Type: text/plain, Size: 7712 bytes --]
Index: gdbtypes.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.c,v
retrieving revision 1.230
diff -u -p -r1.230 gdbtypes.c
--- gdbtypes.c 23 May 2012 23:45:09 -0000 1.230
+++ gdbtypes.c 18 Jun 2012 06:56:42 -0000
@@ -2006,6 +2006,48 @@ is_scalar_type (struct type *type)
}
}
+/* Return true if TYPE is a struct or union. */
+
+int
+is_compound_type (struct type *type)
+{
+ enum type_code type_code;
+
+ CHECK_TYPEDEF (type);
+
+ type_code = TYPE_CODE (type);
+ if (type_code == TYPE_CODE_STRUCT || type_code == TYPE_CODE_UNION)
+ return 1;
+ else
+ return 0;
+}
+
+/* Return true is TYPE is a type which can have methods defined on it.
+ That is, if TYPE is a struct or a union, or is a pointer/reference to a
+ struct or union, then it returns true. */
+
+int
+type_can_have_methods (struct type *type)
+{
+ if (is_compound_type (type))
+ return 1;
+ else
+ {
+ enum type_code type_code;
+
+ CHECK_TYPEDEF (type);
+ type_code = TYPE_CODE (type);
+
+ if (type_code == TYPE_CODE_PTR || type_code == TYPE_CODE_REF)
+ {
+ type = TYPE_TARGET_TYPE (type);
+ return type_can_have_methods (type);
+ }
+ }
+
+ return 0;
+}
+
/* Return true if T is scalar, or a composite type which in practice has
the memory layout of a scalar type. E.g., an array or struct with only
one scalar element inside it, or a union with only scalar elements. */
Index: gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.167
diff -u -p -r1.167 gdbtypes.h
--- gdbtypes.h 17 Jun 2012 19:53:52 -0000 1.167
+++ gdbtypes.h 18 Jun 2012 06:56:43 -0000
@@ -1629,6 +1629,10 @@ extern int is_integral_type (struct type
extern int is_scalar_type_recursive (struct type *);
+extern int is_compound_type (struct type *);
+
+extern int type_can_have_methods (struct type *);
+
extern void maintenance_print_type (char *, int);
extern htab_t create_copied_types_hash (struct objfile *objfile);
Index: valarith.c
===================================================================
RCS file: /cvs/src/src/gdb/valarith.c,v
retrieving revision 1.104
diff -u -p -r1.104 valarith.c
--- valarith.c 9 Jun 2012 07:36:43 -0000 1.104
+++ valarith.c 18 Jun 2012 06:56:43 -0000
@@ -283,8 +283,7 @@ binop_types_user_defined_p (enum exp_opc
if (TYPE_CODE (type2) == TYPE_CODE_REF)
type2 = check_typedef (TYPE_TARGET_TYPE (type2));
- return (TYPE_CODE (type1) == TYPE_CODE_STRUCT
- || TYPE_CODE (type2) == TYPE_CODE_STRUCT);
+ return (is_compound_type (type1) || is_compound_type (type2));
}
/* Check to see if either argument is a structure, or a reference to
@@ -335,22 +334,38 @@ value_user_defined_cpp_op (struct value
struct symbol *symp = NULL;
struct value *valp = NULL;
- find_overload_match (args, nargs, operator, BOTH /* could be method */,
- 0 /* strict match */, &args[0], /* objp */
- NULL /* pass NULL symbol since symbol is unknown */,
- &valp, &symp, static_memfuncp, 0);
+ if (type_can_have_methods (value_type (args[0])))
+ {
+ struct value **argvec;
+ int i;
+
+ argvec = (struct value **) alloca (sizeof (struct value *) * nargs);
+ argvec[0] = value_addr (args[0]);
+ for (i = 1; i < nargs; i++)
+ argvec[i] = args[i];
+
+ find_overload_match (argvec, nargs, operator, BOTH /* could be method */,
+ 0 /* strict match */, &argvec[0], /* objp */
+ NULL /* pass NULL symbol since symbol is unknown */,
+ &valp, &symp, static_memfuncp, 0);
- if (valp)
- return valp;
- if (symp)
- {
- /* This is a non member function and does not
- expect a reference as its first argument
- rather the explicit structure. */
- args[0] = value_ind (args[0]);
- return value_of_variable (symp, 0);
+ if (valp)
+ {
+ /* A method match was found. In such a case, the first argument
+ should actually be a pointer to 'this' (of the first arg). */
+ args[0] = argvec[0];
+ return valp;
+ }
}
+ else
+ find_overload_match (args, nargs, operator, NON_METHOD,
+ 0 /* strict match */, NULL, /* objp */
+ NULL /* pass NULL symbol since symbol is unknown */,
+ &valp, &symp, static_memfuncp, 0);
+
+ if (symp)
+ return value_of_variable (symp, 0);
error (_("Could not find %s."), operator);
}
@@ -397,11 +412,12 @@ value_x_binop (struct value *arg1, struc
/* now we know that what we have to do is construct our
arg vector and find the right function to call it with. */
- if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT)
+ if (!is_compound_type (check_typedef (value_type (arg1)))
+ && !is_compound_type (check_typedef (value_type (arg2))))
error (_("Can't do that binary op on that type")); /* FIXME be explicit */
argvec = (struct value **) alloca (sizeof (struct value *) * 4);
- argvec[1] = value_addr (arg1);
+ argvec[1] = arg1;
argvec[2] = arg2;
argvec[3] = 0;
@@ -565,7 +581,7 @@ value_x_unop (struct value *arg1, enum e
error (_("Can't do that unary op on that type")); /* FIXME be explicit */
argvec = (struct value **) alloca (sizeof (struct value *) * 4);
- argvec[1] = value_addr (arg1);
+ argvec[1] = arg1;
argvec[2] = 0;
nargs = 1;
Index: testsuite/gdb.cp/operator.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/operator.cc,v
retrieving revision 1.2
diff -u -p -r1.2 operator.cc
--- testsuite/gdb.cp/operator.cc 25 Jun 2010 18:05:30 -0000 1.2
+++ testsuite/gdb.cp/operator.cc 18 Jun 2012 06:56:44 -0000
@@ -1,7 +1,38 @@
class A
{
+ public:
+ int a;
+
+ A operator+ (const A &opr2);
+};
+
+union U
+{
+ int i;
+ char c;
};
+A
+A::operator+ (const A &opr2)
+{
+ A new_a;
+ new_a.a = a + opr2.a;
+
+ return new_a;
+}
+
+int
+operator+ (const int opr1, const A &opr2)
+{
+ return opr1 + opr2.a;
+}
+
+int
+operator+ (const U &opr1, const A &opr2)
+{
+ return opr1.i + opr2.a;
+}
+
int operator== (A, int)
{
return 11;
@@ -176,6 +207,7 @@ test x;
int main ()
{
A a;
+
a == 1;
a == 'a';
@@ -207,5 +239,10 @@ int main ()
L l;
l == 1;
- return 0;
+ A obj1 = { 10 };
+ A obj2 = { 20 };
+ int val = 1;
+ U u = { 10 };
+
+ return 0; /* Break here. */
}
Index: testsuite/gdb.cp/operator.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/operator.exp,v
retrieving revision 1.4
diff -u -p -r1.4 operator.exp
--- testsuite/gdb.cp/operator.exp 4 Jan 2012 08:17:47 -0000 1.4
+++ testsuite/gdb.cp/operator.exp 18 Jun 2012 06:56:44 -0000
@@ -26,6 +26,9 @@ if ![runto_main] then {
continue
}
+gdb_breakpoint [gdb_get_line_number "Break here."]
+gdb_continue_to_breakpoint "Break here" ".*Break here.*"
+
# Test global operator
gdb_test "p a == 1" "= 11" "global operator"
gdb_test "p a == 'a'" "= 12" "global operator overload"
@@ -59,3 +62,8 @@ gdb_test "p l == 1" "= 88"
# Test that we don't fall into an import loop
gdb_test {p x[0]} {No symbol "operator\[\]" in current context.}
+
+# Test + operators
+gdb_test "print val + obj1" "11" "Test overloaded operator function"
+gdb_test "print (obj1 + obj2).a" "30" "Test overloaded operator method"
+gdb_test "print u + obj2" "30" "Test overloaded operator function with union arg"
prev parent reply other threads:[~2012-06-18 7:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-01 19:52 Siva Chandra
2012-06-04 20:53 ` Tom Tromey
2012-06-05 18:34 ` Siva Chandra
2012-06-08 17:41 ` Tom Tromey
2012-06-08 19:18 ` Siva Chandra
2012-06-18 7:30 ` Siva Chandra [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAGyQ6gytckT+qW1UhcWq0moDO=qwrCby0KSx3zo2Ye-3uCN4AQ@mail.gmail.com' \
--to=sivachandra@google.com \
--cc=gdb-patches@sourceware.org \
--cc=tromey@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox