|
|
1.1 ! root 1: /* ident "@(#)ctrans:src/tree_walk.c 1.2" */ ! 2: /* ! 3: tree_walk.c ! 4: Utilities for tree-walking ! 5: */ ! 6: ! 7: #include "cfront.h" ! 8: #include "tree_walk.h" ! 9: #include <stdarg.h> ! 10: #include "hash.h" ! 11: // #include <alloca.h> ! 12: // ************ need to add an explicit call of free ! 13: // ************ make it an ifdef ! 14: // ??? #include <streamdefs.h> ! 15: #include <malloc.h> ! 16: ! 17: class walker { ! 18: tree_walk_control control; ! 19: Pnode orig_addr; ! 20: Hash *nodes_seen_hash; ! 21: int depth; ! 22: int made_ht; ! 23: tree_walk_tree * cur_tree; ! 24: public: ! 25: walker(tree_walk_control& c) ; ! 26: ! 27: ~walker () { ! 28: if(made_ht) delete nodes_seen_hash; ! 29: } ! 30: tree_node_action walk (Pnode&); ! 31: tree_node_action walk_ (Pnode& n) ! 32: { ! 33: if(n) { ! 34: int save_depth = depth; ! 35: tree_walk_tree * save_cur_tree = cur_tree; ! 36: ! 37: depth ++; ! 38: if(control.alloc_stack_bytes) { ! 39: cur_tree = (tree_walk_tree *) ! 40: // alloca (control.alloc_stack_bytes + sizeof (tree_walk_tree)); ! 41: malloc(control.alloc_stack_bytes + sizeof (tree_walk_tree)); ! 42: cur_tree->parent = save_cur_tree; ! 43: } ! 44: tree_node_action r = walk(n); ! 45: depth = save_depth; ! 46: return r; ! 47: } else return tna_continue; ! 48: } ! 49: ! 50: tree_node_action walk(Pgen& n) ! 51: { return walk_ ((struct node * &)n); }; ! 52: tree_node_action walk(Pvec& n) ! 53: { return walk_ ((struct node * &)n); }; ! 54: tree_node_action walk(Pptr& n) ! 55: { return walk_ ((struct node * &)n); }; ! 56: tree_node_action walk(Ptype& n) ! 57: { return walk_ ((struct node * &)n); }; ! 58: tree_node_action walk(Pfct& n) ! 59: { return walk_ ((struct node * &)n); }; ! 60: tree_node_action walk(Ptable& n) ! 61: { return walk_ ((struct node * &)n); }; ! 62: tree_node_action walk(Pbase& n) ! 63: { return walk_ ((struct node * &)n); }; ! 64: tree_node_action walk(Pname& n) ! 65: { return walk_ ((struct node * &)n); }; ! 66: tree_node_action walk(Pexpr& n) ! 67: { return walk_ ((struct node * &)n); }; ! 68: tree_node_action walk(Pstmt& n) ! 69: { return walk_ ((struct node * &)n); }; ! 70: tree_node_action walk(Pblock& n) ! 71: { return walk_ ((struct node * &)n); }; ! 72: tree_node_action walk(Penum& n) ! 73: { return walk_ ((struct node * &)n); }; ! 74: tree_node_action walk(Pclass& n) ! 75: { return walk_ ((struct node * &)n); }; ! 76: tree_node_action walk(Pvirt& n) ! 77: { return walk_ ((struct node * &)n); }; ! 78: tree_node_action walk(Plist& n) ! 79: { return walk_ ((struct node * &)n); }; ! 80: tree_node_action walk(Pin& n) ! 81: { return walk_ ((struct node * &)n); }; ! 82: tree_node_action walk(struct ia * & n) ! 83: { return walk_ ((struct node * &)n); }; ! 84: tree_node_action walk(Pbcl& n) ! 85: { return walk_ ((struct node * &)n); }; ! 86: private: ! 87: int fetching () { return (control.fetcher != null_tfp); } ; ! 88: void free_fetched (void *); ! 89: int fetch (void *, unsigned long, void *&); ! 90: int fetch (void * a, unsigned long l, Pnode& p) ! 91: { ! 92: int ret; ! 93: void * t; /* this is an output argument */ ! 94: ret = fetch(a,l,t); ! 95: if(!ret) { ! 96: p = Pnode(t); ! 97: } ! 98: return ret; ! 99: }; ! 100: // void error (const char *,...); ?? at&t -- to get it up quick, line 155 ! 101: void error ( char *, unsigned long=0 ); ! 102: tree_node_action pre_act_on_node (Pnode node, node_class nc, ! 103: Pnode node_copy, Pnode& replacement); ! 104: ! 105: tree_node_action a_gen (Pnode, Pgen, Pnode&); ! 106: tree_node_action a_vec (Pnode, Pvec, Pnode&); ! 107: tree_node_action a_ptr (Pnode, Pptr, Pnode&); ! 108: tree_node_action a_fct (Pnode, Pfct, Pnode&); ! 109: tree_node_action a_table (Pnode, Ptable, Pnode&); ! 110: tree_node_action a_basetype (Pnode, Pbase, Pnode&); ! 111: tree_node_action a_name(Pnode, Pname, Pnode&); ! 112: tree_node_action a_expr (Pnode, Pexpr, Pnode&); ! 113: tree_node_action a_stmt (Pnode, Pstmt, Pnode&); ! 114: tree_node_action a_enumdef (Pnode, Penum, Pnode&); ! 115: tree_node_action a_classdef (Pnode, Pclass, Pnode&); ! 116: tree_node_action a_virt (Pnode, Pvirt, Pnode&); ! 117: tree_node_action a_name_list (Pnode, Plist, Pnode&); ! 118: tree_node_action a_iline (Pnode, Pin, Pnode&); ! 119: tree_node_action a_ia (Pnode, struct ia *, Pnode&); ! 120: tree_node_action a_baseclass (Pnode, Pbcl, Pnode&); ! 121: tree_node_action a_expr_guts (Pexpr); ! 122: }; ! 123: ! 124: ! 125: walker::walker(tree_walk_control& c) ! 126: { control = c; ! 127: made_ht = 0; ! 128: if (c.nodes_seen_hash) ! 129: nodes_seen_hash = c.nodes_seen_hash; ! 130: else { ! 131: nodes_seen_hash = new pointer_hash (100); ! 132: made_ht = 1; ! 133: } ! 134: depth = 0; ! 135: cur_tree = 0; ! 136: } ! 137: ! 138: ! 139: tree_node_action ! 140: walk_tree (tree_walk_control& c, Pnode& n) ! 141: { ! 142: walker w (c); ! 143: return w.walk(n); ! 144: } ! 145: ! 146: ! 147: /* error messages are of finite length, so no need to run ! 148: around mallocing strings */ ! 149: ! 150: // void walker::error (const char * format, ...) ! 151: void walker::error (char *format, unsigned long v) ! 152: { ! 153: va_list args; ! 154: va_start(args, format); ! 155: if(control.call_i_error) { ! 156: char buf[1000]; ! 157: // vsprintf(buf, format, args); ! 158: // vsprintf not universal: by inspection ! 159: // all calls are currently of 1 or 0 arguments ! 160: sprintf(buf, format, v); ! 161: (*control.i_error)('i', buf); ! 162: } else { ! 163: vostream_printf (format, args, *control.error_stream); ! 164: *control.error_stream << "\n"; ! 165: control.error_stream->flush(); ! 166: } ! 167: va_end (args); ! 168: } ! 169: ! 170: ! 171: void ! 172: walker::free_fetched (void * addr) ! 173: { ! 174: if (control.fetcher != null_tfp) /* null indicates no cross-address-space */ ! 175: free ((char *)addr); ! 176: } ! 177: ! 178: int ! 179: walker::fetch (void * addr, unsigned long length, void*& taddr) ! 180: { ! 181: int err; ! 182: ! 183: if (control.fetcher == null_tfp) { ! 184: taddr = addr; ! 185: return 0; ! 186: } else { ! 187: taddr = (void *)malloc ((unsigned int)length); ! 188: if(taddr == 0) { ! 189: error ("walker::fetch: failed to malloc %d bytes.", length); ! 190: return 1; ! 191: } ! 192: ! 193: err = (*control.fetcher) (control.callback_info, addr, length, 0, taddr); ! 194: if(err) { ! 195: error("walker::fetch: fetcher returned %d.", err); ! 196: return 1; ! 197: } ! 198: } ! 199: } ! 200: ! 201: /* ::walk is called with a node pointer and a reference to ! 202: a replacement node pointer. When it returns, ! 203: replacement will be set if the action procedure ! 204: called on the node decided to copy it or replace it. ! 205: There are two possible modularities. ! 206: In case there is cross-address-space action, ! 207: ::walk can't call the action procedure until it has ! 208: entered the case on node bases. Once it has, ! 209: it calls the per-structure-type procedure, ! 210: which calls the action proc. If the action ! 211: proc supplies a replacement, then that replacement ! 212: will be returned up via the reference parameters to ! 213: the per-structure procedures. ! 214: ! 215: It the action procedure returns tna_continue, ! 216: then the walk continues against the new copy of the node ! 217: so that further replacements are reflected in the new copies. ! 218: This prevents replacement from being meaningful cross-address-space, ! 219: since the new copy will presumably be in the current ! 220: (and not the cross) address space. That is, if the node ! 221: is replaced by the action proc, the pointers in the new ! 222: node will drive the subsequent tree walk. Usually one ! 223: would just bitcopy, and then they would be replaced in turn. ! 224: */ ! 225: ! 226: tree_node_action ! 227: walker::walk (Pnode& top) ! 228: { ! 229: Pnode replacement = 0; ! 230: tree_node_action err; ! 231: int class_err; ! 232: node_class nclass; ! 233: Pnode node = 0; /* assign to shut up compiler, ! 234: which dosen't recognize pass-by-reference as a set */ ! 235: ! 236: orig_addr = top; ! 237: ! 238: if(fetching ()) { ! 239: if(fetch((void *)top, sizeof (struct node), node)) ! 240: return tna_error; ! 241: } else node = top; ! 242: ! 243: /* This has a complete catalog of bases, rather than just a list ! 244: of those associated with data structures. Its important ! 245: to detect the errs. ! 246: */ ! 247: ! 248: nclass = classify_node (node, class_err); ! 249: ! 250: if(class_err) { ! 251: error("walker::walk: unknown node type %d.", node->base); ! 252: free_fetched ((void *)node); ! 253: err = tna_error; ! 254: goto Return; ! 255: } ! 256: ! 257: switch(nclass) ! 258: { ! 259: default: ! 260: case nc_unused: ! 261: error("walker::walk: unused node type %d.", node->base); ! 262: err = tna_error; ! 263: goto Return; ! 264: ! 265: case nc_eof: ! 266: break; ! 267: ! 268: case nc_virt: ! 269: fetch((void *)top, sizeof (struct virt), node); ! 270: err = a_virt(top, Pvirt (node), replacement); ! 271: break; ! 272: ! 273: case nc_nlist: ! 274: fetch((void *)top, sizeof (struct name_list), node); ! 275: err = a_name_list(top, (struct name_list *)node, replacement); ! 276: break; ! 277: ! 278: case nc_iline: ! 279: fetch((void *)top, sizeof (struct iline), node); ! 280: err = a_iline(top, (struct iline *)node, replacement); ! 281: break; ! 282: ! 283: case nc_gen: ! 284: fetch((void *)top, sizeof (struct gen), node); ! 285: err = a_gen(top, Pgen (node), replacement); ! 286: break; ! 287: ! 288: case nc_vec: ! 289: fetch((void *)top, sizeof (struct vec), node); ! 290: err = a_vec(top, Pvec(node), replacement); ! 291: break; ! 292: ! 293: case nc_ptr: ! 294: fetch((void *)top, sizeof (struct ptr), node); ! 295: err = a_ptr(top, Pptr(node), replacement); ! 296: break; ! 297: ! 298: case nc_fct: ! 299: fetch((void *)top, sizeof (struct fct), node); ! 300: err = a_fct(top, Pfct(node), replacement); ! 301: break; ! 302: ! 303: case nc_table: ! 304: fetch((void *)top, sizeof (struct table), node); ! 305: err = a_table(top, Ptable(node), replacement); ! 306: break; ! 307: ! 308: case nc_basetype: ! 309: fetch((void *)top, sizeof (struct basetype), node); ! 310: err = a_basetype(top, Pbase(node), replacement); ! 311: break; ! 312: ! 313: case nc_name: ! 314: fetch((void *)top, sizeof (struct name), node); ! 315: err = a_name(top, Pname(node), replacement); ! 316: break; ! 317: ! 318: case nc_expr: ! 319: fetch((void *)top, sizeof (struct expr), node); ! 320: err = a_expr(top, Pexpr(node), replacement); ! 321: break; ! 322: ! 323: case nc_stmt: ! 324: fetch((void *)top, sizeof (struct stmt), node); ! 325: err = a_stmt(top, Pstmt(node), replacement); ! 326: break; ! 327: ! 328: case nc_enumdef: ! 329: fetch((void *)top, sizeof (struct enumdef), node); ! 330: err = a_enumdef(top, Penum(node), replacement); ! 331: break; ! 332: ! 333: case nc_classdef: ! 334: fetch((void *)top, sizeof (struct classdef), node); ! 335: err = a_classdef(top, Pclass(node), replacement); ! 336: break; ! 337: ! 338: case nc_ia: ! 339: fetch((void *)top, sizeof (struct ia), node); ! 340: err = a_ia(top, (struct ia *)node, replacement); ! 341: break; ! 342: ! 343: case nc_baseclass: ! 344: fetch((void *)top, sizeof (struct basecl), node); ! 345: err = a_baseclass(top, Pbcl(node), replacement); ! 346: break; ! 347: ! 348: } ! 349: ! 350: if(replacement) { ! 351: if (fetching ()) { ! 352: error ! 353: ("walker::walk: Attempt to replace tree in cross-address space mode."); ! 354: err = tna_error; ! 355: } ! 356: else top = replacement; ! 357: } ! 358: ! 359: if (control.post_action_proc && err != tna_error) { ! 360: tree_node_action post_err; ! 361: Pnode& post_repl = node; ! 362: ! 363: (*control.post_action_proc) (post_repl, nclass, control.callback_info, post_err, ! 364: depth, orig_addr, *cur_tree); ! 365: if(post_err != tna_continue) err = post_err; ! 366: if(post_repl != node) { ! 367: if (fetching ()) { ! 368: error ! 369: ("walker::walk: Attempt to replace tree in cross-address space mode."); ! 370: err = tna_error; ! 371: } ! 372: else top = post_repl; ! 373: } ! 374: } ! 375: ! 376: free_fetched((void *) node); ! 377: ! 378: Return: ! 379: return err; ! 380: } ! 381: ! 382: /* This is called in pre-order for each node. Then ! 383: post_act_on_node is called after whatever recursive ! 384: processing ensues. ! 385: ! 386: This is called from each of the structure-specific procedures ! 387: to give the action procedure an opportunity to act. ! 388: It can return a replacement pointer and control ! 389: whether to examine the insides of the node. ! 390: */ ! 391: ! 392: tree_node_action ! 393: walker::pre_act_on_node (Pnode node, node_class nc, ! 394: Pnode node_copy, Pnode& replacement) ! 395: { ! 396: /* If we have been here before, then we never proceed */ ! 397: /* node_copy is != node when a fetcher is in use */ ! 398: ! 399: int found; ! 400: int old_node; ! 401: tree_node_action action; ! 402: Pnode new_node; ! 403: int register_in_hash = 1; ! 404: ! 405: nodes_seen_hash->action((int)node, 0, Hash::probe, found, old_node); ! 406: ! 407: if(found) { ! 408: new_node = Pnode(old_node); ! 409: if(new_node != node) replacement = new_node; ! 410: return tna_stop; /* no need to proceed */ ! 411: } ! 412: ! 413: /* OK, we don't know from a previous pass. Call our actor */ ! 414: ! 415: new_node = fetching () && node_copy ? node_copy : node; ! 416: ! 417: (*control.action_proc)(new_node, nc, control.callback_info, action, ! 418: depth, orig_addr, *cur_tree, ! 419: register_in_hash); ! 420: ! 421: if(action != tna_error && !fetching () && new_node != node) { ! 422: replacement = new_node; ! 423: if(register_in_hash) ! 424: nodes_seen_hash->action((int)node, ! 425: (int)new_node, ! 426: Hash::insert, 0, 0); ! 427: } ! 428: else { ! 429: if(register_in_hash) ! 430: nodes_seen_hash->action((int)node, (int) node, Hash::insert, 0, 0); ! 431: } ! 432: return action; ! 433: } ! 434: ! 435: tree_node_action walker::a_table(Pnode ta, Ptable t, Pnode& replacement) ! 436: { ! 437: /* no unions */ ! 438: ! 439: tree_node_action action; ! 440: action = pre_act_on_node(ta, nc_table, Pnode(t), replacement); ! 441: if(action != tna_continue) return action; ! 442: ! 443: /* -----------------------------*/ ! 444: /* For Now, Never Walk a Table. */ ! 445: ! 446: action = tna_stop; return action; ! 447: ! 448: /* An array of pointers. ! 449: * The action procedure is responsible for allocating a new one ! 450: * of those if it replaced and continued. ! 451: * *** end of comment ! 452: ! 453: if(!fetching () && replacement) ! 454: t = Ptable(replacement); ! 455: ! 456: Pname * t_entries; ! 457: ! 458: if(fetching ()) { ! 459: void * temp; ! 460: fetch((void *)t->entries, t->size * sizeof(Pname), temp); ! 461: t_entries = (Pname *)temp; ! 462: } ! 463: else t_entries = t->entries; ! 464: ! 465: for(int nx = 0; nx < t->size; nx ++) { ! 466: action = walk(t_entries[nx]); ! 467: if(action == tna_error) return action; ! 468: } ! 469: ! 470: if(fetching ()) free_fetched ((void *)t_entries); ! 471: ! 472: Pnode n = Pnode(t->real_block); ! 473: ! 474: action = walk(t->real_block); ! 475: if(action == tna_error) return action; ! 476: ! 477: action = walk(t->next); ! 478: action = walk(t->t_name); ! 479: return tna_continue; ! 480: */ // don't walk table ! 481: } ! 482: ! 483: tree_node_action walker::a_enumdef (Pnode ta, Penum e, Pnode& replacement) ! 484: { ! 485: tree_node_action action = pre_act_on_node(ta, nc_enumdef, Pnode(e), replacement); ! 486: ! 487: action = walk(e->mem); ! 488: if(action == tna_error) return action; ! 489: ! 490: action = walk(e->e_type); ! 491: ! 492: return tna_continue; ! 493: } ! 494: ! 495: tree_node_action walker::a_virt(Pnode ta, Pvirt v, Pnode& replacement) ! 496: { ! 497: /* no unions */ ! 498: ! 499: int nx; ! 500: tree_node_action action = pre_act_on_node(ta, nc_enumdef, Pnode(v), replacement); ! 501: ! 502: if(action != tna_continue) return action; ! 503: ! 504: if(!fetching () && replacement) ! 505: v = Pvirt(replacement); ! 506: ! 507: /* an array of velem structures. */ ! 508: ! 509: velem * v_virt_init; ! 510: ! 511: if(fetching ()) { ! 512: void * t; ! 513: fetch((void *)v->virt_init, v->n_init * sizeof(velem), t); ! 514: v_virt_init = (velem *)t; ! 515: } ! 516: else v_virt_init = v->virt_init; ! 517: ! 518: for(nx = 0; nx < v->n_init; nx ++) { ! 519: action = walk(v_virt_init[nx].n); ! 520: if(action == tna_error) return action; ! 521: } ! 522: ! 523: if(fetching ()) free_fetched ((void *)v_virt_init); ! 524: ! 525: action = walk(v->vclass); ! 526: ! 527: return tna_continue; ! 528: } ! 529: ! 530: tree_node_action walker::a_classdef(Pnode ta, Pclass c, Pnode& replacement) ! 531: { ! 532: ! 533: tree_node_action action = pre_act_on_node(ta, nc_classdef, Pnode(c), replacement); ! 534: ! 535: if(action != tna_continue) return action; ! 536: ! 537: if(!fetching () && replacement) ! 538: c = Pclass(replacement); ! 539: ! 540: action = walk(c->baselist); ! 541: if(action == tna_error) return action; ! 542: ! 543: action=walk(c->mem_list); ! 544: if(action == tna_error) return action; ! 545: ! 546: action=walk(c->memtbl); ! 547: if(action == tna_error) return action; ! 548: ! 549: action=walk(c->friend_list); ! 550: if(action == tna_error) return action; ! 551: ! 552: action=walk(c->pubdef); ! 553: if(action == tna_error) return action; ! 554: ! 555: action=walk(c->tn_list); ! 556: if(action == tna_error) return action; ! 557: ! 558: action=walk(c->in_class); ! 559: if(action == tna_error) return action; ! 560: ! 561: action=walk(c->in_fct); ! 562: if(action == tna_error) return action; ! 563: ! 564: action=walk(c->this_type); ! 565: if(action == tna_error) return action; ! 566: ! 567: action=walk(c->virt_list); ! 568: if(action == tna_error) return action; ! 569: ! 570: action=walk(c->c_ctor); ! 571: if(action == tna_error) return action; ! 572: action=walk(c->c_dtor); ! 573: if(action == tna_error) return action; ! 574: action=walk(c->c_itor); ! 575: if(action == tna_error) return action; ! 576: ! 577: action=walk(c->conv); ! 578: if(action == tna_error) return action; ! 579: ! 580: return tna_continue; ! 581: } ! 582: ! 583: tree_node_action walker::a_basetype(Pnode ta, Pbase b, Pnode& replacement) ! 584: { ! 585: ! 586: tree_node_action action = pre_act_on_node(ta, nc_basetype, Pnode(b), replacement); ! 587: int derr; ! 588: ! 589: if(action != tna_continue) return action; ! 590: ! 591: if(!fetching () && replacement) ! 592: b = Pbase(replacement); ! 593: ! 594: action = walk(b->b_name); ! 595: if(action == tna_error) return action; ! 596: ! 597: action = walk(b->b_table); ! 598: if(action == tna_error) return action; ! 599: ! 600: // action = walk(b->b_field); ! 601: // if(action == tna_error) return action; ! 602: ! 603: action = walk(b->b_xname); ! 604: if(action == tna_error) return action; ! 605: ! 606: switch(derr = b->discriminator(0)) { ! 607: case 0: break; ! 608: case 1: ! 609: action = walk(b->b_fieldtype); ! 610: if(action == tna_error) return action; ! 611: break; ! 612: case 2: break; ! 613: default: ! 614: error ("a_basetype: discrim error %d.", derr); ! 615: return tna_error; ! 616: } ! 617: ! 618: return tna_continue; ! 619: } ! 620: ! 621: tree_node_action walker::a_fct(Pnode ta, Pfct f, Pnode& replacement) ! 622: { ! 623: ! 624: tree_node_action action = pre_act_on_node(ta, nc_fct, Pnode(f), replacement); ! 625: ! 626: if(action != tna_continue) return action; ! 627: ! 628: if(!fetching () && replacement) ! 629: f = Pfct(replacement); ! 630: ! 631: action = walk(f->returns); ! 632: if(action == tna_error) return action; ! 633: ! 634: action = walk(f->argtype); ! 635: if(action == tna_error) return action; ! 636: ! 637: action = walk(f->s_returns); ! 638: if(action == tna_error) return action; ! 639: ! 640: action = walk(f->f_this); ! 641: if(action == tna_error) return action; ! 642: ! 643: action = walk(f->memof); ! 644: if(action == tna_error) return action; ! 645: ! 646: action = walk(f->body); ! 647: if(action == tna_error) return action; ! 648: ! 649: action = walk(f->f_init); ! 650: if(action == tna_error) return action; ! 651: ! 652: action = walk(f->f_expr); ! 653: if(action == tna_error) return action; ! 654: ! 655: action = walk(f->last_expanded); ! 656: if(action == tna_error) return action; ! 657: ! 658: action = walk(f->f_result); ! 659: if(action == tna_error) return action; ! 660: ! 661: action = walk(f->f_args); ! 662: if(action == tna_error) return action; ! 663: ! 664: return tna_continue; ! 665: } ! 666: ! 667: tree_node_action walker::a_name_list(Pnode ta, Plist l, Pnode& replacement) ! 668: { ! 669: ! 670: int cl_error; ! 671: tree_node_action action = pre_act_on_node(ta, nc_nlist, Pnode(l), replacement); ! 672: ! 673: if(action == tna_stop) { ! 674: if(!fetching () && replacement) ! 675: l = Plist(replacement); ! 676: cl_error = 0; ! 677: if((classify_node(Pnode(l), cl_error) == nc_nlist) && !cl_error) { ! 678: action = walk(l->l); ! 679: if(action == tna_error) return action; ! 680: } ! 681: } ! 682: ! 683: if(action != tna_continue) return action; ! 684: ! 685: if(!fetching () && replacement) ! 686: l = Plist(replacement); ! 687: ! 688: action = walk(l->f); ! 689: if(action == tna_error) return action; ! 690: ! 691: action = walk(l->l); ! 692: if(action == tna_error) return action; ! 693: ! 694: return tna_continue; ! 695: } ! 696: ! 697: tree_node_action walker::a_gen(Pnode ta, Pgen g, Pnode& replacement) ! 698: { ! 699: ! 700: tree_node_action action = pre_act_on_node(ta, nc_gen, Pnode(g), replacement); ! 701: ! 702: if(action != tna_continue) return action; ! 703: ! 704: if(!fetching () && replacement) ! 705: g = Pgen(replacement); ! 706: ! 707: action = walk(g->fct_list); ! 708: if(action == tna_error) return action; ! 709: ! 710: return tna_continue; ! 711: } ! 712: ! 713: tree_node_action walker::a_vec(Pnode ta, Pvec v, Pnode& replacement) ! 714: { ! 715: ! 716: tree_node_action action = pre_act_on_node(ta, nc_vec, Pnode(v), replacement); ! 717: ! 718: if(action != tna_continue) return action; ! 719: ! 720: if(!fetching () && replacement) ! 721: v = Pvec(replacement); ! 722: ! 723: action = walk(v->typ); ! 724: if(action == tna_error) return action; ! 725: ! 726: action = walk(v->dim); ! 727: if(action == tna_error) return action; ! 728: ! 729: return tna_continue; ! 730: } ! 731: ! 732: tree_node_action walker::a_ptr(Pnode ta, Pptr p, Pnode& replacement) ! 733: { ! 734: ! 735: tree_node_action action = pre_act_on_node(ta, nc_ptr, Pnode(p), replacement); ! 736: ! 737: if(action != tna_continue) return action; ! 738: ! 739: if(!fetching () && replacement) ! 740: p = Pptr(replacement); ! 741: ! 742: action = walk(p->typ); ! 743: if(action == tna_error) return action; ! 744: ! 745: action = walk(p->memof); ! 746: if(action == tna_error) return action; ! 747: ! 748: return tna_continue; ! 749: } ! 750: ! 751: ! 752: tree_node_action walker::a_expr_guts(Pexpr e) ! 753: { ! 754: int derr; ! 755: tree_node_action action; ! 756: ! 757: switch(derr = e->discriminator (0)) { ! 758: case 1: ! 759: action = walk(e->tp); ! 760: if(action == tna_error) return action; ! 761: break; ! 762: case 0: ! 763: break; ! 764: default: ! 765: error ("a_expr: discrim error %d on union 0.", derr); ! 766: return tna_error; ! 767: } ! 768: ! 769: switch(derr = e->discriminator (1)) { ! 770: case 0: ! 771: break; ! 772: default: ! 773: error ("a_expr: discrim error %d on union 1.", derr); ! 774: return tna_error; ! 775: case 1: ! 776: action = walk(e->e1); ! 777: if(action == tna_error) return action; ! 778: break; ! 779: case 2: ! 780: break; ! 781: case 3: ! 782: break; ! 783: } ! 784: ! 785: switch(derr = e->discriminator (2)) { ! 786: case 0: ! 787: break; ! 788: default: ! 789: error ("a_expr: discrim error %d on union 2.", derr); ! 790: return tna_error; ! 791: case 1: ! 792: /* elists are special. e2 for an elist is a peer, not ! 793: a child. */ ! 794: if(e->base != ELIST) { ! 795: action = walk(e->e2); ! 796: if(action == tna_error) return action; ! 797: } ! 798: break; ! 799: case 2: ! 800: break; ! 801: case 3: ! 802: break; ! 803: case 4: ! 804: action = walk(e->n_initializer); ! 805: if(action == tna_error) return action; ! 806: break; ! 807: } ! 808: ! 809: switch(derr = e->discriminator (3)) { ! 810: case 0: ! 811: break; ! 812: default: ! 813: error ("a_expr: discrim error %d on union 3.", derr); ! 814: return tna_error; ! 815: case 1: ! 816: action = walk(e->tp2); ! 817: if(action == tna_error) return action; ! 818: break; ! 819: case 2: ! 820: action = walk(e->fct_name); ! 821: if(action == tna_error) return action; ! 822: break; ! 823: case 3: ! 824: action = walk(e->cond); ! 825: if(action == tna_error) return action; ! 826: break; ! 827: case 4: ! 828: action = walk(e->mem); ! 829: if(action == tna_error) return action; ! 830: break; ! 831: case 5: ! 832: action = walk(e->as_type); ! 833: if(action == tna_error) return action; ! 834: break; ! 835: case 6: ! 836: action = walk(e->n_table); ! 837: if(action == tna_error) return action; ! 838: break; ! 839: case 7: ! 840: action = walk(e->il); ! 841: if(action == tna_error) return action; ! 842: break; ! 843: case 8: ! 844: action = walk(e->query_this); ! 845: if(action == tna_error) return action; ! 846: break; ! 847: } ! 848: return tna_continue; ! 849: } ! 850: ! 851: ! 852: tree_node_action walker::a_expr(Pnode ta, Pexpr e, Pnode& replacement) ! 853: { ! 854: tree_node_action action = pre_act_on_node(ta, nc_expr, Pnode(e), replacement); ! 855: ! 856: if(action == tna_stop) { ! 857: if(!fetching () && replacement) ! 858: e = Pexpr(replacement); ! 859: /* ELIST implies that e2 is a peer, not a child */ ! 860: if(e->base == ELIST) { ! 861: action = walk(e->e2); ! 862: return action; ! 863: } ! 864: } ! 865: ! 866: if(action != tna_continue) return action; ! 867: ! 868: if(!fetching () && replacement) ! 869: e = Pexpr(replacement); ! 870: ! 871: action = a_expr_guts(e); ! 872: if (action == tna_error) return action; ! 873: if(e->base == ELIST) ! 874: action = walk(e->e2); ! 875: return action; ! 876: } ! 877: ! 878: tree_node_action walker::a_baseclass(Pnode ta, Pbcl b, Pnode& replacement) ! 879: { ! 880: tree_node_action action = pre_act_on_node(ta, nc_baseclass, Pnode(b), replacement); ! 881: ! 882: if(action != tna_continue) return action; ! 883: ! 884: if(!fetching () && replacement) ! 885: b = Pbcl(replacement); ! 886: ! 887: action = walk(b->bclass); ! 888: if(action == tna_error) return action; ! 889: ! 890: action = walk(b->init); ! 891: if(action == tna_error) return action; ! 892: ! 893: action = walk(b->next); ! 894: if(action == tna_error) return action; ! 895: ! 896: return tna_continue; ! 897: } ! 898: ! 899: ! 900: /* a name is also an expr. */ ! 901: ! 902: ! 903: tree_node_action walker::a_name(Pnode ta, Pname n, Pnode& replacement) ! 904: { ! 905: int derr; ! 906: int cl_error; ! 907: tree_node_action action = pre_act_on_node(ta, nc_name, Pnode(n), replacement); ! 908: ! 909: /* n_list is a sibling, not a child. We always process it ! 910: except in case of an error. */ ! 911: if(action == tna_stop) { ! 912: cl_error = 0; ! 913: if(!fetching () && replacement) ! 914: n = Pname(replacement); ! 915: if((classify_node(Pnode(n), cl_error) == nc_name) && !cl_error) { ! 916: if(depth > 0 || !control.dont_chase_lists_top) { ! 917: action = walk(n->n_list); ! 918: if(action == tna_error) return action; ! 919: } ! 920: } ! 921: return tna_stop; ! 922: } ! 923: ! 924: if(action != tna_continue) return action; ! 925: ! 926: if(!fetching () && replacement) ! 927: n = Pname(replacement); ! 928: ! 929: /* We don't walk n_tbl_list. Its not part of the graph. ! 930: */ ! 931: ! 932: switch(derr = n->discriminator(0)) { ! 933: case 0: ! 934: break; ! 935: case 1: ! 936: action = walk(n->n_qualifier); ! 937: if(action == tna_error) return action; ! 938: break; ! 939: case 2: ! 940: action = walk(n->n_realscope); ! 941: if(action == tna_error) return action; ! 942: break; ! 943: default: ! 944: error ("a_name: discrim error %d on union 0.", derr); ! 945: return tna_error; ! 946: } ! 947: ! 948: action = a_expr_guts(Pexpr(n)); ! 949: if(action == tna_error) return action; ! 950: ! 951: if(depth > 0 || !control.dont_chase_lists_top) { ! 952: action = walk(n->n_list); ! 953: if(action == tna_error) return action; ! 954: } ! 955: ! 956: return action; ! 957: } ! 958: ! 959: /* --- NOTE: s_list should be deferred until AFTER the post-action ! 960: procedure is called, if there is one. Since no one uses ! 961: post-actions yet I haven't bothered to make this fix. ! 962: --benson */ ! 963: ! 964: tree_node_action walker::a_stmt(Pnode ta, Pstmt s, Pnode& replacement) ! 965: { ! 966: int cl_error; ! 967: int derr; ! 968: tree_node_action action = pre_act_on_node(ta, nc_stmt, Pnode(s), replacement); ! 969: ! 970: if(action == tna_stop) { ! 971: if(!fetching () && replacement) ! 972: s = Pstmt(replacement); ! 973: cl_error = 0; ! 974: if((classify_node(Pnode(s), cl_error) == nc_stmt) && !cl_error) { ! 975: /* s_list is not our subordinate, it is our peer */ ! 976: if(depth > 0 || !control.dont_chase_lists_top) { ! 977: action = walk(s->s_list); /* continue walk of sibs */ ! 978: if (action == tna_error) return tna_error; ! 979: } ! 980: } ! 981: return tna_stop; ! 982: } ! 983: ! 984: if(action != tna_continue) return action; ! 985: ! 986: if(!fetching () && replacement) ! 987: s = Pstmt(replacement); ! 988: ! 989: action = walk(s->s); ! 990: if(action == tna_error) return action; ! 991: ! 992: action = walk(s->memtbl); ! 993: if(action == tna_error) return action; ! 994: ! 995: switch(derr = s->discriminator(0)) { ! 996: default: ! 997: error ("a_stmt: discrim error %d on union 0.", derr); ! 998: return tna_error; ! 999: case 4: ! 1000: case 0: break; ! 1001: case 1: ! 1002: action = walk(s->d); ! 1003: if(action == tna_error) return action; ! 1004: break; ! 1005: case 2: ! 1006: action = walk(s->e2); ! 1007: if(action == tna_error) return action; ! 1008: break; ! 1009: case 3: ! 1010: action = walk(s->has_default); ! 1011: if(action == tna_error) return action; ! 1012: break; ! 1013: case 5: ! 1014: action = walk(s->ret_tp); ! 1015: if(action == tna_error) return action; ! 1016: break; ! 1017: } ! 1018: ! 1019: switch(derr = s->discriminator(1)) { ! 1020: default: ! 1021: error ("a_stmt: discrim error %d on union 1.", derr); ! 1022: return tna_error; ! 1023: case 2: ! 1024: case 0: break; ! 1025: case 1: ! 1026: action = walk(s->e); ! 1027: if(action == tna_error) return action; ! 1028: break; ! 1029: case 3: ! 1030: action = walk(s->s2); ! 1031: if(action == tna_error) return action; ! 1032: break; ! 1033: } ! 1034: ! 1035: switch(derr = s->discriminator(2)) { ! 1036: default: ! 1037: error ("a_stmt: discrim error %d on union 2.", derr); ! 1038: return tna_error; ! 1039: case 0: break; ! 1040: case 1: ! 1041: action = walk(s->for_init); ! 1042: if(action == tna_error) return action; ! 1043: break; ! 1044: case 2: ! 1045: action = walk(s->else_stmt); ! 1046: if(action == tna_error) return action; ! 1047: break; ! 1048: case 3: ! 1049: action = walk(s->case_list); ! 1050: if(action == tna_error) return action; ! 1051: break; ! 1052: } ! 1053: ! 1054: if(depth > 0 || !control.dont_chase_lists_top) { ! 1055: action = walk(s->s_list); ! 1056: if(action == tna_error) return action; ! 1057: } ! 1058: ! 1059: return tna_continue; ! 1060: } ! 1061: ! 1062: tree_node_action walker::a_ia(Pnode ta, struct ia * ia, Pnode& replacement) ! 1063: { ! 1064: tree_node_action action = pre_act_on_node(ta, nc_ia, Pnode(ia), replacement); ! 1065: ! 1066: if(action != tna_continue) return action; ! 1067: ! 1068: if(!fetching () && replacement) ! 1069: ia = (struct ia *)&replacement; ! 1070: ! 1071: action = walk(ia->local); ! 1072: if(action == tna_error) return action; ! 1073: ! 1074: action = walk(ia->arg); ! 1075: if(action == tna_error) return action; ! 1076: ! 1077: action = walk(ia->tp); ! 1078: if(action == tna_error) return action; ! 1079: ! 1080: return tna_continue; ! 1081: } ! 1082: ! 1083: tree_node_action walker::a_iline(Pnode ta, Pin iline, Pnode& replacement) ! 1084: { ! 1085: tree_node_action action = pre_act_on_node(ta, nc_iline, Pnode(iline), replacement); ! 1086: ! 1087: if(action != tna_continue) return action; ! 1088: ! 1089: if(!fetching () && replacement) ! 1090: iline = Pin(replacement); ! 1091: ! 1092: action = walk(iline->fct_name); ! 1093: if(action == tna_error) return action; ! 1094: ! 1095: action = walk(iline->i_next); ! 1096: if(action == tna_error) return action; ! 1097: ! 1098: action = walk(iline->i_table); ! 1099: if(action == tna_error) return action; ! 1100: ! 1101: action = walk(iline->i_args); ! 1102: if(action == tna_error) return action; ! 1103: ! 1104: return tna_continue; ! 1105: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.