diff options
author | Chih-Hung Hsieh <chh@google.com> | 2015-10-14 12:23:34 -0700 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2016-01-02 14:14:00 +0100 |
commit | 454a82803be4694d40942c533bc0b2485d9e264d (patch) | |
tree | 17a42fcca659fae783c815b3db47f0aa66f46163 | |
parent | e2cf85cd35d33f92ff3d032e941783238a8fdaa1 (diff) | |
download | elfutils-454a82803be4694d40942c533bc0b2485d9e264d.tar.gz |
Move nested functions in libdw_visit_scopes.c to file scope.
* No nested functions to compile with clang/llvm.
Signed-off-by: Chih-Hung Hsieh <chh@google.com>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r-- | libdw/ChangeLog | 6 | ||||
-rw-r--r-- | libdw/libdw_visit_scopes.c | 160 |
2 files changed, 95 insertions, 71 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 4d024492..8fd77f40 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,9 @@ +2015-10-14 Chih-Hung Hsieh <chh@google.com> + + * libdw_visit_scopes.c (__libdw_visit_scopes): Move recursive nested + function 'walk_children' to file scope; inline 'recurse' at its call + site. + 2015-10-19 Mark Wielaard <mjw@redhat.com> * frame-cache.c (__libdw_destroy_frame_cache): Call ebl_closebackend diff --git a/libdw/libdw_visit_scopes.c b/libdw/libdw_visit_scopes.c index 5e5c26fd..eb892e10 100644 --- a/libdw/libdw_visit_scopes.c +++ b/libdw/libdw_visit_scopes.c @@ -64,6 +64,21 @@ may_have_scopes (Dwarf_Die *die) return false; } +struct walk_children_state +{ + /* Parameters of __libdw_visit_scopes. */ + unsigned int depth; + struct Dwarf_Die_Chain *imports; + int (*previsit) (unsigned int depth, struct Dwarf_Die_Chain *, void *); + int (*postvisit) (unsigned int depth, struct Dwarf_Die_Chain *, void *); + void *arg; + /* Extra local variables for the walker. */ + struct Dwarf_Die_Chain child; +}; + +static inline int +walk_children (struct walk_children_state *state); + int internal_function __libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root, @@ -76,95 +91,98 @@ __libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root, void *), void *arg) { - struct Dwarf_Die_Chain child; + struct walk_children_state state = + { + .depth = depth, + .imports = imports, + .previsit = previsit, + .postvisit = postvisit, + .arg = arg + }; + + state.child.parent = root; int ret; - - child.parent = root; - if ((ret = INTUSE(dwarf_child) (&root->die, &child.die)) != 0) + if ((ret = INTUSE(dwarf_child) (&root->die, &state.child.die)) != 0) return ret < 0 ? -1 : 0; // Having zero children is legal. - inline int recurse (void) - { - return __libdw_visit_scopes (depth + 1, &child, imports, - previsit, postvisit, arg); - } - - /* Checks the given DIE hasn't been imported yet to prevent cycles. */ - inline bool imports_contains (Dwarf_Die *die) - { - for (struct Dwarf_Die_Chain *import = imports; import != NULL; - import = import->parent) - if (import->die.addr == die->addr) - return true; - - return false; - } + return walk_children (&state); +} - inline int walk_children (void) +static inline int +walk_children (struct walk_children_state *state) { - do - { - /* For an imported unit, it is logically as if the children of - that unit are siblings of the other children. So don't do - a full recursion into the imported unit, but just walk the - children in place before moving to the next real child. */ - while (INTUSE(dwarf_tag) (&child.die) == DW_TAG_imported_unit) - { - Dwarf_Die orig_child_die = child.die; - 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 - && INTUSE(dwarf_child) (&child.die, &child.die) == 0) - { - if (imports_contains (&orig_child_die)) - { - __libdw_seterrno (DWARF_E_INVALID_DWARF); - return -1; - } - struct Dwarf_Die_Chain *orig_imports = imports; - struct Dwarf_Die_Chain import = { .die = orig_child_die, - .parent = orig_imports }; - imports = &import; - int result = walk_children (); - imports = orig_imports; - if (result != DWARF_CB_OK) - return result; - } - - /* Any "real" children left? */ - if ((ret = INTUSE(dwarf_siblingof) (&orig_child_die, - &child.die)) != 0) - return ret < 0 ? -1 : 0; - }; - - child.prune = false; + int ret; + do + { + /* For an imported unit, it is logically as if the children of + that unit are siblings of the other children. So don't do + a full recursion into the imported unit, but just walk the + children in place before moving to the next real child. */ + while (INTUSE(dwarf_tag) (&state->child.die) == DW_TAG_imported_unit) + { + Dwarf_Die orig_child_die = state->child.die; + Dwarf_Attribute attr_mem; + Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&state->child.die, + DW_AT_import, + &attr_mem); + if (INTUSE(dwarf_formref_die) (attr, &state->child.die) != NULL + && INTUSE(dwarf_child) (&state->child.die, &state->child.die) == 0) + { + /* Checks the given DIE hasn't been imported yet + to prevent cycles. */ + bool imported = false; + for (struct Dwarf_Die_Chain *import = state->imports; import != NULL; + import = import->parent) + if (import->die.addr == orig_child_die.addr) + { + imported = true; + break; + } + if (imported) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } + struct Dwarf_Die_Chain *orig_imports = state->imports; + struct Dwarf_Die_Chain import = { .die = orig_child_die, + .parent = orig_imports }; + state->imports = &import; + int result = walk_children (state); + state->imports = orig_imports; + if (result != DWARF_CB_OK) + return result; + } + + /* Any "real" children left? */ + if ((ret = INTUSE(dwarf_siblingof) (&orig_child_die, + &state->child.die)) != 0) + return ret < 0 ? -1 : 0; + }; + + state->child.prune = false; /* previsit is declared NN */ - int result = (*previsit) (depth + 1, &child, arg); + int result = (*state->previsit) (state->depth + 1, &state->child, state->arg); if (result != DWARF_CB_OK) return result; - if (!child.prune && may_have_scopes (&child.die) - && INTUSE(dwarf_haschildren) (&child.die)) + if (!state->child.prune && may_have_scopes (&state->child.die) + && INTUSE(dwarf_haschildren) (&state->child.die)) { - result = recurse (); + result = __libdw_visit_scopes (state->depth + 1, &state->child, state->imports, + state->previsit, state->postvisit, state->arg); if (result != DWARF_CB_OK) return result; } - if (postvisit != NULL) + if (state->postvisit != NULL) { - result = (*postvisit) (depth + 1, &child, arg); + result = (*state->postvisit) (state->depth + 1, &state->child, state->arg); if (result != DWARF_CB_OK) return result; } - } - while ((ret = INTUSE(dwarf_siblingof) (&child.die, &child.die)) == 0); - - return ret < 0 ? -1 : 0; - } + } + while ((ret = INTUSE(dwarf_siblingof) (&state->child.die, &state->child.die)) == 0); - return walk_children (); + return ret < 0 ? -1 : 0; } |