From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jimmy Guo To: "Daniel Berlin+mail.gdb" Cc: gdb@sourceware.cygnus.com Subject: Re: RTTI working for G++ Date: Sat, 01 Apr 2000 00:00:00 -0000 Message-ID: References: X-SW-Source: 2000-q1/msg00726.html Message-ID: <20000401000000.uZCn_FfqZBbFKBKZsSxouaIzMoEP5EiWQogCtYcIx8s@z> >> ... 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 * 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;