diff options
author | Josh Stone <jistone@redhat.com> | 2009-08-21 19:16:18 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-08-21 19:16:18 -0700 |
commit | 9c11995121a80bb6f97af1a2cb1fe71ad06b67a9 (patch) | |
tree | 413926dd6e7f1c3212a7e036b9292e53dee6b548 | |
parent | aaf7ffe85f54349200ffb60aff628fb9fe68be75 (diff) | |
download | systemtap-steved-9c11995121a80bb6f97af1a2cb1fe71ad06b67a9.tar.gz systemtap-steved-9c11995121a80bb6f97af1a2cb1fe71ad06b67a9.tar.xz systemtap-steved-9c11995121a80bb6f97af1a2cb1fe71ad06b67a9.zip |
PR10461: Add support for C++ classes and references
* dwarf_wrappers.cxx (dwarf_type_name): Name class and reference types.
* dwflpp.cxx (dwflpp::iterate_over_globals): Capture class names.
(dwflpp::print_members): Permit classes, and dig into inheritance.
(dwflpp::find_struct_member): Ditto.
(dwflpp::translate_components): Handle classes and references.
(dwflpp::translate_final_fetch_or_store): Ditto.
* loc2c.c (c_translate_pointer): Treat references as simple pointers.
-rw-r--r-- | dwarf_wrappers.cxx | 56 | ||||
-rw-r--r-- | dwflpp.cxx | 46 | ||||
-rw-r--r-- | loc2c.c | 4 |
3 files changed, 81 insertions, 25 deletions
diff --git a/dwarf_wrappers.cxx b/dwarf_wrappers.cxx index 7b64aac5..72c406f1 100644 --- a/dwarf_wrappers.cxx +++ b/dwarf_wrappers.cxx @@ -91,7 +91,7 @@ dwarf_decl_line_integrate (Dwarf_Die *die, int *linep) static bool -dwarf_type_name(Dwarf_Die *type_die, ostringstream& o) +dwarf_type_name(Dwarf_Die *type_die, ostream& o) { // if we've gotten down to a basic type, then we're done bool done = true; @@ -106,12 +106,26 @@ dwarf_type_name(Dwarf_Die *type_die, ostringstream& o) case DW_TAG_union_type: o << "union "; break; + case DW_TAG_class_type: + o << "class "; + break; case DW_TAG_typedef: case DW_TAG_base_type: break; - default: + + // modifier types that require recursion first + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: + case DW_TAG_pointer_type: + case DW_TAG_array_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: done = false; break; + + // unknown tag + default: + return false; } if (done) { @@ -124,14 +138,33 @@ dwarf_type_name(Dwarf_Die *type_die, ostringstream& o) // otherwise, this die is a type modifier. // recurse into the referent type + Dwarf_Die subtype_die_mem, *subtype_die; + subtype_die = dwarf_attr_die(type_die, DW_AT_type, &subtype_die_mem); + + // NB: va_list is a builtin type that shows up in the debuginfo as a + // "struct __va_list_tag*", but it has to be called only va_list. + if (subtype_die != NULL && + dwarf_tag(type_die) == DW_TAG_pointer_type && + dwarf_tag(subtype_die) == DW_TAG_structure_type && + strcmp(dwarf_diename(subtype_die) ?: "", "__va_list_tag") == 0) + { + o << "va_list"; + return true; + } + // if it can't be named, just call it "void" - Dwarf_Die subtype_die; - if (!dwarf_attr_die(type_die, DW_AT_type, &subtype_die) - || !dwarf_type_name(&subtype_die, o)) - o.str("void"), o.seekp(4); + if (subtype_die == NULL || + !dwarf_type_name(subtype_die, o)) + o << "void"; switch (dwarf_tag(type_die)) { + case DW_TAG_reference_type: + o << "&"; + break; + case DW_TAG_rvalue_reference_type: + o << "&&"; + break; case DW_TAG_pointer_type: o << "*"; break; @@ -139,7 +172,12 @@ dwarf_type_name(Dwarf_Die *type_die, ostringstream& o) o << "[]"; break; case DW_TAG_const_type: - o << " const"; + // NB: the debuginfo may sometimes have an extra const tag + // on reference types, which is redundant to us. + if (subtype_die == NULL || + (dwarf_tag(subtype_die) != DW_TAG_reference_type && + dwarf_tag(subtype_die) != DW_TAG_rvalue_reference_type)) + o << " const"; break; case DW_TAG_volatile_type: o << " volatile"; @@ -148,10 +186,6 @@ dwarf_type_name(Dwarf_Die *type_die, ostringstream& o) return false; } - // XXX HACK! The va_list isn't usable as found in the debuginfo... - if (o.str() == "struct __va_list_tag*") - o.str("va_list"), o.seekp(7); - return true; } @@ -686,6 +686,7 @@ dwflpp::iterate_over_globals (int (* callback)(Dwarf_Die *, void *), case DW_TAG_base_type: case DW_TAG_enumeration_type: case DW_TAG_structure_type: + case DW_TAG_class_type: case DW_TAG_typedef: case DW_TAG_union_type: rc = (*callback)(&die, data); @@ -1539,11 +1540,13 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) { const int typetag = dwarf_tag (vardie); - if (typetag != DW_TAG_structure_type && typetag != DW_TAG_union_type) + if (typetag != DW_TAG_structure_type && + typetag != DW_TAG_class_type && + typetag != DW_TAG_union_type) { o << " Error: " << dwarf_type_name(vardie) - << " isn't a struct/union"; + << " isn't a struct/class/union"; return; } @@ -1568,11 +1571,15 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) } // Output each sibling's name to 'o'. - while (dwarf_tag (die) == DW_TAG_member) + do { + int tag = dwarf_tag(die); + if (tag != DW_TAG_member && tag != DW_TAG_inheritance) + continue; + const char *member = dwarf_diename (die) ; - if ( member != NULL ) + if ( tag == DW_TAG_member && member != NULL ) o << " " << member; else { @@ -1590,9 +1597,8 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) print_members(&temp_die,o); } - if (dwarf_siblingof (die, &die_mem) != 0) - break; } + while (dwarf_siblingof (die, die) == 0); } @@ -1620,13 +1626,15 @@ dwflpp::find_struct_member(const target_symbol::component& c, do { - if (dwarf_tag(&die) != DW_TAG_member) + int tag = dwarf_tag(&die); + if (tag != DW_TAG_member && tag != DW_TAG_inheritance) continue; const char *name = dwarf_diename(&die); - if (name == NULL) + if (name == NULL || tag == DW_TAG_inheritance) { - // need to recurse for anonymous structs/unions + // need to recurse for anonymous structs/unions and + // for inherited members Dwarf_Die subdie; if (dwarf_attr_die (&die, DW_AT_type, &subdie) && find_struct_member(c, &subdie, memberdie, locs)) @@ -1701,6 +1709,11 @@ dwflpp::translate_components(struct obstack *pool, /* Just iterate on the referent type. */ break; + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: + c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail); + break; + case DW_TAG_pointer_type: /* A pointer with no type is a void* -- can't dereference it. */ if (!dwarf_hasattr_integrate (die, DW_AT_type)) @@ -1737,6 +1750,7 @@ dwflpp::translate_components(struct obstack *pool, case DW_TAG_structure_type: case DW_TAG_union_type: + case DW_TAG_class_type: if (c.type != target_symbol::comp_struct_member) throw semantic_error ("invalid access '" + lex_cast<string>(c) @@ -1891,12 +1905,13 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, default: throw semantic_error ("unsupported type tag " + lex_cast<string>(typetag) - + " for " + dwarf_type_name(die), e->tok); + + " for " + dwarf_type_name(typedie), e->tok); break; case DW_TAG_structure_type: + case DW_TAG_class_type: case DW_TAG_union_type: - throw semantic_error ("'" + dwarf_type_name(die) + throw semantic_error ("'" + dwarf_type_name(typedie) + "' is being accessed instead of a member", e->tok); break; @@ -1913,7 +1928,7 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, { // clog << "bad type1 " << encoding << " diestr" << endl; throw semantic_error ("unsupported type (mystery encoding " + lex_cast<string>(encoding) + ")" + - " for " + dwarf_type_name(die), e->tok); + " for " + dwarf_type_name(typedie), e->tok); } if (encoding == DW_ATE_float @@ -1922,7 +1937,7 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, { // clog << "bad type " << encoding << " diestr" << endl; throw semantic_error ("unsupported type (encoding " + lex_cast<string>(encoding) + ")" + - " for " + dwarf_type_name(die), e->tok); + " for " + dwarf_type_name(typedie), e->tok); } } @@ -1937,6 +1952,8 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, case DW_TAG_array_type: case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: { Dwarf_Die pointee_typedie_mem; @@ -1957,6 +1974,9 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, ty = pe_long; if (typetag == DW_TAG_array_type) throw semantic_error ("cannot write to array address", e->tok); + if (typetag == DW_TAG_reference_type || + typetag == DW_TAG_rvalue_reference_type) + throw semantic_error ("cannot write to reference", e->tok); assert (typetag == DW_TAG_pointer_type); c_translate_pointer_store (pool, 1, 0 /* PR9768 */, typedie, tail, "THIS->value"); @@ -1612,7 +1612,9 @@ c_translate_pointer (struct obstack *pool, int indent, Dwarf_Addr dwbias __attribute__ ((unused)), Dwarf_Die *typedie, struct location **input) { - assert (dwarf_tag (typedie) == DW_TAG_pointer_type); + assert (dwarf_tag (typedie) == DW_TAG_pointer_type || + dwarf_tag (typedie) == DW_TAG_reference_type || + dwarf_tag (typedie) == DW_TAG_rvalue_reference_type); Dwarf_Attribute attr_mem; Dwarf_Word byte_size; |