public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [patch] Overload resolution among children of a common ancestor
@ 2010-08-30 16:11 sami wagiaalla
  2010-10-19 20:27 ` [patch 1/2] " sami wagiaalla
  2010-10-19 20:30 ` [patch 2/2] " sami wagiaalla
  0 siblings, 2 replies; 8+ messages in thread
From: sami wagiaalla @ 2010-08-30 16:11 UTC (permalink / raw)
  To: gdb-patches

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

This patch introduces a cost for converting types to their ancestor 
types that depends on the distance to that ancestor. It also disables 
the calling of functions which are inherited through non-public 
inheritance. I had to update a couple of test cases for that.

This patch was regression tested on Fedora 13 on x8664 with gcc 4.4.4. 
No regressions.

Sami

[-- Attachment #2: overload_inheritance.patch --]
[-- Type: text/x-patch, Size: 5858 bytes --]

Fix overload resolution between children of common ancestor.

2010-08-30  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdbtypes.h (distance_to_public_ancestor): New function.
	* gdbtypes.c (distance_to_public_ancestor): New function.
	(rank_one_type): Concider distance_to_public_ancestor when ranking
	two structs.
	(is_public_ancestor): Use distance_to_public_ancestor.

2010-08-30  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/overload.cc: Add testing for overload resolution based on
	distance to ancestor.
	* gdb.cp/overload.exp: Ditto.
	* gdb.cp/virtfunc2.cc (Obj2): Change inheritance to public.
	Add calls to the function calls being tested.
	* gdb.cp/derivation.cc (G): Changed inheritance to public.
	Add calls to the function calls being tested.

diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index b7fb110..39912d6 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1903,23 +1903,48 @@ is_ancestor (struct type *base, struct type *dclass)
 int
 is_public_ancestor (struct type *base, struct type *dclass)
 {
+  return (distance_to_public_ancestor (base, dclass) >= 0);
+}
+
+/* If BASE is a public ancestor of DCLASS return the distance between them.
+   otherwise return -1;
+   eg:
+
+   class A {};
+   class B: public A {};
+   class C: public B {};
+   class D: C {};
+
+   distance_to_public_ancestor (A, A) = 0
+   distance_to_public_ancestor (A, B) = 1
+   distance_to_public_ancestor (A, C) = 2
+   distance_to_public_ancestor (A, D) = -1
+
+   */
+int
+distance_to_public_ancestor (struct type *base, struct type *dclass)
+{
   int i;
+  int d;
 
   CHECK_TYPEDEF (base);
   CHECK_TYPEDEF (dclass);
 
   if (class_types_same_p (base, dclass))
-    return 1;
+    return 0;
 
   for (i = 0; i < TYPE_N_BASECLASSES (dclass); ++i)
     {
       if (! BASETYPE_VIA_PUBLIC (dclass, i))
 	continue;
-      if (is_public_ancestor (base, TYPE_BASECLASS (dclass, i)))
-	return 1;
+
+      d = distance_to_public_ancestor (base, TYPE_BASECLASS (dclass, i));
+      if (d >= 0)
+        return 1 + d;
+
     }
 
-  return 0;
+  return -1;
 }
 
 /* A helper function for is_unique_ancestor.  */
@@ -2120,6 +2145,7 @@ integer_types_same_name_p (const char *first, const char *second)
 int
 rank_one_type (struct type *parm, struct type *arg)
 {
+  int d;
   /* Identical type pointers.  */
   /* However, this still doesn't catch all cases of same type for arg
      and param.  The reason is that builtin types are different from
@@ -2411,8 +2437,9 @@ rank_one_type (struct type *parm, struct type *arg)
 	{
 	case TYPE_CODE_STRUCT:
 	  /* Check for derivation */
-	  if (is_ancestor (parm, arg))
-	    return BASE_CONVERSION_BADNESS;
+	  d = distance_to_public_ancestor (parm, arg);
+	  if (d >= 0)
+	    return BASE_CONVERSION_BADNESS + d;
 	  /* else fall through */
 	default:
 	  return INCOMPATIBLE_TYPE_BADNESS;
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index ed8d613..6a1eb80 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1358,6 +1358,8 @@ extern int class_types_same_p (const struct type *, const struct type *);
 
 extern int is_ancestor (struct type *, struct type *);
 
+extern int distance_to_public_ancestor (struct type *, struct type *);
+
 extern int is_public_ancestor (struct type *, struct type *);
 
 extern int is_unique_ancestor (struct type *, struct value *);
diff --git a/gdb/testsuite/gdb.cp/derivation.cc b/gdb/testsuite/gdb.cp/derivation.cc
index f6d42e7..02999c1 100644
--- a/gdb/testsuite/gdb.cp/derivation.cc
+++ b/gdb/testsuite/gdb.cp/derivation.cc
@@ -96,7 +96,7 @@ public:
     
 };
 
-class G : private A, public B, protected C {
+class G : public A, public B, public C {
 public:
     int g;
     int gg;
@@ -207,7 +207,10 @@ int main(void)
     E e_instance;
     F f_instance;
     G g_instance;
-    
+
+    g_instance.afoo();
+    g_instance.cfoo();
+
     #ifdef usestubs
        set_debug_traps();
        breakpoint();
diff --git a/gdb/testsuite/gdb.cp/overload.cc b/gdb/testsuite/gdb.cp/overload.cc
index dc117fb..bd2f96c 100644
--- a/gdb/testsuite/gdb.cp/overload.cc
+++ b/gdb/testsuite/gdb.cp/overload.cc
@@ -89,6 +89,14 @@ namespace XXX {
   void marker2() {}
 }
 
+class A {};
+class B: public A {};
+class C: public B {};
+class D: C {};
+
+int bar (A) { return 11; }
+int bar (B) { return 22; }
+
 int main () 
 {
     char arg2 = 2;
@@ -105,6 +113,15 @@ int main ()
     int arg13 = 200.0;
     char arg14 = 'a';
 
+    A a;
+    B b;
+    C c;
+    D d;
+
+    bar (a);
+    bar (b);
+    bar (c);
+
     char *str = (char *) "A";
     foo foo_instance1(111);
     foo foo_instance2(222, str);
@@ -132,6 +149,7 @@ int main ()
 
     marker1(); // marker1-returns-here
     XXX::marker2(); // marker1-returns-here
+
     return 0;
 }
 
diff --git a/gdb/testsuite/gdb.cp/overload.exp b/gdb/testsuite/gdb.cp/overload.exp
index 25aeb07..048e074 100644
--- a/gdb/testsuite/gdb.cp/overload.exp
+++ b/gdb/testsuite/gdb.cp/overload.exp
@@ -266,6 +266,11 @@ gdb_test "print foo_instance1.overload1arg(&arg14)" \
     "\\$\[0-9\]+ = 14" \
     "print call overloaded func char\\* arg"
 
+gdb_test "print bar(a)" "= 11"
+gdb_test "print bar(b)" "= 22"
+gdb_test "print bar(c)" "= 22"
+gdb_test "print bar(d)" "Cannot resolve function bar to any overloaded instance"
+
 # ---
 
 # List overloaded functions.
diff --git a/gdb/testsuite/gdb.cp/virtfunc2.cc b/gdb/testsuite/gdb.cp/virtfunc2.cc
index 90f3eda..666a495 100644
--- a/gdb/testsuite/gdb.cp/virtfunc2.cc
+++ b/gdb/testsuite/gdb.cp/virtfunc2.cc
@@ -27,7 +27,7 @@ public:
   virtual int do_print() { return 123456; }
 };
 
-class Obj2 : Obj,  virtual public interface
+class Obj2 : public Obj,  virtual public interface
 {
   virtual int do_print2() { return 654321; }
 };
@@ -35,5 +35,7 @@ class Obj2 : Obj,  virtual public interface
 int main(int argc, char** argv) {
   Obj o;
   Obj2 o2;
+  o2.do_print();
+
   return 0;	// marker 1
 }

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

end of thread, other threads:[~2010-11-02 20:31 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-30 16:11 [patch] Overload resolution among children of a common ancestor sami wagiaalla
2010-10-19 20:27 ` [patch 1/2] " sami wagiaalla
2010-10-22 15:39   ` Tom Tromey
2010-11-02 18:04     ` sami wagiaalla
2010-11-02 20:31       ` Tom Tromey
2010-10-19 20:30 ` [patch 2/2] " sami wagiaalla
2010-10-22 17:16   ` Tom Tromey
2010-11-02 18:05     ` sami wagiaalla

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