This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfc] patch for pr8880


On 02/09/2010 06:35 PM, Tom Tromey wrote:
Tom> Why not just use value_ind?

Sami> value_ind works. I just missed it :)

Totally understandable, the value API is over-large.

Sami>  I could put this code in a function to be called from value_x_binop
Sami>  and value_x_unop. That would at least avoid the awkward argument
Sami>  counting but not earlier than that since the arguments need to have
Sami>  been evaluated and/or add a check for la_language == language_cplus.

I think that sounds ok.


Done! I learned that one can catch the exception to prevent value_struct_elt from exiting, attempt the ADL search then deliver the patch if that fails.

Tom>  Also, ADL should only be done for unqualified names.
Tom>  It isn't clear to me that this change satisfies that requirement.

Sami>  Let me look into this. It might be a general problem I don't think gdb
Sami>  ever differentiates between qualified and unqualified names

I was looking into this area a little bit recently.

c-exp.y does sometimes differentiate the cases; it will emit an OP_SCOPE
in the qualified case.  I think we do mishandle either "::name" or
"::name::name" here, in the sense that these aren't distinguished from a
name without a leading "::".  (ADL also should be avoided for something
like obj->method(), but from what I remember your changes handled ok.)


Is it correct to assume then that qualified names should be treated through evaluation of OP_SCOPE and is not effected by this patch - baring lexer/parser bugs. Especially since the patch is now restricted to user defined operators.


diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.cc b/gdb/testsuite/gdb.cp/namespace-koenig.cc
index 6c2c01d..3c30cb2 100644
--- a/gdb/testsuite/gdb.cp/namespace-koenig.cc
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.cc
@@ -129,6 +129,42 @@ namespace L {
}
//------------
+
+namespace M {
+ class O{
+ public:
+ int operator== (int){
+ return 18;
+ }
+
+ int operator== (float){
+ return 19;
+ }
+
+ int operator+ (float){
+ return 22;
+ }
+
+ };
+
+ int operator!= (O, int){
+ return 20;
+ }
+
+ int operator!= (O, double){
+ return 21;
+ }
+
+ int operator+ (O, int){
+ return 23;
+ }
+
+ int operator++ (O){
+ return 24;
+ }
+
+}
+//------------
int
main ()
{
@@ -180,7 +216,15 @@ main ()
L::A::B::O labo;
foo (labo);
-
+
+ M::O o;
+ o == 5;
+ o == 5.0f;
+ o != 5;
+ o != 5.0f;
+ o + 5;
+ o + 5.0f;
+
return first (0, c) + foo (eo) +
foo (eo, eo) + foo (eo, eo, 1) +
foo (fo, eo) + foo (1 ,fo, eo) +
diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.exp b/gdb/testsuite/gdb.cp/namespace-koenig.exp
index 616b816..c73e239 100644
--- a/gdb/testsuite/gdb.cp/namespace-koenig.exp
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.exp
@@ -93,3 +93,20 @@ gdb_test "p bar(ko,1)" "= -1"
#test lookup of objects belonging to nested namespaces
gdb_test "p foo(labo)" "= 17"
+
+# test lookup of namespace user-defined operators
+# and overload resolution:
+
+# within class
+gdb_test "p o == 5" "= 18"
+gdb_test "p o == 5.0f" "= 19"
+
+# within namespace
+gdb_test "p o != 5" "= 20"
+gdb_test "p o != 5.0f" "= 21"
+
+# across namespace and class
+gdb_test "p o + 5.0f" "= 22"
+gdb_test "p o + 5" "= 23"
+
+gdb_test "p o++" "= 24"
diff --git a/gdb/valarith.c b/gdb/valarith.c
index ed76b09..c672a5b 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -31,6 +31,7 @@
#include "dfp.h"
#include <math.h>
#include "infcall.h"
+#include "exceptions.h"
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C). */
@@ -298,6 +299,62 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1)
}
}
+struct value *
+value_user_defined_adl_op (struct value **args, int nargs, char *operator)
+{
+
+ struct symbol *symp;
+ struct type **arg_types;
+ int i;
+
+ /* This function, if found, will not be a member function
+ and does not expect a pointer as its first argument
+ rather the explicit structure. */
+ args[0] = value_ind (args[0]);
+
+ arg_types = (struct type **)alloca (nargs * (sizeof (struct type *)));
+ /* Prepare list of argument types for overload resolution */
+ for (i = 0; i < nargs; i++)
+ arg_types [i] = value_type (args [i]);
+
+ find_overload_match (arg_types, nargs, operator, 0 /* not method */,
+ 0 /* strict match */, NULL,
+ NULL /* pass NULL symbol since symbol is unknown */,
+ NULL, &symp, NULL);
+
+ if (symp)
+ return value_of_variable (symp, 0);
+
+ return NULL;
+}
+
+struct value *
+value_user_defined_op (struct value **argp, struct value **args, char *name,
+ int *static_memfuncp, int nargs)
+{
+ struct value *result = NULL;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ result = value_struct_elt (argp, args, name, static_memfuncp,
+ "structure");
+ }
+
+ if (except.reason < 0)
+ {
+
+ if (current_language->la_language == language_cplus)
+ /* Try ADL. */
+ result = value_user_defined_adl_op (args, nargs, name);
+
+ if (!result)
+ error ("%s", except.message);
+ }
+
+ return result;
+}
+
/* We know either arg1 or arg2 is a structure, so try to find the right
user defined function. Create an argument vector that calls
arg1.operator @ (arg1,arg2) and return that value (where '@' is any
@@ -438,7 +495,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op,
error (_("Invalid binary operation specified."));
}
- argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+ argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
+ &static_memfuncp, 2);
if (argvec[0])
{
@@ -535,7 +593,8 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
error (_("Invalid unary operation specified."));
}
- argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure");
+ argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr,
+ &static_memfuncp, 1);
if (argvec[0])
{

Attachment: patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]