static bool walk(struct Node *node, cbtree_walker_func cb_func, void *cb_arg) { if (!is_node(node)) return cb_func(cb_arg, get_external(node)); return walk(node->child[0], cb_func, cb_arg) && walk(node->child[1], cb_func, cb_arg); }
/* walk nodes until external pointer is found */ static void *raw_lookup(struct CBTree *tree, const void *key, unsigned klen) { struct Node *node = tree->root; unsigned bit; while (is_node(node)) { bit = get_bit(node->bitpos, key, klen); node = node->child[bit]; } return get_external(node); }
/* recursive freeing */ static void destroy_node(struct CBTree *tree, struct Node *node) { if (is_node(node)) { destroy_node(tree, node->child[0]); destroy_node(tree, node->child[1]); cx_free(tree->cx, node); } else if (tree->obj_free_cb) { void *obj = get_external(node); tree->obj_free_cb(tree->cb_ctx, obj); } }
bool AdminNetNodeAdd::commit(AdminState* admin) throw (admin_error) { AdminNetNodeBase::commit(admin); AdminState::WriteLockRecord net_rec = get_net_write(); NetStatePtr net = boost::dynamic_pointer_cast<NetState>(net_rec.first); NetVertex v; bool ret = net->add_node(get_node(), v, *net_rec.second); if (ret) net->set_external(v, get_external(), *net_rec.second); return ret; }
/* true -> object was found and removed, false -> not found */ bool cbtree_delete(struct CBTree *tree, const void *key, unsigned klen) { void *obj, *tmp; unsigned bit = 0; /* location of current node/obj pointer under examination */ struct Node **pos = &tree->root; /* if 'pos' has user obj, prev_pos has internal node pointing to it */ struct Node **prev_pos = NULL; if (!tree->root) return false; /* match bits we know about */ while (is_node(*pos)) { bit = get_bit((*pos)->bitpos, key, klen); prev_pos = pos; pos = &(*pos)->child[bit]; } /* does the key actually matches */ obj = get_external(*pos); if (!key_matches(tree, obj, key, klen)) return false; if (tree->obj_free_cb) tree->obj_free_cb(tree->cb_ctx, obj); /* drop the internal node pointing to our key */ if (prev_pos) { tmp = *prev_pos; *prev_pos = (*prev_pos)->child[bit ^ 1]; cx_free(tree->cx, tmp); } else { tree->root = NULL; } return true; }
void gather_interface_dies(root_die& root, set<iterator_base>& out, type_set& dedup_types_out, std::function<bool(const iterator_base&)> pred) { /* We want to deduplicate the types that we output, as we go. * CARE: what about anonymous types? We might want to generate names for them * based on their offset, in which case deduplication isn't transparent. * For this reason we output dedup_types_out separately from the DIEs. * However, everything in dedup_types_out is also in out (FIXME: is this a good idea?) */ auto toplevel_seq = root.grandchildren(); type_set& types = dedup_types_out; /* FIXME: it needn't be just grandchildren. */ for (auto i_d = std::move(toplevel_seq.first); i_d != toplevel_seq.second; ++i_d) { if (pred(i_d.base().base())) { // looks like a goer -- add it to the objs out.insert(i_d.base().base()); /* utility that will come in handy */ auto add_all_types = [&types, &root](iterator_df<type_die> outer_t) { walk_type(outer_t, iterator_base::END, [&types, &root](iterator_df<type_die> t, iterator_df<program_element_die> reason) -> bool { if (!t) return false; // void case auto memb = reason.as_a<member_die>(); if (memb && memb->get_declaration() && *memb->get_declaration() && memb->get_external() && *memb->get_external()) { // static member vars don't get added nor recursed on return false; } // apart from that, insert all nonvoids.... auto inserted = types.insert(t); if (!inserted.second) { // cerr << "Type was already present: " << *t // << " (or something equal to it: " << *inserted.first // << ")" << endl; // cerr << "Attributes: " << t->copy_attrs(root) << endl; return false; // was already present } else { cerr << "Inserted new type: " << *t << endl; // cerr << "Attributes: " << t->copy_attrs(root) << endl; return true; } } ); }; /* Also output everything that this depends on. We have to case-split * for now. */ if (i_d.base().base().is_a<subprogram_die>()) { // make sure we have all the relevant types in our set auto i_subp = i_d.base().base().as_a<subprogram_die>(); if (i_subp->find_type()) add_all_types(i_subp->find_type()); auto fps = i_subp->children().subseq_of<formal_parameter_die>(); for (auto i_fp = std::move(fps.first); i_fp != fps.second; ++i_fp) { auto outer_t = i_fp->find_type(); add_all_types(outer_t); } } else if (i_d.base().base().is_a<variable_die>()) { add_all_types(i_d.base().base().as_a<variable_die>()->get_type()); } else if (i_d.base().base().is_a<type_die>()) { /* Just walk it. */ add_all_types(i_d.base().base().as_a<type_die>()); } } // end if pred } // end for /* Now we've gathered everything. Make sure everything in "types" is in * "out". */ for (auto i_d = types.begin(); i_d != types.end(); ++i_d) { out.insert(*i_d); } /* Check that everything that's in "out", if it is a type, is also in * types. */ for (auto i_d = out.begin(); i_d != out.end(); ++i_d) { if (i_d->is_a<type_die>() && !i_d->is_a<subprogram_die>()) { if (types.find(i_d->as_a<type_die>()) == types.end()) { cerr << "BUG: didn't find " << i_d->summary() << " in types list." << endl; } } } }