public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [patch] smart pointer support
@ 2010-07-20 15:58 sami wagiaalla
  2010-07-23 23:37 ` Tom Tromey
  0 siblings, 1 reply; 19+ messages in thread
From: sami wagiaalla @ 2010-07-20 15:58 UTC (permalink / raw)
  To: gdb-patches

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

The '->' operator can be overloaded in C++ and when overloaded it 
forwards the function call or member reference to the return type. Example:

template < typename Type> class SmartPointer{
   Type* p;
  public:
   SmartPointer(Type *pointer){
     p = pointer;
   }

   Type* operator->(){
     return p;
   }
};


class MyType{
   public:
   void foo(){
     printf("I am foo\n");
   }
};

int main(){
   MyType mt;

   SmartPointer<MyType> sp(&mt);

   sp->foo();

   return 0;
}

Here sp->foo() really means (sp->)->foo()

This patch adds support for that in gdb

This patch adds a test to the test suite to test for the functionality 
above and was regression tested by running the test suite on Fedora 13 
on x8664 with gcc 444


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

Support overloading of 'operator->'.

2010-07-20  Sami Wagiaalla  <swagiaal@redhat.com>

	 PR C++/11500:
	* valarith.c (value_x_unop): Handle STRUCTOP_PTR.
	* eval.c (evaluate_subexp_standard): Check for overload of
	'operator->'.

2010-07-20  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/smartp.exp: New test.
	* gdb.cp/smartp.cc : New test.

diff --git a/gdb/eval.c b/gdb/eval.c
index ea3d8a0..5f4ab2f 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1431,6 +1431,20 @@ evaluate_subexp_standard (struct type *expect_type,
 	  else
 	    {
 	      arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+
+	      /* For C++ check to see if the operator '->' has been overloaded.
+	         If the operator has been overloaded replace arg2 with the value
+	         returned by the custom operator and continue evaluation.  */
+	      if (exp->language_defn->la_language == language_cplus)
+		{
+		  struct type *arg_type = value_type (arg2);
+		  if (arg_type && TYPE_CODE (arg_type) == TYPE_CODE_STRUCT)
+		    {
+		      struct value *value = value_x_unop (arg2, op, noside);
+		      if (value)
+			arg2 = value;
+		    }
+		}
 	    }
 	  /* Now, say which argument to start evaluating from */
 	  tem = 2;
@@ -1818,6 +1832,20 @@ evaluate_subexp_standard (struct type *expect_type,
       if (noside == EVAL_SKIP)
 	goto nosideret;
 
+      /* For C++ check to see if operator '->' has been overloaded.
+         If so replace arg1 with the value returned by evaluating
+         operator->().  */
+      if (exp->language_defn->la_language == language_cplus)
+	{
+	  struct type *arg_type = value_type (arg1);
+
+	  if (arg_type && TYPE_CODE (arg_type) == TYPE_CODE_STRUCT)
+	    {
+	      struct value *value = value_x_unop (arg1, op, noside);
+	      if (value)
+		arg1 = value;
+	    }
+	}
       /* JYG: if print object is on we need to replace the base type
 	 with rtti type in order to continue on with successful
 	 lookup of member / method only available in the rtti type. */
diff --git a/gdb/testsuite/gdb.cp/smartp.cc b/gdb/testsuite/gdb.cp/smartp.cc
new file mode 100644
index 0000000..a42db6f
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/smartp.cc
@@ -0,0 +1,95 @@
+class Type1{
+  public:
+  int foo(){
+    return 11;
+  }
+};
+
+class Type2{
+  public:
+  int foo(){
+    return 22;
+  }
+};
+
+class Type3{
+  public:
+  int foo(int){
+    return 33;
+  }
+  int foo(char){
+    return 44;
+  }
+};
+
+class Type4 {
+  public:
+    int a;
+    int b;
+};
+
+int foo (Type3, float)
+{
+  return 55;
+}
+
+class MyPointer{
+  Type1 *p;
+ public:
+  MyPointer(Type1 *pointer){
+    p = pointer;
+  }
+
+  Type1 *operator->(){
+    return p;
+  }
+};
+
+template <typename T> class SmartPointer{
+  T* p;
+ public:
+  SmartPointer(T *pointer){
+    p = pointer;
+  }
+
+  T *operator->(){
+    return p;
+  }
+};
+
+int main(){
+  Type1 mt1;
+  Type2 mt2;
+  Type3 mt3;
+
+  Type4 mt4;
+  mt4.a = 11;
+  mt4.b = 12;
+
+  MyPointer mp(&mt1);
+  Type1 *mtp = &mt1;
+
+  SmartPointer<Type1> sp1(&mt1);
+  SmartPointer<Type2> sp2(&mt2);
+  SmartPointer<Type3> sp3(&mt3);
+  SmartPointer<Type4> sp4(&mt4);
+
+  mp->foo();
+  mtp->foo();
+
+  sp1->foo();
+  sp2->foo();
+
+  sp3->foo(1);
+  sp3->foo('a');
+
+  sp4->a;
+  sp4->b;
+
+  Type4 *mt4p = &mt4;
+  mt4p->a;
+  mt4p->b;
+
+  return 0; // end of main
+}
+
diff --git a/gdb/testsuite/gdb.cp/smartp.exp b/gdb/testsuite/gdb.cp/smartp.exp
new file mode 100644
index 0000000..335ecf8
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/smartp.exp
@@ -0,0 +1,68 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set testfile smartp
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+    untested "Couldn't compile test program"
+    return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint main"
+    continue
+}
+
+gdb_breakpoint [gdb_get_line_number "end of main"]
+gdb_continue_to_breakpoint "end of main"
+
+# Test that overloaded arrow operator works
+gdb_test "p mp->foo()"            "= 11"
+
+# Test that regular arrow operator still works
+gdb_test "p mtp->foo()"            "= 11"
+
+# Test that templated smart pointers work
+gdb_test "p sp1->foo()"            "= 11"
+gdb_test "p sp2->foo()"            "= 22"
+
+# Test that overload resolution works properly
+# with smart pointers
+gdb_test "p sp3->foo(1)"           "= 33"
+gdb_test "p sp3->foo('a')"         "= 44"
+
+# Test smart pointers work for member references
+gdb_test "p sp4->a"         "= 11"
+gdb_test "p sp4->b"         "= 12"
+
+# Test regular arrow operator still works for
+# member references
+gdb_test "p mt4p->a"         "= 11"
+gdb_test "p mt4p->b"         "= 12"
+
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 0c40905..91f9c0c 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -616,6 +616,9 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside)
     case UNOP_IND:
       strcpy (ptr, "*");
       break;
+    case STRUCTOP_PTR:
+      strcpy (ptr, "->");
+      break;
     default:
       error (_("Invalid unary operation specified."));
     }

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

end of thread, other threads:[~2010-10-19 20:55 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-20 15:58 [patch] smart pointer support sami wagiaalla
2010-07-23 23:37 ` Tom Tromey
2010-08-05 18:46   ` sami wagiaalla
2010-08-05 22:57     ` Ulrich Weigand
2010-08-06 16:23       ` sami wagiaalla
2010-08-06 16:48         ` Ulrich Weigand
2010-08-06 17:29           ` Tom Tromey
2010-08-08 15:01             ` Ulrich Weigand
2010-08-06 21:33           ` sami wagiaalla
2010-08-06 22:20             ` Tom Tromey
2010-08-09 15:59               ` sami wagiaalla
2010-08-09 17:35                 ` Tom Tromey
2010-08-09 18:04                   ` sami wagiaalla
2010-08-09 18:23                     ` Jan Kratochvil
2010-08-16 20:31                       ` sami wagiaalla
2010-08-16 20:59                         ` Pedro Alves
2010-08-17 16:16                           ` sami wagiaalla
2010-08-17 17:15                             ` Tom Tromey
2010-10-19 20:55                               ` 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).