public inbox for archer@sourceware.org
 help / color / mirror / Atom feed
* [rfc] patch for pr8880
@ 2010-02-08 16:35 Sami Wagiaalla
  2010-02-08 17:30 ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Sami Wagiaalla @ 2010-02-08 16:35 UTC (permalink / raw)
  To: Project Archer

[-- Attachment #1: Type: text/plain, Size: 3781 bytes --]

This was a long chase but an easy fix.
Thoughts ?

diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.cc b/gdb/testsuite/gdb.cp/namespace-koenig.cc
index 6c2c01d..5df6a33 100644
--- a/gdb/testsuite/gdb.cp/namespace-koenig.cc
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.cc
@@ -129,6 +129,29 @@ namespace L {
 }
 
 //------------
+
+namespace M {
+  class O{
+  public:
+    int operator== (int){
+      return 18;
+    }
+
+    int operator== (float){
+      return 19;
+    }
+  };
+
+  int operator!= (O, int){
+    return 20;
+  }
+
+  int operator!= (O, double){
+    return 21;
+  }
+
+}
+//------------
 int
 main ()
 {
@@ -180,6 +203,12 @@ main ()
 
   L::A::B::O labo;
   foo (labo);
+
+  M::O o;
+  o == 5;
+  o == 5.0f;
+  o != 5;
+  o != 5.0f;
   
   return first (0, c) + foo (eo) +
          foo (eo, eo) + foo (eo, eo, 1)  +
diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.exp b/gdb/testsuite/gdb.cp/namespace-koenig.exp
index 616b816..f9ac963 100644
--- a/gdb/testsuite/gdb.cp/namespace-koenig.exp
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.exp
@@ -93,3 +93,10 @@ 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.
+gdb_test "p o == 5" "= 18"
+gdb_test "p o == 5.0f" "= 19"
+gdb_test "p o != 5" "= 20"
+gdb_test "p o != 5.0f" "= 21"
diff --git a/gdb/valops.c b/gdb/valops.c
index e6ea6c9..25d077f 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -889,6 +889,13 @@ value_at (struct type *type, CORE_ADDR addr)
   return get_value_at (type, addr, 0);
 }
 
+struct value *
+value_at_value (struct value *value)
+{
+  return value_at(TYPE_TARGET_TYPE (value_type(value)),
+                  value_as_address(value));
+}
+
 /* Return a lazy value with type TYPE located at ADDR (cf. value_at).  */
 
 struct value *
@@ -2104,6 +2111,9 @@ value_struct_elt (struct value **argp, struct value **args,
   struct type *t;
   struct value *v;
 
+  struct type **arg_types;
+  int nargs, i = 0;
+
   *argp = coerce_array (*argp);
 
   t = check_typedef (value_type (*argp));
@@ -2173,6 +2183,33 @@ value_struct_elt (struct value **argp, struct value **args,
 	*static_memfuncp = 1;
     }
 
+  /* try Koenig lookup.  */
+  if (!v && args)
+    {
+      struct symbol *symp;
+      /* 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_at_value(args[0]);
+
+      nargs = 0;
+      if (args[1] == 0)
+        nargs = 1;
+      else if (args[2] == 0)
+        nargs = 2;
+
+      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, name, 0 /* not method */,
+                           0 /* strict match */, NULL,
+                           NULL /* pass NULL symbol since symbol is unknown */,
+                           NULL, &symp, NULL);
+
+      v = value_of_variable (symp, 0);
+    }
   if (!v)
     error (_("Structure has no component named %s."), name);
   return v;
diff --git a/gdb/value.h b/gdb/value.h
index 42b4497..1f1dead 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -348,6 +348,7 @@ extern struct value *value_from_decfloat (struct type *type,
 					  const gdb_byte *decbytes);
 
 extern struct value *value_at (struct type *type, CORE_ADDR addr);
+extern struct value *value_at_value (struct value *value);
 extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
 
 extern struct value *value_from_contents_and_address (struct type *,


[-- Attachment #2: pr8880.patch --]
[-- Type: text/plain, Size: 3730 bytes --]

diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.cc b/gdb/testsuite/gdb.cp/namespace-koenig.cc
index 6c2c01d..5df6a33 100644
--- a/gdb/testsuite/gdb.cp/namespace-koenig.cc
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.cc
@@ -129,6 +129,29 @@ namespace L {
 }
 
 //------------
+
+namespace M {
+  class O{
+  public:
+    int operator== (int){
+      return 18;
+    }
+
+    int operator== (float){
+      return 19;
+    }
+  };
+
+  int operator!= (O, int){
+    return 20;
+  }
+
+  int operator!= (O, double){
+    return 21;
+  }
+
+}
+//------------
 int
 main ()
 {
@@ -180,6 +203,12 @@ main ()
 
   L::A::B::O labo;
   foo (labo);
+
+  M::O o;
+  o == 5;
+  o == 5.0f;
+  o != 5;
+  o != 5.0f;
   
   return first (0, c) + foo (eo) +
          foo (eo, eo) + foo (eo, eo, 1)  +
diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.exp b/gdb/testsuite/gdb.cp/namespace-koenig.exp
index 616b816..f9ac963 100644
--- a/gdb/testsuite/gdb.cp/namespace-koenig.exp
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.exp
@@ -93,3 +93,10 @@ 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.
+gdb_test "p o == 5" "= 18"
+gdb_test "p o == 5.0f" "= 19"
+gdb_test "p o != 5" "= 20"
+gdb_test "p o != 5.0f" "= 21"
diff --git a/gdb/valops.c b/gdb/valops.c
index e6ea6c9..25d077f 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -889,6 +889,13 @@ value_at (struct type *type, CORE_ADDR addr)
   return get_value_at (type, addr, 0);
 }
 
+struct value *
+value_at_value (struct value *value)
+{
+  return value_at(TYPE_TARGET_TYPE (value_type(value)),
+                  value_as_address(value));
+}
+
 /* Return a lazy value with type TYPE located at ADDR (cf. value_at).  */
 
 struct value *
@@ -2104,6 +2111,9 @@ value_struct_elt (struct value **argp, struct value **args,
   struct type *t;
   struct value *v;
 
+  struct type **arg_types;
+  int nargs, i = 0;
+
   *argp = coerce_array (*argp);
 
   t = check_typedef (value_type (*argp));
@@ -2173,6 +2183,33 @@ value_struct_elt (struct value **argp, struct value **args,
 	*static_memfuncp = 1;
     }
 
+  /* try Koenig lookup.  */
+  if (!v && args)
+    {
+      struct symbol *symp;
+      /* 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_at_value(args[0]);
+
+      nargs = 0;
+      if (args[1] == 0)
+        nargs = 1;
+      else if (args[2] == 0)
+        nargs = 2;
+
+      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, name, 0 /* not method */,
+                           0 /* strict match */, NULL,
+                           NULL /* pass NULL symbol since symbol is unknown */,
+                           NULL, &symp, NULL);
+
+      v = value_of_variable (symp, 0);
+    }
   if (!v)
     error (_("Structure has no component named %s."), name);
   return v;
diff --git a/gdb/value.h b/gdb/value.h
index 42b4497..1f1dead 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -348,6 +348,7 @@ extern struct value *value_from_decfloat (struct type *type,
 					  const gdb_byte *decbytes);
 
 extern struct value *value_at (struct type *type, CORE_ADDR addr);
+extern struct value *value_at_value (struct value *value);
 extern struct value *value_at_lazy (struct type *type, CORE_ADDR addr);
 
 extern struct value *value_from_contents_and_address (struct type *,


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-08 16:35 [rfc] patch for pr8880 Sami Wagiaalla
@ 2010-02-08 17:30 ` Tom Tromey
  2010-02-09 19:23   ` Sami Wagiaalla
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2010-02-08 17:30 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: Project Archer

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

Sami> This was a long chase but an easy fix.
Sami> Thoughts ?

Lots of formatting nits.

Also I have a few more substantive comments.

Sami> +struct value *
Sami> +value_at_value (struct value *value)
Sami> +{
Sami> +  return value_at(TYPE_TARGET_TYPE (value_type(value)),
Sami> +                  value_as_address(value));

Why not just use value_ind?

Sami> @@ -2104,6 +2111,9 @@ value_struct_elt (struct value **argp, struct value **args,

Modifying value_struct_elt seems dangerous.  This is called from many
places in the code, including some which don't expect ADL to be used --
e.g., Java, Ada.

Can this be done by the caller somehow instead?
Or perhaps some refactoring is needed.

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

Tom

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-08 17:30 ` Tom Tromey
@ 2010-02-09 19:23   ` Sami Wagiaalla
  2010-02-09 23:35     ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Sami Wagiaalla @ 2010-02-09 19:23 UTC (permalink / raw)
  To: archer

On 02/08/2010 12:30 PM, Tom Tromey wrote:
>>>>>> "Sami" == Sami Wagiaalla<swagiaal@redhat.com>  writes:
>
> Sami>  This was a long chase but an easy fix.
> Sami>  Thoughts ?
>
> Lots of formatting nits.
>
> Also I have a few more substantive comments.
>
> Sami>  +struct value *
> Sami>  +value_at_value (struct value *value)
> Sami>  +{
> Sami>  +  return value_at(TYPE_TARGET_TYPE (value_type(value)),
> Sami>  +                  value_as_address(value));
>
> Why not just use value_ind?
>

value_ind works. I just missed it :)

> Sami>  @@ -2104,6 +2111,9 @@ value_struct_elt (struct value **argp, struct value **args,
>
> Modifying value_struct_elt seems dangerous.  This is called from many
> places in the code, including some which don't expect ADL to be used --
> e.g., Java, Ada.
>
> Can this be done by the caller somehow instead?
> Or perhaps some refactoring is needed.
>

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

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

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-09 19:23   ` Sami Wagiaalla
@ 2010-02-09 23:35     ` Tom Tromey
  2010-02-11 21:00       ` Tom Tromey
  2010-02-18 19:45       ` Sami Wagiaalla
  0 siblings, 2 replies; 10+ messages in thread
From: Tom Tromey @ 2010-02-09 23:35 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: archer

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.

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.)

I've been sort of nosing around PR 9496 and PR 8693, but I haven't
really committed yet.  There is a big comment before the qualified_type
production that explains the problem.

I was thinking that maybe we could try to do more in the lexer and
differentiate between the kinds of qualified names there.  This is
probably simplest, though I suspect it may cause us some pain later on.

The other idea I had was to require bison and somehow use the GLR parser
feature to let us differentiate the cases.  It is a little hard to see
exactly how this would work, but I haven't looked at it too deeply yet.

Tom

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-09 23:35     ` Tom Tromey
@ 2010-02-11 21:00       ` Tom Tromey
  2010-02-12 15:44         ` Sami Wagiaalla
  2010-02-18 19:45       ` Sami Wagiaalla
  1 sibling, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2010-02-11 21:00 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: archer

>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> c-exp.y does sometimes differentiate the cases; it will emit an
Tom> OP_SCOPE in the qualified case.  I think we do mishandle either
Tom> "::name" or "::name::name" here, in the sense that these aren't
Tom> distinguished from a name without a leading "::".

Sami mentioned that this was handled on expr-cumulative.

I looked, and it does seem to be partially handled, but I think there
are still bugs.  Also, parts of the implementation are bad -- checking
for "::" in lookup_symbol_in_language is a no-no.

I may end up redoing this; if you're actively working in this area, let
me know, and I will back off.

Tom> I've been sort of nosing around PR 9496 and PR 8693, but I haven't
Tom> really committed yet.  There is a big comment before the qualified_type
Tom> production that explains the problem.

Tom> I was thinking that maybe we could try to do more in the lexer and
Tom> differentiate between the kinds of qualified names there.  This is
Tom> probably simplest, though I suspect it may cause us some pain later on.

Tom> The other idea I had was to require bison and somehow use the GLR parser
Tom> feature to let us differentiate the cases.  It is a little hard to see
Tom> exactly how this would work, but I haven't looked at it too deeply yet.

I think in the short term I am going to try hacking the lexer here.
This should let us solve a number of frequently-reported bugs without
undue pain or regressions.

In the longer term, though, we will have to push all this into the
parser, the comment before the use of find_template_name_end explains
why.

Tom

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-11 21:00       ` Tom Tromey
@ 2010-02-12 15:44         ` Sami Wagiaalla
  0 siblings, 0 replies; 10+ messages in thread
From: Sami Wagiaalla @ 2010-02-12 15:44 UTC (permalink / raw)
  To: Tom Tromey; +Cc: archer

On 02/11/2010 04:00 PM, Tom Tromey wrote:
>>>>>> "Tom" == Tom Tromey<tromey@redhat.com>  writes:
>
> Tom>  c-exp.y does sometimes differentiate the cases; it will emit an
> Tom>  OP_SCOPE in the qualified case.  I think we do mishandle either
> Tom>  "::name" or "::name::name" here, in the sense that these aren't
> Tom>  distinguished from a name without a leading "::".
>
> Sami mentioned that this was handled on expr-cumulative.
>
> I looked, and it does seem to be partially handled, but I think there
> are still bugs.  Also, parts of the implementation are bad -- checking
> for "::" in lookup_symbol_in_language is a no-no.
>
> I may end up redoing this; if you're actively working in this area, let
> me know, and I will back off.
>

Sounds good to me. Go for it.

Sami

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-09 23:35     ` Tom Tromey
  2010-02-11 21:00       ` Tom Tromey
@ 2010-02-18 19:45       ` Sami Wagiaalla
  2010-02-19 23:23         ` Tom Tromey
  1 sibling, 1 reply; 10+ messages in thread
From: Sami Wagiaalla @ 2010-02-18 19:45 UTC (permalink / raw)
  To: Tom Tromey, Project Archer

[-- Attachment #1: Type: text/plain, Size: 6438 bytes --]

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 #2: patch --]
[-- Type: text/plain, Size: 4779 bytes --]

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])
     {

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-18 19:45       ` Sami Wagiaalla
@ 2010-02-19 23:23         ` Tom Tromey
  2010-02-22 16:37           ` Sami Wagiaalla
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Tromey @ 2010-02-19 23:23 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: Project Archer

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

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

Yes, I think that is a reasonable goal.

It is mostly true now, except that "::name" is not emitted as OP_SCOPE.
I think it probably ought to be.

Sami> +value_user_defined_adl_op (struct value **args, int nargs, char *operator)

The new functions should be static.  They need intro comments, as well.

On trunk, you'll want to make 'operator' const; I don't know if that
little cleanup has made it to expr-cumulative yet.

Sami> +  arg_types = (struct type **)alloca (nargs * (sizeof (struct type *)));

Missing a space before alloca.

I think this looks good; check it in with those little changes.

Once Keith's big physname series goes in, I think we should push all the
remaining expr-cumulative stuff upstream, then shut down the branch and
do small fixes like this directly on trunk.  For bigger fixes we can
still make a branch.  I'll handle whatever stuff I've pushed on the
branch.

Tom

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-19 23:23         ` Tom Tromey
@ 2010-02-22 16:37           ` Sami Wagiaalla
  2010-02-23 22:32             ` Tom Tromey
  0 siblings, 1 reply; 10+ messages in thread
From: Sami Wagiaalla @ 2010-02-22 16:37 UTC (permalink / raw)
  To: Project Archer

On 02/19/2010 06:23 PM, Tom Tromey wrote:
>>>>>> "Sami" == Sami Wagiaalla<swagiaal@redhat.com>  writes:
>
> Sami>  Is it correct to assume then that qualified names should be treated
> Sami>  through evaluation of OP_SCOPE and is not effected by this patch -
> Sami>  baring lexer/parser bugs. Especially since the patch is now restricted
> Sami>  to user defined operators.
>
> Yes, I think that is a reasonable goal.
>
> It is mostly true now, except that "::name" is not emitted as OP_SCOPE.
> I think it probably ought to be.
>
> Sami>  +value_user_defined_adl_op (struct value **args, int nargs, char *operator)
>

Want me to work on that or are you already doing it ?

> The new functions should be static.  They need intro comments, as well.
>
> On trunk, you'll want to make 'operator' const; I don't know if that
> little cleanup has made it to expr-cumulative yet.
>
> Sami>  +  arg_types = (struct type **)alloca (nargs * (sizeof (struct type *)));
>
> Missing a space before alloca.
>
> I think this looks good; check it in with those little changes.
>

Will do. Thanks.

> Once Keith's big physname series goes in, I think we should push all the
> remaining expr-cumulative stuff upstream, then shut down the branch and
> do small fixes like this directly on trunk.  For bigger fixes we can
> still make a branch.  I'll handle whatever stuff I've pushed on the
> branch.

Yup, I am working on that for my patches.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [rfc] patch for pr8880
  2010-02-22 16:37           ` Sami Wagiaalla
@ 2010-02-23 22:32             ` Tom Tromey
  0 siblings, 0 replies; 10+ messages in thread
From: Tom Tromey @ 2010-02-23 22:32 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: Project Archer

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

>> It is mostly true now, except that "::name" is not emitted as OP_SCOPE.
>> I think it probably ought to be.

Sami> Want me to work on that or are you already doing it ?

I'm going to do it.

Tom

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-02-23 22:32 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-08 16:35 [rfc] patch for pr8880 Sami Wagiaalla
2010-02-08 17:30 ` Tom Tromey
2010-02-09 19:23   ` Sami Wagiaalla
2010-02-09 23:35     ` Tom Tromey
2010-02-11 21:00       ` Tom Tromey
2010-02-12 15:44         ` Sami Wagiaalla
2010-02-18 19:45       ` Sami Wagiaalla
2010-02-19 23:23         ` Tom Tromey
2010-02-22 16:37           ` Sami Wagiaalla
2010-02-23 22:32             ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).