C:/Users/Dennis/src/lang/russell.orig/src/pass4/subst.c

Go to the documentation of this file.
00001 # define TRACE
00002 # undef TRACE
00003 # define DEBUG
00004 
00005 # include <stdio.h>
00006 # include "parm.h"
00007 
00008 # include "stree/ststructs.mh"
00009 
00010 # include "stree/stsigs.mh"
00011 
00012 # include "sigs.h"
00013 
00014 # include "pass3/decl_pairs.h"
00015 # include "pass3/is_local.h"
00016 
00017 extern unsigned stplinks[];
00018 
00019 extern int stsize[];
00020 
00021 extern int yynerrs;  /* number of errors encountered in this pass */
00022 
00023 extern struct cn * dontsubst;
00024 
00025 extern NODE * substerr;
00026 
00027 extern FILE * unparse_file;
00028 
00029 /* Return an expression on the dontsubst list if s contains one.
00030  * Otherwise return NIL.
00031  */
00032 NODE * on_dontsubst(s)
00033 NODE *s;
00034 {
00035     struct cn *c;
00036 
00037     c = dontsubst;
00038     while(c != NIL) {
00039         if( is_descendant(((NODE *)(cn_head(c))), s) ) {
00040 #           ifdef TRACE
00041                 printf("on_dontsubst: returning 0x%X\n", cn_head(c));
00042                 fflush(stdout);
00043 #           endif
00044             return((NODE *)(cn_head(c)));
00045         }
00046         c = cn_tail(c);
00047     };
00048     return(NIL);
00049 }
00050 
00051 /*
00052  * subst(p, parameter list, argument list)
00053  *
00054  * Returns a structure which is a copy of the first argument except
00055  * that all identifiers declared in the parameter list are replaced
00056  * by the corresponding denotations in the argument list.
00057  * An attempt is made to copy as little of the signature
00058  * as possible.
00059  *  It is assumed that all identifiers in p point to their
00060  * declaration.
00061  *  Back pointers in the copy point to the original nodes.
00062  *  If an attempt is made to substitute an expression which has
00063  * a subexpression on the dontsubst list, substerr is set to point 
00064  * to the subexpression.
00065  */
00066 
00067 NODE * subst1();
00068 
00069 NODE * subst(p,params,args)
00070 NODE * p, * params, * args;
00071 {
00072     NODE * result;
00073 
00074     if (is_empty(params)) {
00075         return(p);
00076     }
00077     clr_dlist;
00078     result = subst1(p, params, args);
00079 #   ifdef TRACE
00080         if (result != p) {
00081             unparse_file = stdout;
00082             printf("subst: replaced\n");
00083             unparse(p);
00084             printf("\nwith\n");
00085             unparse(result);
00086             printf("\n");
00087         }
00088 #   endif
00089     return(result);
00090 }
00091 
00092 NODE * subst1(p,params,args)
00093 NODE * p, *params, *args;
00094 {
00095     boolean mod_flag = FALSE; /* One of the descendants was modified */
00096     register int knd;         /* kind field of node being examined   */
00097     int plinkv;               /* bit vector indicating primary links */
00098                               /* to be followed to recursively       */
00099                               /* substitute in subtrees              */
00100     int sigv;                 /* vector of signature pointers        */
00101     register NODE ** q;       /* pointer to link field to be         */
00102                               /* recursively examined.               */
00103     int idpos;                /* position of identifier in params    */
00104     NODE * tmpcopy[MAXFIELDS];/* temporary version of result         */
00105     register NODE ** s;
00106     register int i;
00107     int lim;
00108     register struct cn * c;
00109     int j;
00110     NODE * v, * w;
00111 
00112     if (p == ERR_SIG || p == NIL) return(p);
00113 
00114     switch ( knd = (p -> kind) ) {
00115         case LISTHEADER:
00116             i = 0;
00117             j = length(p);
00118             /* get sufficiently large chunk of memory to temporarily copy */
00119             /* the list, thus minimizing number of allocations.           */
00120                 if (j <= MAXFIELDS) {
00121                     s = tmpcopy;
00122                 } else {
00123                     s = (NODE **) malloc(j * sizeof(NODE *));
00124                 }
00125             maplist(q, p, {
00126                 s[i] = subst1(q, params, args);
00127                         /* should be locked but ... */
00128                 if(s[i] != q) {
00129                     mod_flag = TRUE;
00130                 }
00131                 i++;
00132             });
00133             if (mod_flag) {
00134               /* convert the temporary copy in s to a real list structure */
00135               /* and return it */
00136                 NODE * result;
00137                 result = emptylist();
00138                 for (i = 0; i < j; i++) {
00139                     addright(result,s[i]);
00140                 }
00141                 if (j > MAXFIELDS) free(s);
00142                 return(result);
00143             } else {
00144                 if (j > MAXFIELDS) free(s);
00145                 return(p);
00146             }
00147         case OPRID:
00148         case LETTERID:
00149           if (p -> id_str_table_index == -1) return(p);
00150 #         ifdef DEBUG
00151             if (!(p -> id_def_found) && yynerrs == 0) {
00152                 dbgmsg("subst: id declaration unresolved: %s\n",
00153                        getname(p -> id_str_table_index));
00154             }
00155 #         endif
00156           if (!p -> id_def_found) {
00157             /* undeclared identifier */
00158             return(p);
00159           }
00160           if (p -> sel_type != NIL) {
00161               NODE * new_sel_type = subst1(p -> sel_type, params, args);
00162 
00163               if (new_sel_type == p -> sel_type) {
00164                   /* id_appl may be wrong, but inside a signature it's */
00165                   /* not used.                                         */
00166                   return(p);
00167               } else {
00168                   NODE * q = copynode(p);
00169                   q -> sig_done = SIG_UNKNOWN;
00170                   chgfld(&(q -> signature), NIL);
00171                   chgfld(&(q -> sel_type), new_sel_type);
00172                   q -> id_appl = NIL;
00173                   return(q);
00174               }
00175           }
00176 
00177           /* check for identifier in parameter list and */
00178           /* substitute if appropriate.                 */
00179           /* Replace signature transparent ids by r.h.s. */
00180               i = 0;
00181               idpos = 0;
00182               if (p -> id_last_definition -> kind == PARAMETER) {
00183                 maplist(s, params, {
00184                   i++;
00185                   if(is_declared_by(p,s)) {
00186                       idpos = i;
00187                   }    
00188                 });
00189               } else if (p -> id_last_definition != NIL
00190                          && p -> id_last_definition -> kind == DECLARATION
00191                          && p -> id_last_definition -> decl_sig_transp) {
00192                 NODE * tmp = subst1(p -> id_last_definition -> decl_denotation,
00193                                     params, args);
00194                 if (tmp != p -> id_last_definition -> decl_denotation) {
00195                     return(tmp);
00196                 }
00197                 /* else treat it like any other identifier, so we don't */
00198                 /* make extra copies.                                   */
00199               }
00200               if (idpos != 0) {
00201                   /* return the idpos th element of args */
00202                       i = 0;
00203                       maplist(s, args, {
00204                           i++;
00205                           if(i == idpos) {
00206                               /* check if it includes an expression on the */
00207                               /* dontsubst list.                           */
00208                                 if (on_dontsubst(s) != NIL) {
00209                                   substerr = on_dontsubst(s);
00210                                 }
00211                               return(s);
00212                           }
00213                       });
00214               } else {
00215                   if (dl_new_decl(p) != p -> id_last_definition) {
00216                     /* declaration changed - need to copy node */
00217                     NODE * q = copynode(p);
00218                     q -> id_last_definition = dl_new_decl(p);
00219                     if (q -> signature != ERR_SIG) {
00220                       q -> sig_done = SIG_UNKNOWN;
00221                       chgfld(&(q -> signature), NIL);
00222                     }
00223                     q -> id_appl = NIL;
00224                     return(q);
00225                   } else {
00226                       /* id_appl may be wrong, but inside a signature it's */
00227                       /* not used.                                         */
00228                       return(p);
00229                   }
00230               }
00231 
00232         case MODPRIMARY:
00233             /* Need to copy now so that local type id references get changed */
00234             if (p -> mp_type_modifier == NIL) {
00235                 /* forgetting node.  Can and should be discarded */
00236                 return (subst1(p -> mp_primary, params, args));
00237             }
00238             v = copynode(p);
00239             add_dlist(p, v);
00240             chgfld(&(v -> mp_primary), subst1(p -> mp_primary, params, args));
00241             chgfld(&(v -> mp_type_modifier),
00242                    subst1(p -> mp_type_modifier, params, args));
00243             if (p -> mp_primary == v -> mp_primary &&
00244                 p -> mp_type_modifier == v -> mp_type_modifier) {
00245                 return(v);
00246             } else if (p -> signature != ERR_SIG) {
00247                 chgfld(&(v -> signature), NIL);
00248                 v -> sig_done = SIG_UNKNOWN;
00249             }
00250             return(v);
00251 
00252         case RECORDCONSTRUCTION:
00253             /* Need to copy now so that local type id references get changed */
00254             v = copynode(p);
00255             add_dlist(p, v);
00256             chgfld(&(v -> rec_component_list),
00257                    subst1(p -> rec_component_list, params, args));
00258             if (p -> signature != ERR_SIG) {
00259                 chgfld(&(v -> signature), NIL);
00260                 v -> sig_done = SIG_UNKNOWN;
00261             }
00262             return(v);
00263 
00264         case UNIONCONSTRUCTION:
00265             /* Need to copy now so that local type id references get changed */
00266             v = copynode(p);
00267             add_dlist(p, v);
00268             chgfld(&(v -> prod_components),
00269                    subst1(p -> prod_components, params, args));
00270             if (p -> signature != ERR_SIG) {
00271                 chgfld(&(v -> signature), NIL);
00272                 v -> sig_done = SIG_UNKNOWN;
00273             }
00274             return(v);
00275 
00276         case PRODCONSTRUCTION:
00277           /* treat parameter nodes as declarations, as for FUNCCONSTR below */
00278           {
00279             NODE * new_prod = copynode(p);
00280             NODE * new_params = emptylist();
00281 
00282             /* Build new list of parameters and add them to decl map */
00283               maplist(s, p -> prod_components, {
00284                 v = copynode(s);
00285                 add_dlist(s, v);
00286                 addright(new_params, v);
00287               });
00288             /* Substitute into parameter signatures */
00289               maplist(s, new_params, {
00290                 chgfld(&(s -> par_signature),
00291                        subst1(s -> par_signature, params, args));
00292               });
00293             /* replace components and clear signature */
00294               chgfld(&(new_prod -> prod_components), new_params);
00295               if (new_prod -> signature != ERR_SIG) {
00296                 chgfld(&(new_prod -> signature), NIL);
00297                 new_prod -> sig_done = SIG_UNKNOWN;
00298               }
00299             return(new_prod); 
00300           }
00301 
00302         case TYPESIGNATURE:
00303             /* Need to copy now so that local type id references get changed */
00304             v = copynode(p);
00305             add_dlist(p, v);
00306             chgfld(&(v -> ts_clist),
00307                    subst1(p -> ts_clist, params, args));
00308             return(v);
00309 
00310         /* The following constructs are treated specially to avoid */
00311         /* trying to substitute for declaring instances of ids     */
00312         /* Declarations are added to the list by the enclosing     */
00313         /* constructs.                                             */
00314         case TSCOMPONENT:
00315             v = subst1(p -> tsc_signature, params, args);
00316             if (v != p -> tsc_signature) {
00317                 w = copynode(p);
00318                 chgfld(&(w -> tsc_signature), v);
00319                 return(w);
00320             } else {
00321                 return(p);
00322             }
00323 
00324         case WITHLIST:
00325             /* Don't try to substitute for local id */
00326             v = subst1(p -> wl_component_list, params, args);
00327             if (v != p -> wl_component_list) {
00328                 w = copynode(p);
00329                 chgfld(&(w -> wl_component_list), v);
00330                 return(w);
00331             } else {
00332                 return(p);
00333             }
00334 
00335         case EXPORTLIST:
00336         case HIDELIST:
00337             v = subst1(p -> el_export_element_list, params, args);
00338             if (v != p -> el_export_element_list) {
00339                 w = copynode(p);
00340                 chgfld(&(w -> el_export_element_list), v);
00341                 return(w);
00342             } else {
00343                 return(p);
00344             }
00345 
00346 
00347         case RECORDELEMENT:
00348             v = subst1(p -> re_denotation, params, args);
00349             if (v != p -> re_denotation) {
00350                 w = copynode(p);
00351                 chgfld(&(w -> re_denotation), v);
00352                 return(w);
00353             } else {
00354                 return(p);
00355             }
00356 
00357         case PARAMETER:
00358             v = subst1(p -> par_signature, params, args);
00359             if (v != p -> par_signature) {
00360                 w = copynode(p);
00361                 chgfld(&(w -> par_signature), v);
00362                 return(w);
00363             } else {
00364                 return(p);
00365             }
00366 
00367         case DECLARATION:
00368           { NODE * new_sig, * new_den;
00369 
00370             new_sig = subst1(p -> decl_signature, params, args);
00371             new_den = subst1(p -> decl_denotation, params, args);
00372             if (new_sig != p -> decl_signature
00373                 || new_den != p -> decl_denotation) {
00374                 w = copynode(p);
00375                 chgfld(&(w -> decl_signature), new_sig);
00376                 chgfld(&(w -> decl_denotation), new_den);
00377                 return(w);
00378             } else {
00379                 return(p);
00380             }
00381           }
00382 
00383         /* In the following two cases it is necessary to first      */
00384         /* add all declared identifiers to the list of declarations */
00385         /* This code will probably be executed at most once a       */
00386         /* century.  Therefore no attempt is made to avoid          */
00387         /* unnecessary copies.                                      */
00388         case BLOCKDENOTATION:
00389           {
00390             NODE * new_block = copynode(p);
00391             NODE * new_decls = emptylist();
00392 
00393             /* Build new list of declarations and add them to map */
00394               maplist(s, p -> bld_declaration_list, {
00395                 v = copynode(s);
00396                 add_dlist(s, v);
00397                 addright(new_decls, v);
00398               });
00399             /* Substitute into declarations */
00400               maplist(s, new_decls, {
00401                 chgfld(&(s -> decl_signature),
00402                        subst1(s -> decl_signature, params, args));
00403                 chgfld(&(s -> decl_denotation),
00404                        subst1(s -> decl_denotation, params, args));
00405               });
00406             /* substitute into body and replace declaration list */
00407               chgfld(&(new_block -> bld_den_seq),
00408                      subst1(p -> bld_den_seq, params, args));
00409               chgfld(&(new_block -> bld_declaration_list), new_decls);
00410             /* Clear signature */
00411               if (new_block -> signature != ERR_SIG) {
00412                 chgfld(&(new_block -> signature), NIL);
00413                 new_block -> sig_done = SIG_UNKNOWN;
00414               }
00415             return(new_block); 
00416           }
00417 
00418         case FUNCCONSTR:
00419           /* Check whether params corresponds to this function  */
00420           /* construction.  If so, substitute no further, since */
00421           /* a subsequent mention of an identifier in params    */
00422           /* actually corresponds to the local declaration.     */
00423           /* This can actually happen, as in                    */
00424           /*    (Short with { I == func ...})$I [ ... ]         */
00425           /* We check identity of first parameter, since others */
00426           /* could have been added by inferargs.                */
00427             if (!is_empty(p -> signature -> fsig_param_list)
00428                 && first(params) -> pre_num == 
00429                    first(p -> signature -> fsig_param_list) -> pre_num) {
00430 #               ifdef TRACE
00431                     printf("Truncating substitution\n");
00432 #               endif
00433                 return(p);
00434             }
00435           {
00436             NODE * new_func = copynode(p);
00437             NODE * new_sig = copynode(p -> signature);
00438             NODE * new_params = emptylist();
00439 
00440             /* Build new list of parameters and add them to decl map */
00441               maplist(s, p -> signature -> fsig_param_list, {
00442                 v = copynode(s);
00443                 add_dlist(s, v);
00444                 addright(new_params, v);
00445               });
00446             /* Substitute into parameter signatures */
00447               maplist(s, new_params, {
00448                 chgfld(&(s -> par_signature),
00449                        subst1(s -> par_signature, params, args));
00450               });
00451             /* substitute into body, result sig, and replace signature */
00452               if (new_sig -> fsig_result_sig != ERR_SIG) {
00453                 chgfld(&(new_sig -> fsig_result_sig),
00454                        subst1(new_sig -> fsig_result_sig, params, args));
00455               }
00456               chgfld(&(new_sig -> fsig_param_list), new_params);
00457               chgfld(&(new_func -> fc_body),
00458                      subst1(p -> fc_body, params, args));
00459               chgfld(&(new_func -> signature), new_sig);
00460             return(new_func); 
00461           }
00462 
00463         case FUNCSIGNATURE:
00464           {
00465             NODE * new_sig = copynode(p);
00466             NODE * new_params = emptylist();
00467 
00468             /* Build new list of parameters and add them to decl map */
00469               maplist(s, p -> fsig_param_list, {
00470                 v = copynode(s);
00471                 add_dlist(s, v);
00472                 addright(new_params, v);
00473               });
00474             /* Substitute into parameter signatures */
00475               maplist(s, new_params, {
00476                 chgfld(&(s -> par_signature),
00477                        subst1(s -> par_signature, params, args));
00478               });
00479             /* substitute into body, result sig, and replace signature */
00480               if (new_sig -> fsig_result_sig != ERR_SIG) {
00481                 chgfld(&(new_sig -> fsig_result_sig),
00482                        subst1(new_sig -> fsig_result_sig, params, args));
00483               }
00484               chgfld(&(new_sig -> fsig_param_list), new_params);
00485             return(new_sig); 
00486           }
00487 
00488         default:
00489         deflt:
00490             i = 0;
00491             q = (NODE **) p;
00492             sigv = stsigs[knd];
00493             plinkv = stplinks[knd];
00494             lim = stsize[knd];
00495             for(; i < lim;
00496                 (plinkv <<= 1, sigv <<= 1, q++, i++)) {
00497                 if (plinkv < 0 && sigv >= 0 /* non-sig primary link */) {
00498                     tmpcopy[i] = subst1(*q, params, args);
00499                             /* should be locked but ... */
00500                     if(tmpcopy[i] != *q) {
00501                         mod_flag = TRUE;
00502                     }
00503                 } else {
00504                     tmpcopy[i] = *q;
00505                             /* again ... */
00506                 }
00507             }
00508             if (mod_flag) {
00509                 /* zero out signatures and clear sig_done fields */
00510                     for((sigv = stsigs[knd], i = 0); sigv != 0;
00511                         (sigv <<= 1, i++)) {
00512                         if (sigv < 0) {
00513                             tmpcopy[i] = 0;
00514                             tmpcopy[i+1] = SIG_UNKNOWN;
00515                         }
00516                     }
00517                 return(copynode((NODE *)tmpcopy));
00518             } else {
00519                 return(p);
00520             }
00521     }
00522 }
00523 
00524 /* Returns TRUE if the expression p is safe to substitute even if its */
00525 /* signature can't be found.                                          */
00526 /* Assumes that an attempt has been made to find the signature of p.  */
00527 /* Thus at least some partial information is known.                   */
00528 boolean trivial(p)
00529 NODE * p;
00530 {
00531     switch(p -> kind) {
00532         case LETTERID:
00533         case OPRID:
00534             if (!p -> id_def_found) {
00535                 return(FALSE);
00536             }
00537             if (p -> sel_type == NIL) {
00538                 return(TRUE);
00539             } else {
00540                 return(trivial(p -> sel_type));
00541             }
00542         default:
00543             return(FALSE);
00544     }
00545 }
00546 
00547 /* Return a structure identical to p, but insure that nodes that will */
00548 /* contain context sensitive information are copied, so that this     */
00549 /* information can be distinct for different contexts.                */
00550 /* Such information is relevant only for expressions that will be     */
00551 /* evaluated.  Others are ignored.                                    */
00552 
00553 NODE * unshare1();
00554 
00555 NODE * unshare(p)
00556 NODE * p;
00557 {
00558     NODE * result;
00559 
00560     clr_dlist;
00561     result = unshare1(p);
00562     return(result);
00563 }
00564 
00565 NODE * unshare1(p)
00566 NODE * p;
00567 {
00568     boolean mod_flag = FALSE; /* One of the descendants was modified */
00569     register int knd;         /* kind field of node being examined   */
00570     int plinkv;               /* bit vector indicating primary links */
00571                               /* to be followed to recursively       */
00572                               /* substitute in subtrees              */
00573     int sigv;                 /* vector of signature pointers        */
00574     register NODE ** q;       /* pointer to link field to be         */
00575                               /* recursively examined.               */
00576     NODE * tmpcopy[MAXFIELDS];/* temporary version of result         */
00577     register NODE ** s;
00578     register int i;
00579     int lim;
00580     register struct cn * c;
00581     int j;
00582     NODE * v, * w;
00583 
00584 
00585     if (p == NIL) { return(NIL); }
00586 
00587     knd = p -> kind;
00588     switch(knd) {
00589         case LISTHEADER:
00590             i = 0;
00591             j = length(p);
00592             /* get sufficiently large chunk of memory to temporarily copy */
00593             /* the list, thus minimizing number of allocations.           */
00594                 if (j <= MAXFIELDS) {
00595                     s = tmpcopy;
00596                 } else {
00597                     s = (NODE **) malloc(j * sizeof(NODE *));
00598                 }
00599             maplist(q, p, {
00600                 s[i] = unshare1(q);
00601                         /* should be locked but ... */
00602                 if(s[i] != q) {
00603                     mod_flag = TRUE;
00604                 }
00605                 i++;
00606             });
00607             if (mod_flag) {
00608               /* convert the temporary copy in s to a real list structure */
00609               /* and return it */
00610                 NODE * result;
00611                 result = emptylist();
00612                 for (i = 0; i < j; i++) {
00613                     addright(result,s[i]);
00614                 }
00615                 if (j > MAXFIELDS) free(s);
00616                 return(result);
00617             } else {
00618                 if (j > MAXFIELDS) free(s);
00619                 return(p);
00620             }
00621 
00622         case FUNCCONSTR:
00623           /* Force a copy to be made */
00624           {
00625             NODE * new_func = copynode(p);
00626             NODE * new_sig = copynode(p -> signature);
00627             char * new_lbl = (char *) malloc(strlen(p -> fc_code_label)+8);
00628             char buf[7];
00629             static int fn_count = 0;
00630             
00631             chgfld(&(new_sig -> fsig_param_list),
00632                    unshare1(new_sig -> fsig_param_list));
00633             chgfld(&(new_func -> signature), new_sig);
00634             new_sig -> fsig_construction = new_func;
00635             chgfld(&(new_func -> fc_body), unshare1(p -> fc_body));
00636             /* Give it a new name.  We may need to generate code for it */
00637             /* in different contexts.  Such code can be different,      */
00638             /* because it could appear at a different level.            */
00639 #             ifdef DEBUG
00640                 if (p -> fc_code_label == NIL) {
00641                     dbgmsg("Unshare: missing label\n");
00642                     abort();
00643                 }
00644 #             endif
00645               strcpy(new_lbl, p -> fc_code_label);
00646               sprintf(buf, ".%d", fn_count++);
00647               strcat(new_lbl, buf);
00648               new_func -> fc_code_label = new_lbl;
00649             return(new_func); 
00650           }
00651 
00652         case DECLARATION:
00653           /* Force a copy */
00654           { NODE * new_sig, * new_den;
00655             extern NODE * clear_construction();
00656 
00657             new_sig = clear_construction(p -> decl_signature);
00658             new_den = unshare1(p -> decl_denotation);
00659             w = copynode(p);
00660             chgfld(&(w -> decl_signature), new_sig);
00661             chgfld(&(w -> decl_denotation), new_den);
00662             w -> decl_sig_done = SIG_UNKNOWN;
00663             return(w);
00664           }
00665 
00666         case PARAMETER:
00667           /* Force a top level copy.  Signature may be shared. */
00668             v = copynode(p);
00669             add_dlist(p, v);
00670             return(v);
00671 
00672         case BLOCKDENOTATION:
00673           /* First add to declaration list, then unshare subexpressions. */
00674           {
00675             NODE * new_block = copynode(p);
00676             NODE * new_decls = emptylist();
00677 
00678             /* Build new list of declarations and add them to map */
00679               maplist(s, p -> bld_declaration_list, {
00680                 v = copynode(s);
00681                 add_dlist(s, v);
00682                 addright(new_decls, v);
00683               });
00684             /* unshare declarations */
00685               maplist(s, new_decls, {
00686                 chgfld(&(s -> decl_denotation), unshare1(s -> decl_denotation));
00687               });
00688             /* Unshare body, and replace declaration list */
00689               chgfld(&(new_block -> bld_den_seq), unshare1(p -> bld_den_seq));
00690               chgfld(&(new_block -> bld_declaration_list), new_decls);
00691 
00692             new_block -> bld_flags &= ~NO_SURR_LOOP;
00693             return(new_block);
00694           }
00695 
00696         case MODPRIMARY:
00697             /* Need to copy */
00698             v = copynode(p);
00699             add_dlist(p,v);
00700             chgfld(&(v -> mp_primary), unshare1(p -> mp_primary));
00701             if (v -> mp_type_modifier != NIL) {
00702               chgfld(&(v -> mp_type_modifier), unshare1(p -> mp_type_modifier));
00703             }
00704             v -> mp_no_surr_loop = FALSE;
00705             return(v);
00706 
00707         case PRODCONSTRUCTION:
00708         case UNIONCONSTRUCTION:
00709             /* No evaluable subexpressions.  No need to look further. */
00710             return(p);
00711 
00712         case LETTERID:
00713         case OPRID:
00714             if (p -> sel_type == NIL) {
00715                 if ((w = dl_new_decl(p)) != p -> id_last_definition) {
00716                     /* Create a copy pointing to the copied declaration */
00717                     v = copynode(p);
00718                     v -> id_last_definition = w;
00719                     return(v);
00720                 } else {
00721                     return(p);
00722                 }
00723             } else {
00724                 v = unshare1(p -> sel_type);
00725                 if (v != p -> sel_type) {
00726                     w = copynode(p);
00727                     chgfld(&(w -> sel_type), v);
00728                     return(w);
00729                 } else {
00730                     return(p);
00731                 }
00732             }
00733 
00734         default:
00735             i = 0;
00736             q = (NODE **) p;
00737             sigv = stsigs[knd];
00738             plinkv = stplinks[knd];
00739             lim = stsize[knd];
00740             for(; i < lim;
00741                 (plinkv <<= 1, sigv <<= 1, q++, i++)) {
00742                 if (plinkv < 0 && sigv >= 0 /* non-sig primary link */) {
00743                     tmpcopy[i] = unshare1(*q);
00744                             /* should be locked but ... */
00745                     if(tmpcopy[i] != *q) {
00746                         mod_flag = TRUE;
00747                     }
00748                 } else {
00749                     tmpcopy[i] = *q;
00750                             /* again ... */
00751                 }
00752             }
00753             if (mod_flag) {
00754 #               ifdef VERBOSE
00755                   printf("Unshare copied node: ");
00756                   unparse_file = stdout;
00757                   unparse(p);
00758                   printf("\n");
00759 #               endif
00760                 /* Clear fsig_construction pointers. */
00761                     for((sigv = stsigs[knd], i = 0); sigv != 0;
00762                         (sigv <<= 1, i++)) {
00763                         if (sigv < 0) {
00764                             extern NODE * clear_construction();
00765                             NODE * s = tmpcopy[i];
00766 
00767                             tmpcopy[i] = clear_construction(s);
00768                         }
00769                     }
00770                 return(copynode((NODE *)tmpcopy));
00771             } else {
00772                 return(p);
00773             }
00774     }
00775 }

Generated on Fri Jan 25 10:39:47 2008 for russell by  doxygen 1.5.4