diff options
Diffstat (limited to 'elfutils/libdw/libdw_visit_scopes.c')
-rw-r--r-- | elfutils/libdw/libdw_visit_scopes.c | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/elfutils/libdw/libdw_visit_scopes.c b/elfutils/libdw/libdw_visit_scopes.c index 06168fb1..3b92ea09 100644 --- a/elfutils/libdw/libdw_visit_scopes.c +++ b/elfutils/libdw/libdw_visit_scopes.c @@ -46,59 +46,82 @@ classify_die (Dwarf_Die *die) } int -__libdw_visit_scopes (depth, root, visit, arg) +__libdw_visit_scopes (depth, root, previsit, postvisit, arg) unsigned int depth; - Dwarf_Die *root; - int (*visit) (unsigned int depth, Dwarf_Die *die, void *arg); + struct Dwarf_Die_Chain *root; + int (*previsit) (unsigned int depth, struct Dwarf_Die_Chain *, void *); + int (*postvisit) (unsigned int depth, struct Dwarf_Die_Chain *, void *); void *arg; { - Dwarf_Die child; - if (INTUSE(dwarf_child) (root, &child) != 0) + struct Dwarf_Die_Chain child; + + child.parent = root; + if (INTUSE(dwarf_child) (&root->die, &child.die) != 0) return -1; + inline int recurse (void) + { + return __libdw_visit_scopes (depth + 1, &child, + previsit, postvisit, arg); + } + do { - int result = (*visit) (depth, &child, arg); - if (result != DWARF_CB_OK) - return result; + child.prune = false; - switch (classify_die (&child)) + if (previsit != NULL) { - case match: - case match_inline: - case walk: - if (INTUSE(dwarf_haschildren) (&child)) - { - result = __libdw_visit_scopes (depth + 1, &child, visit, arg); - if (result != DWARF_CB_OK) - return result; - } - break; + int result = (*previsit) (depth + 1, &child, arg); + if (result != DWARF_CB_OK) + return result; + } - case imported: + if (!child.prune) + switch (classify_die (&child.die)) { - /* This is imports another compilation unit to appear - as part of this one, inside the current scope. - Recurse to searesulth the referenced unit, but without - recording it as an inner scoping level. */ - - Dwarf_Attribute attr_mem; - Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child, DW_AT_import, - &attr_mem); - if (INTUSE(dwarf_formref_die) (attr, &child) != NULL) + case match: + case match_inline: + case walk: + if (INTUSE(dwarf_haschildren) (&child.die)) { - result = __libdw_visit_scopes (depth + 1, &child, visit, arg); - if (result != 0) + int result = recurse (); + if (result != DWARF_CB_OK) return result; } + break; + + case imported: + { + /* This imports another compilation unit to appear + as part of this one, inside the current scope. + Recurse to search the referenced unit, but without + recording it as an inner scoping level. */ + + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&child.die, + DW_AT_import, + &attr_mem); + if (INTUSE(dwarf_formref_die) (attr, &child.die) != NULL) + { + int result = recurse (); + if (result != DWARF_CB_OK) + return result; + } + } + break; + + default: + break; } - break; - default: - break; + if (postvisit != NULL) + { + int result = (*postvisit) (depth + 1, &child, arg); + if (result != DWARF_CB_OK) + return result; } } - while (INTUSE(dwarf_siblingof) (&child, &child) == 0); + while (INTUSE(dwarf_siblingof) (&child.die, &child.die) == 0); return 0; } |