-static void callee_ana_node(ir_node * node, eset * methods) {
- int i;
-
- assert((get_irn_mode(node) == mode_P) || is_Bad(node));
- /* rekursion verhindern */
- if (get_irn_link(node) == MARK) {
- /* already visited */
- return;
- }
- set_irn_link(node, MARK);
-
- switch (get_irn_opcode(node)) {
- case iro_SymConst:
- /* externe Methode (wegen fix_symconst!) */
- eset_insert(methods, MARK); /* free method -> unknown */
- break;
-
- case iro_Const: {
- /* interne Methode */
- entity * ent = get_Const_tarval(node)->u.P.ent;
- assert(ent && is_method_type(get_entity_type(ent)));
- if (get_entity_visibility(ent) != external_allocated) {
- assert(get_entity_irg(ent));
- eset_insert(methods, ent);
- } else {
- eset_insert(methods, MARK); /* free method -> unknown */
- }
- break;
- }
-
- case iro_Sel:
- /* polymorphe Methode */
- for (i = get_Sel_n_methods(node) - 1; i >= 0; --i) {
- entity * ent = get_Sel_method(node, i);
- if (ent) {
- eset_insert(methods, ent);
- } else {
- eset_insert(methods, MARK);
- }
- }
- break;
-
- case iro_Bad:
- /* nothing */
- break;
-
- case iro_Phi: /* Vereinigung */
- for (i = get_Phi_n_preds(node) - 1; i >= 0; --i) {
- callee_ana_node(get_Phi_pred(node, i), methods);
- }
- break;
-
- case iro_Id:
- callee_ana_node(get_Id_pred(node), methods);
- break;
-
- case iro_Proj:
- callee_ana_proj(get_Proj_pred(node), get_Proj_proj(node), methods);
- break;
-
- case iro_Add:
- case iro_Sub:
- case iro_Conv:
- /* extern */
- eset_insert(methods, MARK); /* free method -> unknown */
- break;
-
- default:
- assert(0 && "invalid opcode or opcode not implemented");
- break;
- }
-
- set_irn_link(node, NULL);
-}
-