public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Jimmy Guo <guo@cup.hp.com>
To: "Daniel Berlin+mail.gdb" <dan@cgsoftware.com>
Cc: gdb@sourceware.cygnus.com
Subject: Re: RTTI working for G++
Date: Thu, 16 Mar 2000 15:53:00 -0000	[thread overview]
Message-ID: <Pine.LNX.4.10.10003161127110.4096-100000@hpcll168.cup.hp.com> (raw)
In-Reply-To: <k8j3bkp2.fsf@dan.resnet.rochester.edu>

>> ... However, one of the fixes was that when print
>> object is on, and one wants to print member / methods of the derived
>> type, you can now do so. 
>
>See, i didn't consider that a bug, i considered it a lacking
>feature. It just wasn't doing the lookup it would need to do, and i've
>been too busy to fix it.

If 'print foo' says it's a pointer to something, and 'print foo->a' says
'There is no member or method named a.', it's very confusing to the
user.  When print object is on, this could happen.  I'd be more willing
to say it's a bug, since the error message contradicts with what print
says and just misleads user ('which one should I believe from this
debugger?').

The fix is in eval.c (evaluate_subexp_standard): it needs to know if
objectprint is set, and if so, return the pointer to the rtti type when
dealing with STUCTOP_PTR (if target type code is TYPE_CODE_CLASS).

>> Besides, there're some fixes to handle pointer
>> to a derived type and explicit casting of a pointer to a base to a
>> derived type. 
>
>This i ran up against. I also handled reference types (By pretending
>they were pointers).

Actually the example you gave at the end of this email looks like
something I fixed, in the casting code.  I'm not familiar with
value_rtti_type and don't quite understand what you were dealing with --
full, etc. are all reset to initial values upon entry into
value_rtti_type ().

>Did you notice that it's not really fun to use value_nid (damn
>flyspell keeps "correcting" the IND to nid, as if "nid" was really a word
>either.) in value_rtti_type? value_nid will call the RTTI routine
>during it's lazy evaluation, which gets you into a recursive nightmare
>if you aren't careful.

I wasn't adventuring into that area since I'm looking at the higher
layer of the proper handling of casting, printing, and expression
evaluation.

>I'd be glad to incorporate your fixes into my patch, and i'd
>appreciate it if you'd look at mine.
>I'll post it to gdb-patches in a few days.

Mine is enclosed in this email.

>I'm a little confused about the semantics of using_enc/full/top in value_rtti_type.
>
>It seems if i set full to 0, on multiple inheritance, it gets the name
>right, but the offset wrong, so you have the right name, and the wrong
>values.
>If i set full to 1, it gets the name wrong ("suspicious *", which
>means it couldn't look it up right), but the values right.

See if my changes to c-valprint.c and valops.c solved your problem.  I
think at least part of the problem is that the pointer value was _not_
adjusted when you change the type of the thing to a rtti type, which is
fixed in these two files.  c-valprint.c deals with printing the pointer
value itself; valops.c deals with printing a member of the pointer value.

Patch follows (the change to typeprint.c probably conflicts with your
version, and I like the output you provided).

- Jimmy Guo, guo@cup.hp.com

Thu Mar 16 15:49:56 2000	Jimmy guo	<guo@cup.hp.com>

	* c-valprint.c (c_value_print): adjust pointer value when
	objectprint is set and pointer type is changed to point to the
	rtti type.

	* eval.c (evaluate_subexp_standard): for OP_VAR_VALUE, always
	return full value object; for STRUCTOP_PTR, use pointer to
	rtti type to get member / method if objectprint is set and
	target type of pointer is class.

	* typeprint.c (whatis_exp): if objectprint is set and exp is of
	pointer / reference type to a class object, look up and print
	the pointer / reference to rtti type.

	* valops.c (value_cast): when casting a pointer / reference type
	of a class object to pointer / refer to its rtti type, adjust
	the new pointer value accordingly.


Index: c-valprint.c
/usr/local/bin/diff -c -w -L c-valprint.c c-valprint.c@@/main/cygnus/7 c-valprint.c
*** c-valprint.c
--- c-valprint.c	Thu Mar 16 10:21:16 2000
***************
*** 497,502 ****
--- 497,505 ----
                    /* create a reference type referencing the real type */
                    type = lookup_reference_type (real_type);
                  }
+ 	      /* JYG: Need to adjust pointer value. */
+               val->aligner.contents[0] -= top;
+ 
                /* Note: When we look up RTTI entries, we don't get any 
                   information on const or volatile attributes */
              }
Index: eval.c
/usr/local/bin/diff -c -w -L eval.c eval.c@@/main/cygnus/9 eval.c
*** eval.c
--- eval.c	Thu Mar 16 15:41:34 2000
***************
*** 37,42 ****
--- 37,45 ----
  /* This is defined in valops.c */
  extern int overload_resolution;
  
+ /* JYG: lookup rtti type of STRUCTOP_PTR when this is set to continue
+    on with successful lookup for member/method of the rtti type. */
+ extern int objectprint;
  
  /* Prototypes for local functions. */
  
***************
*** 428,459 ****
        (*pos) += 3;
        if (noside == EVAL_SKIP)
  	goto nosideret;
-       if (noside == EVAL_AVOID_SIDE_EFFECTS)
- 	{
- 	  struct symbol *sym = exp->elts[pc + 2].symbol;
- 	  enum lval_type lv;
- 
- 	  switch (SYMBOL_CLASS (sym))
- 	    {
- 	    case LOC_CONST:
- 	    case LOC_LABEL:
- 	    case LOC_CONST_BYTES:
- 	      lv = not_lval;
- 	      break;
  
! 	    case LOC_REGISTER:
! 	    case LOC_REGPARM:
! 	      lv = lval_register;
! 	      break;
  
- 	    default:
- 	      lv = lval_memory;
- 	      break;
- 	    }
- 
- 	  return value_zero (SYMBOL_TYPE (sym), lv);
- 	}
-       else
  	return value_of_variable (exp->elts[pc + 2].symbol,
  				  exp->elts[pc + 1].block);
  
--- 431,446 ----
        (*pos) += 3;
        if (noside == EVAL_SKIP)
  	goto nosideret;
  
!       /* JYG: We used to just return value_zero of the symbol type
! 	 if we're asked to avoid side effects.  Otherwise we return
! 	 value_of_variable (...).  However I'm not sure if
! 	 value_of_variable () has any side effect.
! 	 We need a full value object returned here for whatis_exp ()
! 	 to call evaluate_type () and then pass the full value to
! 	 value_rtti_target_type () if we are dealing with a pointer
! 	 or reference to a base class and print object is on. */
  
        return value_of_variable (exp->elts[pc + 2].symbol,
  				exp->elts[pc + 1].block);
  
***************
*** 1051,1056 ****
--- 1038,1068 ----
        arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
        if (noside == EVAL_SKIP)
  	goto nosideret;
+ 
+       /* 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. */
+       {
+         struct type *type = VALUE_TYPE (arg1);
+         struct type *real_type;
+         int full, top, using_enc;
+         
+         if (objectprint &&
+             (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+           {
+             real_type = value_rtti_target_type (arg1, &full, &top, &using_enc);
+             if (real_type)
+               {
+                 if (TYPE_CODE (type) == TYPE_CODE_PTR)
+                   real_type = lookup_pointer_type (real_type);
+                 else
+                   real_type = lookup_reference_type (real_type);
+ 
+                 arg1 = value_cast (real_type, arg1);
+               }
+           }
+       }
+ 
        if (noside == EVAL_AVOID_SIDE_EFFECTS)
  	return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
  						   &exp->elts[pc + 2].string,
Index: typeprint.c
/usr/local/bin/diff -c -w -L typeprint.c typeprint.c@@/main/cygnus/6 typeprint.c
*** typeprint.c
--- typeprint.c	Thu Mar 16 09:59:00 2000
***************
*** 82,87 ****
--- 82,88 ----
    register value_ptr val;
    register struct cleanup *old_chain = NULL;
    struct type *real_type = NULL;
+   struct type *type;
    int full = 0;
    int top = -1;
    int using_enc = 0;
***************
*** 96,112 ****
    else
      val = access_value_history (0);
  
    real_type = value_rtti_type (val, &full, &top, &using_enc);
  
    printf_filtered ("type = ");
  
!   if (real_type && objectprint)
!     printf_filtered ("/* real type = %s%s */\n",
! 		     TYPE_NAME (real_type),
! 		     full ? "" : " (incomplete object)");
!   /* FIXME: maybe better to use type_print (real_type, "", gdb_stdout, -1); */
  
!   type_print (VALUE_TYPE (val), "", gdb_stdout, show);
    printf_filtered ("\n");
  
    if (exp)
--- 97,136 ----
    else
      val = access_value_history (0);
  
+   type = VALUE_TYPE (val);
+ 
+   if (objectprint)
+     {
+       if (((TYPE_CODE (type) == TYPE_CODE_PTR) ||
+            (TYPE_CODE (type) == TYPE_CODE_REF))
+           &&
+           (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+         {
+           real_type = value_rtti_target_type (val, &full, &top, &using_enc);
+           if (real_type)
+             {
+               if (TYPE_CODE (type) == TYPE_CODE_PTR)
+                 real_type = lookup_pointer_type (real_type);
+               else
+                 real_type = lookup_reference_type (real_type);
+             }
+         }
+       else if (TYPE_CODE (type) == TYPE_CODE_CLASS)
          real_type = value_rtti_type (val, &full, &top, &using_enc);
+     }
  
    printf_filtered ("type = ");
  
!   if (real_type)
!     {
!       printf_filtered ("/* real type = ");
!       type_print (real_type, "", gdb_stdout, -1);
!       if (! full)
!         printf_filtered (" (incomplete object)");
!       printf_filtered (" */\n");    
!     }
  
!   type_print (type, "", gdb_stdout, show);
    printf_filtered ("\n");
  
    if (exp)
Index: valops.c
/usr/local/bin/diff -c -w -L valops.c valops.c@@/main/cygnus/15 valops.c
*** valops.c
--- valops.c	Thu Mar 16 10:01:30 2000
***************
*** 326,331 ****
--- 326,337 ----
  		      value_ptr v2 = value_ind (arg2);
  		      VALUE_ADDRESS (v2) -= VALUE_ADDRESS (v)
  			+ VALUE_OFFSET (v);
+ 
+                       /* JYG: adjust the new pointer value and
+ 			 embedded offset. */
+                       v2->aligner.contents[0] -=  VALUE_EMBEDDED_OFFSET (v);
+                       VALUE_EMBEDDED_OFFSET (v2) = 0;
+ 
  		      v2 = value_addr (v2);
  		      VALUE_TYPE (v2) = type;
  		      return v2;

WARNING: multiple messages have this Message-ID
From: Jimmy Guo <guo@cup.hp.com>
To: "Daniel Berlin+mail.gdb" <dan@cgsoftware.com>
Cc: gdb@sourceware.cygnus.com
Subject: Re: RTTI working for G++
Date: Sat, 01 Apr 2000 00:00:00 -0000	[thread overview]
Message-ID: <Pine.LNX.4.10.10003161127110.4096-100000@hpcll168.cup.hp.com> (raw)
Message-ID: <20000401000000.uZCn_FfqZBbFKBKZsSxouaIzMoEP5EiWQogCtYcIx8s@z> (raw)
In-Reply-To: <k8j3bkp2.fsf@dan.resnet.rochester.edu>

>> ... However, one of the fixes was that when print
>> object is on, and one wants to print member / methods of the derived
>> type, you can now do so. 
>
>See, i didn't consider that a bug, i considered it a lacking
>feature. It just wasn't doing the lookup it would need to do, and i've
>been too busy to fix it.

If 'print foo' says it's a pointer to something, and 'print foo->a' says
'There is no member or method named a.', it's very confusing to the
user.  When print object is on, this could happen.  I'd be more willing
to say it's a bug, since the error message contradicts with what print
says and just misleads user ('which one should I believe from this
debugger?').

The fix is in eval.c (evaluate_subexp_standard): it needs to know if
objectprint is set, and if so, return the pointer to the rtti type when
dealing with STUCTOP_PTR (if target type code is TYPE_CODE_CLASS).

>> Besides, there're some fixes to handle pointer
>> to a derived type and explicit casting of a pointer to a base to a
>> derived type. 
>
>This i ran up against. I also handled reference types (By pretending
>they were pointers).

Actually the example you gave at the end of this email looks like
something I fixed, in the casting code.  I'm not familiar with
value_rtti_type and don't quite understand what you were dealing with --
full, etc. are all reset to initial values upon entry into
value_rtti_type ().

>Did you notice that it's not really fun to use value_nid (damn
>flyspell keeps "correcting" the IND to nid, as if "nid" was really a word
>either.) in value_rtti_type? value_nid will call the RTTI routine
>during it's lazy evaluation, which gets you into a recursive nightmare
>if you aren't careful.

I wasn't adventuring into that area since I'm looking at the higher
layer of the proper handling of casting, printing, and expression
evaluation.

>I'd be glad to incorporate your fixes into my patch, and i'd
>appreciate it if you'd look at mine.
>I'll post it to gdb-patches in a few days.

Mine is enclosed in this email.

>I'm a little confused about the semantics of using_enc/full/top in value_rtti_type.
>
>It seems if i set full to 0, on multiple inheritance, it gets the name
>right, but the offset wrong, so you have the right name, and the wrong
>values.
>If i set full to 1, it gets the name wrong ("suspicious *", which
>means it couldn't look it up right), but the values right.

See if my changes to c-valprint.c and valops.c solved your problem.  I
think at least part of the problem is that the pointer value was _not_
adjusted when you change the type of the thing to a rtti type, which is
fixed in these two files.  c-valprint.c deals with printing the pointer
value itself; valops.c deals with printing a member of the pointer value.

Patch follows (the change to typeprint.c probably conflicts with your
version, and I like the output you provided).

- Jimmy Guo, guo@cup.hp.com

Thu Mar 16 15:49:56 2000	Jimmy guo	<guo@cup.hp.com>

	* c-valprint.c (c_value_print): adjust pointer value when
	objectprint is set and pointer type is changed to point to the
	rtti type.

	* eval.c (evaluate_subexp_standard): for OP_VAR_VALUE, always
	return full value object; for STRUCTOP_PTR, use pointer to
	rtti type to get member / method if objectprint is set and
	target type of pointer is class.

	* typeprint.c (whatis_exp): if objectprint is set and exp is of
	pointer / reference type to a class object, look up and print
	the pointer / reference to rtti type.

	* valops.c (value_cast): when casting a pointer / reference type
	of a class object to pointer / refer to its rtti type, adjust
	the new pointer value accordingly.


Index: c-valprint.c
/usr/local/bin/diff -c -w -L c-valprint.c c-valprint.c@@/main/cygnus/7 c-valprint.c
*** c-valprint.c
--- c-valprint.c	Thu Mar 16 10:21:16 2000
***************
*** 497,502 ****
--- 497,505 ----
                    /* create a reference type referencing the real type */
                    type = lookup_reference_type (real_type);
                  }
+ 	      /* JYG: Need to adjust pointer value. */
+               val->aligner.contents[0] -= top;
+ 
                /* Note: When we look up RTTI entries, we don't get any 
                   information on const or volatile attributes */
              }
Index: eval.c
/usr/local/bin/diff -c -w -L eval.c eval.c@@/main/cygnus/9 eval.c
*** eval.c
--- eval.c	Thu Mar 16 15:41:34 2000
***************
*** 37,42 ****
--- 37,45 ----
  /* This is defined in valops.c */
  extern int overload_resolution;
  
+ /* JYG: lookup rtti type of STRUCTOP_PTR when this is set to continue
+    on with successful lookup for member/method of the rtti type. */
+ extern int objectprint;
  
  /* Prototypes for local functions. */
  
***************
*** 428,459 ****
        (*pos) += 3;
        if (noside == EVAL_SKIP)
  	goto nosideret;
-       if (noside == EVAL_AVOID_SIDE_EFFECTS)
- 	{
- 	  struct symbol *sym = exp->elts[pc + 2].symbol;
- 	  enum lval_type lv;
- 
- 	  switch (SYMBOL_CLASS (sym))
- 	    {
- 	    case LOC_CONST:
- 	    case LOC_LABEL:
- 	    case LOC_CONST_BYTES:
- 	      lv = not_lval;
- 	      break;
  
! 	    case LOC_REGISTER:
! 	    case LOC_REGPARM:
! 	      lv = lval_register;
! 	      break;
  
- 	    default:
- 	      lv = lval_memory;
- 	      break;
- 	    }
- 
- 	  return value_zero (SYMBOL_TYPE (sym), lv);
- 	}
-       else
  	return value_of_variable (exp->elts[pc + 2].symbol,
  				  exp->elts[pc + 1].block);
  
--- 431,446 ----
        (*pos) += 3;
        if (noside == EVAL_SKIP)
  	goto nosideret;
  
!       /* JYG: We used to just return value_zero of the symbol type
! 	 if we're asked to avoid side effects.  Otherwise we return
! 	 value_of_variable (...).  However I'm not sure if
! 	 value_of_variable () has any side effect.
! 	 We need a full value object returned here for whatis_exp ()
! 	 to call evaluate_type () and then pass the full value to
! 	 value_rtti_target_type () if we are dealing with a pointer
! 	 or reference to a base class and print object is on. */
  
        return value_of_variable (exp->elts[pc + 2].symbol,
  				exp->elts[pc + 1].block);
  
***************
*** 1051,1056 ****
--- 1038,1068 ----
        arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
        if (noside == EVAL_SKIP)
  	goto nosideret;
+ 
+       /* 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. */
+       {
+         struct type *type = VALUE_TYPE (arg1);
+         struct type *real_type;
+         int full, top, using_enc;
+         
+         if (objectprint &&
+             (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+           {
+             real_type = value_rtti_target_type (arg1, &full, &top, &using_enc);
+             if (real_type)
+               {
+                 if (TYPE_CODE (type) == TYPE_CODE_PTR)
+                   real_type = lookup_pointer_type (real_type);
+                 else
+                   real_type = lookup_reference_type (real_type);
+ 
+                 arg1 = value_cast (real_type, arg1);
+               }
+           }
+       }
+ 
        if (noside == EVAL_AVOID_SIDE_EFFECTS)
  	return value_zero (lookup_struct_elt_type (VALUE_TYPE (arg1),
  						   &exp->elts[pc + 2].string,
Index: typeprint.c
/usr/local/bin/diff -c -w -L typeprint.c typeprint.c@@/main/cygnus/6 typeprint.c
*** typeprint.c
--- typeprint.c	Thu Mar 16 09:59:00 2000
***************
*** 82,87 ****
--- 82,88 ----
    register value_ptr val;
    register struct cleanup *old_chain = NULL;
    struct type *real_type = NULL;
+   struct type *type;
    int full = 0;
    int top = -1;
    int using_enc = 0;
***************
*** 96,112 ****
    else
      val = access_value_history (0);
  
    real_type = value_rtti_type (val, &full, &top, &using_enc);
  
    printf_filtered ("type = ");
  
!   if (real_type && objectprint)
!     printf_filtered ("/* real type = %s%s */\n",
! 		     TYPE_NAME (real_type),
! 		     full ? "" : " (incomplete object)");
!   /* FIXME: maybe better to use type_print (real_type, "", gdb_stdout, -1); */
  
!   type_print (VALUE_TYPE (val), "", gdb_stdout, show);
    printf_filtered ("\n");
  
    if (exp)
--- 97,136 ----
    else
      val = access_value_history (0);
  
+   type = VALUE_TYPE (val);
+ 
+   if (objectprint)
+     {
+       if (((TYPE_CODE (type) == TYPE_CODE_PTR) ||
+            (TYPE_CODE (type) == TYPE_CODE_REF))
+           &&
+           (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
+         {
+           real_type = value_rtti_target_type (val, &full, &top, &using_enc);
+           if (real_type)
+             {
+               if (TYPE_CODE (type) == TYPE_CODE_PTR)
+                 real_type = lookup_pointer_type (real_type);
+               else
+                 real_type = lookup_reference_type (real_type);
+             }
+         }
+       else if (TYPE_CODE (type) == TYPE_CODE_CLASS)
          real_type = value_rtti_type (val, &full, &top, &using_enc);
+     }
  
    printf_filtered ("type = ");
  
!   if (real_type)
!     {
!       printf_filtered ("/* real type = ");
!       type_print (real_type, "", gdb_stdout, -1);
!       if (! full)
!         printf_filtered (" (incomplete object)");
!       printf_filtered (" */\n");    
!     }
  
!   type_print (type, "", gdb_stdout, show);
    printf_filtered ("\n");
  
    if (exp)
Index: valops.c
/usr/local/bin/diff -c -w -L valops.c valops.c@@/main/cygnus/15 valops.c
*** valops.c
--- valops.c	Thu Mar 16 10:01:30 2000
***************
*** 326,331 ****
--- 326,337 ----
  		      value_ptr v2 = value_ind (arg2);
  		      VALUE_ADDRESS (v2) -= VALUE_ADDRESS (v)
  			+ VALUE_OFFSET (v);
+ 
+                       /* JYG: adjust the new pointer value and
+ 			 embedded offset. */
+                       v2->aligner.contents[0] -=  VALUE_EMBEDDED_OFFSET (v);
+                       VALUE_EMBEDDED_OFFSET (v2) = 0;
+ 
  		      v2 = value_addr (v2);
  		      VALUE_TYPE (v2) = type;
  		      return v2;

  reply	other threads:[~2000-03-16 15:53 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-03-13 16:53 Daniel Berlin
2000-03-15 13:20 ` Jimmy Guo
2000-03-15 20:33   ` Daniel Berlin+mail.gdb
2000-03-16 15:53     ` Jimmy Guo [this message]
2000-03-16 16:29       ` Jimmy Guo
2000-04-01  0:00         ` Jimmy Guo
2000-04-01  0:00       ` Jimmy Guo
2000-04-01  0:00     ` Daniel Berlin+mail.gdb
2000-04-01  0:00   ` Jimmy Guo
2000-04-01  0:00 ` Daniel Berlin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.10.10003161127110.4096-100000@hpcll168.cup.hp.com \
    --to=guo@cup.hp.com \
    --cc=dan@cgsoftware.com \
    --cc=gdb@sourceware.cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).