2010-07-28 Daniel Jacobowitz <dan@codesourcery.com>
authorPedro Alves <palves@redhat.com>
Wed, 28 Jul 2010 19:04:08 +0000 (19:04 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 28 Jul 2010 19:04:08 +0000 (19:04 +0000)
gdb/
* dwarf2read.c (read_subroutine_type): Improve THIS detection,
handling DW_AT_object_pointer, and workaround GCC PR 43053.

gdb/testsuite/
* gdb.cp/member-ptr.exp, gdb.cp/printmethod.exp,
gdb.dwarf2/member-ptr-forwardref.exp: Adjust.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/member-ptr.exp
gdb/testsuite/gdb.cp/printmethod.exp
gdb/testsuite/gdb.dwarf2/member-ptr-forwardref.exp

index ebcc04ce35c5309cf1f1c2409513113833ae53d8..05ec70e63799b9631a1ddc1c42bff91bf9640e14 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-28  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * dwarf2read.c (read_subroutine_type): Improve THIS detection,
+       handling DW_AT_object_pointer, and workaround GCC PR 43053.
+
 2010-07-28  Tom Tromey  <tromey@redhat.com>
 
        * Makefile.in (HFILES_NO_SRCDIR): Remove link-warning.h.
index 4c92c61c18ab2e818cda7fef72e16fa2f6071e93..7a0da0e1b4c8006f814eea441fad0d7ebf2dbd16 100644 (file)
@@ -7395,11 +7395,17 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
        {
          if (child_die->tag == DW_TAG_formal_parameter)
            {
-             /* Dwarf2 has no clean way to discern C++ static and non-static
-                member functions. G++ helps GDB by marking the first
-                parameter for non-static member functions (which is the
-                this pointer) as artificial. We pass this information
-                to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.  */
+             struct type *arg_type;
+
+             /* DWARF version 2 has no clean way to discern C++
+                static and non-static member functions.  G++ helps
+                GDB by marking the first parameter for non-static
+                member functions (which is the this pointer) as
+                artificial.  We pass this information to
+                dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL.
+
+                DWARF version 3 added DW_AT_object_pointer, which GCC
+                4.5 does not yet generate.  */
              attr = dwarf2_attr (child_die, DW_AT_artificial, cu);
              if (attr)
                TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
@@ -7417,7 +7423,40 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
                        TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 1;
                    }
                }
-             TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, cu);
+             arg_type = die_type (child_die, cu);
+
+             /* RealView does not mark THIS as const, which the testsuite
+                expects.  GCC marks THIS as const in method definitions,
+                but not in the class specifications (GCC PR 43053).  */
+             if (cu->language == language_cplus && !TYPE_CONST (arg_type)
+                 && TYPE_FIELD_ARTIFICIAL (ftype, iparams))
+               {
+                 int is_this = 0;
+                 struct dwarf2_cu *arg_cu = cu;
+                 const char *name = dwarf2_name (child_die, cu);
+
+                 attr = dwarf2_attr (die, DW_AT_object_pointer, cu);
+                 if (attr)
+                   {
+                     /* If the compiler emits this, use it.  */
+                     if (follow_die_ref (die, attr, &arg_cu) == child_die)
+                       is_this = 1;
+                   }
+                 else if (name && strcmp (name, "this") == 0)
+                   /* Function definitions will have the argument names.  */
+                   is_this = 1;
+                 else if (name == NULL && iparams == 0)
+                   /* Declarations may not have the names, so like
+                      elsewhere in GDB, assume an artificial first
+                      argument is "this".  */
+                   is_this = 1;
+
+                 if (is_this)
+                   arg_type = make_cv_type (1, TYPE_VOLATILE (arg_type),
+                                            arg_type, 0);
+               }
+
+             TYPE_FIELD_TYPE (ftype, iparams) = arg_type;
              iparams++;
            }
          child_die = sibling_die (child_die);
index ef40fb56c61414588a34b8c8b6bdd0192f1e9f11..44ee3b98b011fde03dfc3af380c2fb2b9d3c6bb3 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-28  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gdb.cp/member-ptr.exp, gdb.cp/printmethod.exp,
+       gdb.dwarf2/member-ptr-forwardref.exp: Adjust.
+
 2010-07-28  Tom Tromey  <tromey@redhat.com>
 
        PR c++/9946:
index 329de52c1283f5525172163200d4f20d208b3b39..33f121b89ce648120bf7ecf4d3b06b518273e038 100644 (file)
@@ -396,7 +396,7 @@ gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name {
 
 set name "ptype pmf"
 gdb_test_multiple "ptype pmf" $name {
-    -re "type = int \\( ?A::\\*\\)\\(A \\*, int\\)\r\n$gdb_prompt $" {
+    -re "type = int \\( ?A::\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
        pass $name
     }
     -re "type = int \\( ?A::\\*\\)\\(void\\)\r\n$gdb_prompt $" {
@@ -418,7 +418,7 @@ gdb_test_multiple "ptype pmf" $name {
 
 set name "print pmf"
 gdb_test_multiple "print pmf" $name {
-    -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
+    -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
        pass $name
     }
     -re "$vhn = .*not supported with HP aCC.*\r\n$gdb_prompt $" {
@@ -440,7 +440,7 @@ gdb_test_multiple "print pmf" $name {
 
 set name "ptype pmf_p"
 gdb_test_multiple "ptype pmf_p" $name {
-    -re "type = int \\( ?A::\\*\\*\\)\\(A \\*, int\\)\r\n$gdb_prompt $" {
+    -re "type = int \\( ?A::\\*\\*\\)\\(A \\*( const)?, int\\)\r\n$gdb_prompt $" {
        pass $name
     }
     -re "type = int \\( ?A::\\*\\*\\)\\(void\\)\r\n$gdb_prompt $" {
@@ -482,7 +482,7 @@ gdb_test_multiple "print pmf_p" $name {
 
 set name "print a.*pmf"
 gdb_test_multiple "print a.*pmf" $name {
-    -re "$vhn = {int \\(A \\*, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
+    -re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
        pass $name
     }
     -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
@@ -504,7 +504,7 @@ gdb_test_multiple "print a.*pmf" $name {
 
 set name "print a_p->*pmf"
 gdb_test_multiple "print a_p->*pmf" $name {
-    -re "$vhn = {int \\(A \\*, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
+    -re "$vhn = {int \\(A \\*( const)?, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
        pass $name
     }
     -re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
@@ -606,7 +606,7 @@ gdb_test_multiple "print (a.*pmf)(3)" $name {
     }
 }
 
-gdb_test "ptype a.*pmf" "type = int \\(A \\*, int\\)"
+gdb_test "ptype a.*pmf" "type = int \\(A \\*( const)?, int\\)"
 
 # Print out a pointer to data member which requires looking into
 # a base class.
@@ -618,9 +618,9 @@ gdb_test "print diamond.*diamond_pmi" "$vhn = 77"
 
 # These two have a different object adjustment, but call the same method.
 gdb_test "print diamond.*left_pmf" \
-    "$vhn = {int \\(Diamond \\*\\)} $hex <Base::get_x\\((void|)\\)>"
+    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
 gdb_test "print diamond.*right_pmf" \
-    "$vhn = {int \\(Diamond \\*\\)} $hex <Base::get_x\\((void|)\\)>"
+    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Base::get_x\\((void|)\\)>"
 
 gdb_test "print (diamond.*left_pmf) ()" "$vhn = 77"
 gdb_test "print (diamond.*right_pmf) ()" "$vhn = 88"
@@ -628,9 +628,9 @@ gdb_test "print (diamond.*right_pmf) ()" "$vhn = 88"
 # These two point to different methods, although they have the same
 # virtual table offsets.
 gdb_test "print diamond.*left_vpmf" \
-    "$vhn = {int \\(Diamond \\*\\)} $hex <Left::vget\\((void|)\\)>"
+    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Left::vget\\((void|)\\)>"
 gdb_test "print diamond.*right_vpmf" \
-    "$vhn = {int \\(Diamond \\*\\)} $hex <Right::vget\\((void|)\\)>"
+    "$vhn = {int \\(Diamond \\*( const)?\\)} $hex <Right::vget\\((void|)\\)>"
 
 gdb_test "print (diamond.*left_vpmf) ()" "$vhn = 177"
 gdb_test "print (diamond.*left_base_vpmf) ()" "$vhn = 2077"
@@ -658,5 +658,5 @@ gdb_test "print null_pmi = &A::j" "$vhn = &A::j"
 gdb_test "print null_pmi = 0" "$vhn = NULL"
 
 gdb_test "print null_pmf" "$vhn = NULL"
-gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::foo ?\\(int\\)>"
+gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*( const)?, int\\)\\) $hex <A::foo ?\\(int\\)>"
 gdb_test "print null_pmf = 0" "$vhn = NULL"
index 12c9ca80a1c01a66dfb446a75a01a0ccc7675e75..16cd752ea6af5b735ba9449bf3e878183e65243e 100644 (file)
@@ -62,10 +62,10 @@ gdb_continue_to_breakpoint "end of constructors"
 # The first of these is for PR gdb/653.
 
 gdb_test "print theA->virt" \
-    "\\$\[0-9\]* = {void \\(A \\*\\)} $hex <A::virt\\((void|)\\)>" \
+    "\\$\[0-9\]* = {void \\(A \\* const\\)} $hex <A::virt\\((void|)\\)>" \
     "print virtual method."
 gdb_test "print theA->nonvirt" \
-    "\\$\[0-9\]* = {void \\(A \\*\\)} $hex <A::nonvirt\\((void|)\\)>" \
+    "\\$\[0-9\]* = {void \\(A \\* const\\)} $hex <A::nonvirt\\((void|)\\)>" \
     "print nonvirtual method."
 
 gdb_exit
index bb947bcf09facbafa38232991d2259a84e37f1fb..7a72e530c04fe036e19be8fe9733261b9da2544d 100644 (file)
@@ -45,4 +45,4 @@ gdb_test "show cp-abi" {The currently selected C\+\+ ABI is "gnu-v3".*}
 
 gdb_load ${binfile}
 
-gdb_test "ptype c" "type = struct C {\[\r\n \t\]*private:\[\r\n \t\]*int \\(C::\\*fp\\)\\(C \\*\\);\[\r\n \t\]*}"
+gdb_test "ptype c" "type = struct C {\[\r\n \t\]*private:\[\r\n \t\]*int \\(C::\\*fp\\)\\(C \\*( const)?\\);\[\r\n \t\]*}"