This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[patch] Overload resolution among children of a common ancestor


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
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
 }

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