📄 dflow.c
字号:
return; nio = get_arlist(); nio->tn = n; nio->nxt = d->aio; d->aio = nio;}static voidsym_babble(leafnode *leaf, unsigned long mark){ char *q = "--"; scopetab_t *s = (scopetab_t *) 0; if (!leaf) return; if (leaf->syment && leaf->syment->nes) s = leaf->syment->nes; /* name enclosing scope */ fprintf(stdout, "%3d, %s::%s\t", leaf->hdr.line, s?s->owner:"-", nmestr(leaf->data.sval)); if (s) switch (s->owner_t) { case TN_OBJ_DEF: q = "struct/union"; break; case TN_FUNC_DEF: q = "fnct"; break; } fprintf(stdout, "(%s) ", q); dflow_mark(stdout, mark); if (s && leaf->syment) { find_symbol(leaf->syment->nes, leaf->syment); if (s->owner_t == TN_OBJ_DEF) printf(" prior use: %d", leaf->syment->used); } fprintf(stdout, "\n");}DefUse *walk_tree(treenode *child, unsigned long markin){ leafnode *leaf; if_node *ifn; for_node *forn; unsigned long mark = markin; DefUse *d1 = (DefUse *) 0; DefUse *d2 = (DefUse *) 0; char *u = ""; /* first bug found by uno 8/9/2001 */ char *nu; if (0 && child) { printf("%s\t", name_of_node(child->hdr.type)); dflow_mark(stdout, markin); printf("\n"); } if (child) switch (child->hdr.which){ case LEAF_T: leaf = (leafnode *) child; if (leaf->hdr.type == TN_IDENT) { if (0 || (Verbose&2)) sym_babble(leaf, mark); if (leaf->syment) leaf->syment->used = 1; if (!leaf->syment && uno && mark && leaf->data.sval) { symentry_t *t; t = new_symentry(); t->nme = leaf->data.sval; t->node = child; t->fn = child->hdr.fnm; t->used = 1; leaf->syment = t; goto go4it; } if (!leaf->syment || is_typedef(leaf->syment) || (leaf->syment->nes && leaf->syment->nes->owner_t == TN_OBJ_DEF)) /* ?? */ { if (0 || (Verbose&2)) { fprintf(stdout, "--tn_ident - %s -- mark %d\n", nmestr(leaf->data.sval), mark); if (!leaf->syment) fprintf(stdout, "\tignored (zero syment)\n"); else if (!leaf->syment->nes) fprintf(stdout, "\tignored (zero syment->nes)\n"); else fprintf(stdout, "\tignored (%d==%d)\n", leaf->syment->nes->owner_t, TN_OBJ_DEF); } return (DefUse *) 0; /* defuse info not relevant */ } if (0) { fprintf(stdout, "--TN_ident - %s -- mark %d - decl_level %d\t", nmestr(leaf->data.sval), mark, leaf->syment->decl_level); dflow_mark(stdout, mark); printf("\n"); } if (!mark) { if (0) fprintf(stdout, "no mark -- "); if (0) fprintf(stdout, "%d:%s\n", leaf->hdr.line, nmestr(leaf->data.sval)); if (Verbose&2) printf("using default mark\n"); mark |= USE; /* expr with 1 ident */ } if (mark&(REF0|REF1|REF2)) { if (0) fprintf(stdout, "saw a %s: %s\n", (mark&REF1)?"ref1":"ref2", doit(leaf, 0)); if (mark&(REF1|REF0)) /* lhs of struct reference: ref0->x, ref1.x */ { strcat(ref1_pref, doit(leaf, 1)); } else if (mark&REF2) /* rhs of struct reference: x->ref2, x.ref2 */ { strcat(ref1_pref, doit(leaf, 1)); } if (leaf && leaf->syment && leaf->syment->nes && leaf->syment->nes->owner) { if (leaf->syment->nes->owner[0] == '-') u = set_u(leaf->syment, u); else { u = (char *) emalloc(strlen(leaf->syment->nes->owner) +strlen(ref1_pref)+2+1); strcpy(u, leaf->syment->nes->owner); } } else { u = (char *) emalloc(1+strlen(ref1_pref)+2+1); strcpy(u, "-"); } strcat(u, "::"); strcat(u, ref1_pref); strcpy(ref1_pref, ""); goto go4it; } else { nu = doit(leaf, 0); if (nu[0] == '-') { u = set_u(leaf->syment, nu); } else { u = (char *) emalloc(strlen(nu)+1); strcpy(u, nu); }go4it: if (0) { printf("WT %s:%d\t%s\t", child->hdr.fnm, child->hdr.line, nmestr(leaf->data.sval)); dflow_mark(stdout, mark); if (leaf->syment) printf("\t(owner %s) -- (%s)\n", x_stmnt(leaf->syment->container), u); printf(" is prototype: %d\n", is_a_prototype);} d1 = (DefUse *) emalloc(sizeof(DefUse)); if (uno) { if (mark) d1->other = symadd(leaf->syment, mark); } else { d1->special = 0; if (!(mark&FCALL) && strncmp(u, "fct", strlen("fct")) != 0) { if ((mark&USE) && !(mark&ALIAS)) d1->use = symadd(leaf->syment, mark); if ((mark&DEF) && !(mark&DEREF)) d1->def = symadd(leaf->syment, mark); if (mark&(DEREF|ALIAS|DECL|ARRAY_DECL)) d1->other = symadd(leaf->syment, mark); } } } if (0) { fprintf(stderr, "tn_ident - %s -- mark %d\t", nmestr(leaf->data.sval), mark); dump_defuse(d1, stderr); fprintf(stderr, "\n"); } return d1; } break; case IF_T: ifn = (if_node *) child; switch (ifn->hdr.type) { case TN_IF: d1 = walk_tree(ifn->cond, mark|USE); attach_defuse(ifn->cond, "if_cond", d1); /* was child i.s.o. ifn->cond */ d2 = walk_tree(ifn->then_n, mark); d1 = merge_lists(d1, d2); d2 = walk_tree(ifn->else_n, mark); break; case TN_COND_EXPR: d1 = walk_tree(ifn->cond, mark|USE); d2 = walk_tree(ifn->then_n, mark); d1 = merge_lists(d1, d2); d2 = walk_tree(ifn->else_n, mark); /* alas an uninit var in the else branch can be obscured by an assign in the then branch */ d1 = merge_lists(d1, d2); attach_defuse(child, "c_expr", d1); return d1; default: fprintf(stderr, "cannot happen - bad if_t\n"); exit(1); } break; case FOR_T: /* either a function or a for-loop */ RealDecls++; forn = (for_node *) child; d1 = walk_tree(forn->init, mark); if (forn->hdr.type == TN_FUNC_DEF) { is_a_prototype = 0; d2 = walk_tree(forn->test, mark); is_a_prototype = 1; } else d2 = walk_tree(forn->test, mark|USE); if (forn->hdr.type == TN_FOR) attach_defuse(forn->test, "cond", d2); d1 = merge_lists(d1, d2); d1 = merge_lists(d1, walk_tree(forn->incr, mark)); d2 = walk_tree(forn->stemnt, mark); /* body */ RealDecls--; break; case NODE_T: switch(child->hdr.type){ case TN_FUNC_DECL: /* name on lnode, params on rnode */ if (child->lnode && child->lnode->hdr.which == LEAF_T && child->lnode->hdr.type == TN_IDENT) Fct_name = nmestr(((leafnode *)(child->lnode))->data.sval); if (RealDecls && (strcmp(Fct_name, want) == 0)) { if (vis) set_fbase(child->hdr.line, Fct_name); if (0) fprintf(stdout, "%3d: %s\n", child->hdr.line, Fct_name); } if (is_a_prototype) d1 = walk_tree(child->rnode, mark|DEF|USE|PARAM); /* suppress complaints about disuse */ else d1 = walk_tree(child->rnode, mark|DEF|PARAM); attach_defuse(child, "decl1", d1); return d1; case TN_DECLS: d1 = walk_tree(child->lnode, mark|DECL); d2 = walk_tree(child->rnode, mark|DECL); d1 = merge_lists(d1, d2); attach_defuse(child, "decls", d1); return d1; case TN_DECL: if (!child->lnode) break; /* prototype */ if (child->lnode->hdr.type == TN_PNTR) d1 = walk_tree(child->rnode, mark|DEREF|DECL); else /* lnode has type information only */ d1 = walk_tree(child->rnode, mark|DECL); attach_defuse(child, "decl2", d1); return d1; case TN_ARRAY_DECL: d1 = walk_tree(child->lnode, mark|ARRAY_DECL); /* base name */ d2 = walk_tree(child->rnode, USE); d1 = merge_lists(d1, d2); attach_defuse(child, "decl3", d1); add_aio(d1, child); return d1; case TN_SELECT: /* access of structure element */ if (child->hdr.tok == ARROW) { d1 = walk_tree(child->lnode, mark|REF0); strcat(ref1_pref, "->"); } else { d1 = walk_tree(child->lnode, mark|REF1); strcat(ref1_pref, "."); } d2 = walk_tree(child->rnode, mark|REF2); d1 = merge_lists(d1, d2); attach_defuse(child, "select", d1); return d1; case TN_CAST: /* e.g.,: (void) fcall(args); */ d1 = walk_tree(child->rnode, mark); attach_defuse(child, "cast", d1); return d1; case TN_FUNC_CALL: storefname(child); d1 = walk_tree(child->lnode, mark|FCALL); d2 = walk_tree(child->rnode, mark|USE); d1 = merge_lists(d1, d2); attach_defuse(child, "fnct", d1); return d1; case TN_EXPR: switch (child->hdr.tok) { case INCR: case DECR: /* either --x (rnode) or x-- (lnode) */ /* for structs, only rightmost member gets DEF */ if (child->rnode && child->rnode->hdr.type == TN_SELECT) { if (child->rnode->hdr.tok == ARROW) d1 = walk_tree(child->rnode->lnode, mark|USE|REF0); else d1 = walk_tree(child->rnode->lnode, mark|USE|REF1); d2 = walk_tree(child->rnode->rnode, mark|USE|DEF|REF2); d1 = merge_lists(d1, d2); d2 = (DefUse *) 0; } else d1 = walk_tree(child->rnode, mark|DEF|USE); if (child->lnode && child->lnode->hdr.type == TN_SELECT) { if (child->lnode->hdr.tok == ARROW) d1 = walk_tree(child->lnode->lnode, mark|USE|REF0); else d1 = walk_tree(child->lnode->lnode, mark|USE|REF1); d2 = walk_tree(child->lnode->rnode, mark|USE|DEF|REF2); d1 = merge_lists(d1, d2); d2 = (DefUse *) 0; } else d2 = walk_tree(child->lnode, mark|DEF|USE); d1 = merge_lists(d1, d2); attach_defuse(child, "incr", d1); return d1; case ALIGNOF: case SIZEOF: d1 = walk_tree(child->rnode, mark|PARAM); /* tag meant to avoid complaints on things like sizeof (*ptr) */ attach_defuse(child, "sizeof", d1); return d1; case CASE: if (child->lnode) { fprintf(stderr, "%s: unexpected lnode, case\n", progname); d1 = walk_tree(child->lnode, mark); d2 = walk_tree(child->rnode, mark|USE); d1 = merge_lists(d1, d2); } else d1 = walk_tree(child->rnode, mark|USE); attach_defuse(child, "case", d1); break; case B_AND: if (child->lnode == NULL) /* aliasing - takes address of name */ return walk_tree(child->rnode, mark|ALIAS); /* else part of an expression */ mark |= USE; /* fall through */ default: /* all other forms of an expression */ d1 = walk_tree(child->lnode, mark); d2 = walk_tree(child->rnode, mark); d1 = merge_lists(d1, d2); attach_defuse(child, "expr", d1); return d1; } break; case TN_SWITCH: case TN_WHILE: case TN_DOWHILE: d1 = walk_tree(child->lnode, mark|USE); /* condition */ attach_defuse(child->lnode, "cond", d1); d2 = walk_tree(child->rnode, mark); d1 = merge_lists(d1, d2); return d1; case TN_ASSIGN: { watch = 0; if (watch) printf("A - mark = %d -- %s\n", mark, x_stmnt(child)); if (def_and_use(child->hdr.tok)) { d1 = walk_tree(child->lnode, mark|DEF|USE); } else { int nmark = mark; if (watch) printf("B - mark = %d -- %s\n", nmark, x_stmnt(child->lnode)); if (nmark&USE) { nmark &= ~USE; nmark |= USEafterdef; } if (watch) printf("C - mark = %d -- %s -- lnode=%s\n", nmark, x_stmnt(child->lnode), name_of_node(child->lnode->hdr.type)); d1 = walk_tree(child->lnode, nmark|DEF); if (watch) { printf("Bd1: "); dump_defuse(d1, stdout); printf("\n"); } } d2 = walk_tree(child->rnode, (mark&~DECL)|USE); if (watch) { printf("D1: "); dump_defuse(d1, stdout); printf("\n"); printf("D2: "); dump_defuse(d2, stdout); printf("\n"); } d1 = merge_lists(d2, d1); /* d1 after d2 */ if (watch) { printf("D1+D2: "); dump_defuse(d1, stdout); printf("\n"); } attach_defuse(child, "asgn", d1); return d1; } case TN_DEREF: d1 = walk_tree(child->lnode, mark|DEREF); d2 = walk_tree(child->rnode, mark|DEREF); d1 = merge_lists(d1, d2); return d1; case TN_JUMP: if (child->hdr.tok != RETURN) goto out; /* no var refs */ d1 = walk_tree(child->lnode, mark|USE); attach_defuse(child, "return", d1); return d1; case TN_INDEX: d1 = walk_tree(child->lnode, mark | DEREF); /* indexing an array derefs basename */ if (strlen(ref1_pref) > 0) strcat(ref1_pref, "["); d2 = walk_tree(child->rnode, (mark&(~(DEF|ALIAS|DEREF)))); if (strlen(ref1_pref) > 0) strcat(ref1_pref, "]"); d1 = merge_lists(d1, d2); add_aio(d1, child); return d1; case TN_TRANS_LIST: walk_tree(child->lnode, mark); walk_tree(child->rnode, mark); return d1; default: break; } d1 = walk_tree(child->lnode, mark); d2 = walk_tree(child->rnode, mark); break; }out: return merge_lists(d1, d2);}voidbugger(char *store, treenode *root, int top){ leafnode *leaf; if (!root) return; switch (root->hdr.which) { case LEAF_T: leaf = (leafnode *) root; switch (leaf->hdr.type) { case TN_IDENT: strcat(store, leaf->data.sval->str); break; default: goto bad; } break; case NODE_T: switch (root->hdr.type) { case TN_SELECT: bugger(store, root->lnode, 0); if (root->hdr.tok == ARROW) strcat(store, "->"); else strcat(store, "."); bugger(store, root->rnode, 0); break; case TN_FUNC_CALL: bugger(store, root->lnode, 0); strcat(store, "()"); break; default: goto bad; } break; default:bad: strcat(store, "<unknown type>"); break; } if (top) strcat(store, "()");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -