Annotation of researchv10no/cmd/cfront/optcfront/tree_walk.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.