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

Go to the documentation of this file.
00001 /* Perform findsig's job for MODPRIMARY nodes with currently unknown */
00002 /* signature.                                        */
00003 # define TRACE
00004 # undef TRACE
00005 # define DEBUG
00006 
00007 # define TRACE2
00008 # undef TRACE2
00009 # include <stdio.h>
00010 # include "parm.h"
00011 # include "arith.h"
00012 
00013 # include "stree/ststructs.mh"
00014 # ifdef DEBUG
00015 #   include "stree/is_ptr.h"
00016 # endif
00017 
00018 # include "sigs.h"
00019 
00020 # include "stree/Array.h"
00021 
00022 /* Needed to construct type signatures for constructions */
00023 # include "pass1/stt/sttdefs.h"
00024 
00025 extern FILE * unparse_file;
00026 
00027 extern boolean Gflag;
00028 
00029 extern boolean Nflag;
00030 
00031 # define UNDEFNAME ((sttrelptr) 0)   /* the name of an anonymous identifier */
00032 
00033 extern int yynerrs;
00034 
00035 extern int next_pre; /* needed so that comparison for declarations will */
00036                      /* continue to work.                               */
00037 
00038 # define ERR_NODE_DEFINED
00039 extern NODE * err_node;        /* node to be used for error message in lieu */
00040                                /* of current node.  Used by errmsg macros   */
00041 extern char * err_msg;         /* message to be used in lieu of usual one   */
00042 
00043 NODE * declerr;     /* declsig failure indication */
00044 
00045 NODE * substerr;    /* subst error indication       */
00046                     /* Set to something other than SUCCESS if       */
00047                     /* subst is asked to substitute an incompletely */
00048                     /* expanded expression, as indicated by         */
00049                     /* dontsubst                                    */
00050 
00051 extern int match_len;      /* length of argument type.  Set by amatch. */
00052 extern unsigned * match_delv;  /* bitvector indicating necessary deletions */
00053                                /* set by amatch.                           */
00054 
00055 struct cn * dontsubst; /* list of incompletely expanded nodes  */
00056                        /* which should not be substituted into */
00057                        /* signatures.                          */
00058 
00059 extern int comp_index;
00060 
00061 # ifdef VAX
00062     int nargs();
00063 # endif
00064 
00065 void find_inline();
00066 
00067 void Gfind_inline();
00068 
00069 NODE * declsig();
00070 
00071 boolean is_const();
00072 
00073 int comp_wlc();
00074 
00075 boolean may_fail;         /* current signature deduction may fail */
00076                           /* without dire consequences.           */
00077 
00078 static NODE * current_type; /* used as implicit parameter to comp_wlc */
00079 
00080 NODE * findmpsig(p)
00081 NODE * p;
00082 {
00083     NODE * sig; /* current approximation to result signature */
00084     NODE * tm = p -> mp_type_modifier;
00085     NODE * q;
00086     Array *a;
00087     int a_len;
00088     unsigned * delv;    /* bit vector indicating deleted */
00089                         /* components.                   */
00090     extern boolean changed_strings;
00091                         /* Set by delcomp. indicates that    */
00092                         /* either constants or concatenation */
00093                         /* were replaced.                    */
00094     int i;
00095 
00096 
00097     /* find signature of original type */
00098         if ((q = findsig(p -> mp_primary, FALSE)) != SUCCESS) {
00099 #           ifdef TRACE
00100               printf("Can't find signature of primary:\n");
00101               unparse_file = stdout;
00102               unparse(p -> mp_primary);
00103               printf("\n");
00104 #           endif
00105             p -> sig_done = SIG_UNKNOWN;
00106             return(q);
00107         }
00108         sig = p -> mp_primary -> signature;
00109 #       ifdef TRACE
00110           printf("orig_sig = %X\n", sig);
00111           if (sig != ERR_SIG) {
00112             unparse_file = stdout;
00113             unparse(sig);
00114             printf("\nrefcount = %X\n", sig -> refcount);
00115           }
00116 #       endif
00117         if (sig == ERR_SIG) {
00118             p -> signature = ERR_SIG;
00119             p -> sig_done = SIG_DONE;
00120             return(SUCCESS);
00121         }
00122         if (sig -> kind != TYPESIGNATURE) {
00123             errmsg0(p, "Non-type used in type modification");
00124             p -> signature = ERR_SIG;
00125             p -> sig_done = SIG_DONE;
00126             return(SUCCESS);
00127         }
00128 #   ifdef DEBUG
00129         if (tm == NIL) {
00130             dbgmsg("findsig: NIL type modifier\n");
00131             abort();
00132         }
00133 #   endif
00134     switch(tm -> kind) {
00135       case WITHLIST:
00136         /* create array version of list */
00137             a = list_to_array(tm -> wl_component_list);
00138             a_len = a -> a_size;
00139         /* find signatures of all components */
00140             for (i = 0; i < a_len; i++) {
00141 #               ifdef DEBUG
00142                     if(a->a_body[i] -> kind != DECLARATION) {
00143                         dbgmsg("findsig: bad wl\n");
00144                     }
00145 #               endif
00146                 (void) declsig(a->a_body[i]);
00147                 if (declerr != SUCCESS) {
00148                     p -> sig_done = SIG_UNKNOWN;
00149 #                   ifdef TRACE
00150                       printf("Can't find with list component signature:\n");
00151                       unparse_file = stdout;
00152                       unparse(a -> a_body[i] -> decl_id);
00153                       printf("\n");
00154 #                   endif
00155                     free_array(a);
00156                     return(declerr);
00157                 }
00158                 if (a -> a_body[i]
00159                       -> decl_signature != ERR_SIG) {
00160                   if(a -> a_body[i] -> decl_signature
00161                          -> kind == VARSIGNATURE) {
00162                     free_array(a);
00163                     errmsg0(a -> a_body[i],
00164                             "Variable in with list");
00165                     p -> sig_done = SIG_DONE;
00166                     p -> signature = ERR_SIG;
00167                     return(SUCCESS);
00168                   }
00169                   /* Clear ARRAY_SIZE etc. indication, since */
00170                   /* it now applies to the wrong type        */
00171                   {
00172                     int tp;
00173                     NODE * sig = a -> a_body[i] -> decl_signature;
00174 
00175                     if (sig -> kind == FUNCSIGNATURE) {
00176                       tp = special_tp(sig -> fsig_special);
00177                       if (tp == ARRAY_SIZE
00178                           || tp == ARRAY_STD_NEW
00179                           || tp == ARRAY_PTR_NEW) {
00180                           sig -> fsig_special = 0;
00181                       }
00182                     }
00183                   }
00184                 }
00185             }
00186         /* sort them */
00187             current_type = p;
00188             qsort(&a->a_body[0], a_len,
00189                   (sizeof (NODE *)), comp_wlc);
00190         /* check for duplicates */
00191             for (i = 0; i < a_len-1; i++) {
00192                 if (comp_wlc(&(a->a_body[i]),
00193                     &(a->a_body[i+1])) == 0) {
00194                     errmsg1(tm, "Duplicate declaration of %s in with",
00195                             getname(a->a_body[i]->decl_id
00196                                     ->id_str_table_index));
00197                 }
00198             }
00199         /* construct deletion vector */
00200           {
00201             int delv_len; /* length in bytes */
00202             int delv_len_w; /* length in words */
00203             unsigned *t;
00204 
00205             p -> mp_orig_length = tsig_length(sig);
00206             delv_len = roundup(p -> mp_orig_length,
00207                                WORDLENGTH) >> 3;
00208             delv_len_w = delv_len >> (LOGWL - 3);
00209             if (delv_len > 0) {
00210                 delv = (unsigned *)malloc(delv_len);
00211             } else {
00212                 delv = 0;
00213             }
00214             for (t = delv; t < delv + delv_len_w; t++) {
00215                 *t = 0;
00216             }
00217             for (i = 0; i < a_len; i++) {
00218                 if(getcomp(sig,
00219                            a -> a_body[i] -> decl_id,
00220                            NIL,
00221                            a -> a_body[i] -> decl_signature, p,
00222                            NIL,
00223                            TRUE) != NIL) {
00224                     t = delv + (comp_index >> LOGWL);
00225                     *t |= 1 << (WORDLENGTH-1 - mod(comp_index,
00226                                                    WORDLENGTH));
00227                 }
00228             }
00229           }
00230         /* delete components from signature */
00231           sig = lock(delcomp(sig, delv));
00232           if (changed_strings) {
00233             sig -> ts_string_code = NIL;
00234             sig -> ts_element_code = NIL;
00235           }
00236 #         ifdef TRACE
00237             printf("sig after deletion = %X\n", sig);
00238             printf("refcount = %X\n", sig -> refcount);
00239 #         endif
00240         /* add new values */
00241           for (i = 0; i < a_len; i++) {
00242             inscomp(sig,
00243                     a->a_body[i] -> decl_id,
00244                     a->a_body[i] -> decl_signature, p);
00245 #           ifdef TRACE
00246               printf("sig after insertion = %X\n", sig);
00247               printf("refcount = %X\n", sig -> refcount);
00248 #           endif
00249             a->a_body[i] -> decl_sel_index = comp_index;
00250           }
00251         /* replace with list with a sorted version */
00252           chgfld(&(tm -> wl_component_list), emptylist());
00253           for (i = 0; i < a_len; i++) {
00254             addright(tm -> wl_component_list, a->a_body[i]);
00255           }
00256         /* deallocate the array version */
00257           free_array(a);
00258           break;
00259 
00260       case HIDELIST:
00261       case EXPORTLIST:
00262         /* construct deletion vector */
00263           {
00264             int delv_len;  /* length in bytes */
00265             int delv_len_w;  /* length in words */
00266             unsigned *t;
00267 
00268             p -> mp_orig_length = tsig_length(sig);
00269             delv_len = roundup(p -> mp_orig_length,
00270                                WORDLENGTH
00271                               ) >> 3;
00272             delv_len_w = delv_len >> (LOGWL - 3);
00273             delv = (unsigned *)malloc(delv_len);
00274 #           ifdef TRACE
00275                 printf("findsig:export: delv_len_w = %d\n",
00276                        delv_len_w);
00277 #           endif
00278             for (t = delv; t < delv + delv_len_w; t++) {
00279                 *t = 0;
00280             }
00281             begin_maplist(s, tm -> el_export_element_list) {
00282               switch(s -> kind) {
00283 
00284               case EXPORTELEMENT:
00285                 if (s -> ee_export_list != NIL) {
00286                   errmsg0(s,
00287                       "nested export lists not implemented");
00288                 }
00289                 if(getcomp(sig,
00290                            s -> ee_id,
00291                            (s -> ee_signature == NIL /* only an optimization */
00292                             || tm -> el_local_type_id != NIL
00293                                                /* don't subst if id is given */
00294                             ? NIL : p -> mp_primary),
00295                            s -> ee_signature,
00296                            tm -> el_local_type_id == NIL? NIL : p,
00297                            NIL,
00298                            TRUE) != NIL) {
00299 #                   ifdef TRACE
00300                         printf("found comp w/ index %d\n",
00301                                comp_index);
00302 #                   endif
00303                     t = delv + (comp_index >> LOGWL);
00304                     *t |= 1 << (WORDLENGTH-1 - mod(comp_index,
00305                                                    WORDLENGTH));
00306                   if (s -> ee_signature == NIL &&
00307                       !is_unique(sig, s -> ee_id
00308                                       -> id_str_table_index)) {
00309                       errmsg1(s, "ambiguous export element: %s",
00310                               getname(s -> ee_id
00311                                         -> id_str_table_index));
00312                       unparse_file = stderr;
00313                       fprintf(stderr, "\ttype signature is: ");
00314                       unparse(sig);
00315                       fprintf(stderr, "\n");
00316                   }
00317                 } else {
00318                   errmsg1(s,
00319                           "Missing export/hide list element: %s",
00320                           getname(s -> ee_id
00321                                     -> id_str_table_index));
00322                 }
00323                 break;
00324               case ALLCONSTANTS:
00325                 {
00326                   int nconstants;  /* # of consts in orig. type */
00327                   int i;
00328                   NODE * dcs_node = first(sig -> ts_clist);
00329                   unsigned * base;
00330 
00331 #                 ifdef DEBUG
00332                     if (dcs_node -> kind != DEFCHARSIGS) {
00333                       dbgmsg("findsig: bad DEFCHARSIGS");
00334                       abort();
00335                     }
00336 #                 endif
00337 #                 ifdef TRACE
00338                     printf("processing all constants\n");
00339 #                 endif
00340                   base = &(dcs_node -> dcs_0);
00341                   /* Calculate # of constants */
00342                     nconstants = 0;
00343                     for(i = 0; i < NVECTORS; i++) {
00344                       nconstants += bitcnt(base[i]);
00345                     }
00346                   /* Fill in whole words */
00347                     for (t = delv;
00348                          nconstants >= WORDLENGTH;) {
00349                         *t = -1;
00350                         nconstants -= WORDLENGTH;
00351                         t++;
00352                     }
00353                   /* Fill in remaining bits */
00354                     for (i = 0; i < nconstants; i++) {
00355                       *t |= 1 << (WORDLENGTH-1
00356                                   - mod(i,WORDLENGTH));
00357                     }
00358                   break;
00359                 }
00360 
00361 #             ifdef DEBUG
00362                 default:
00363                     dbgmsg("findsig: bad export list\n");
00364                     abort();
00365 #             endif
00366 
00367               } /* end switch */
00368             } end_maplist;
00369             if (tm -> kind == EXPORTLIST) {
00370               /* complement deletion vector */
00371 #             ifdef TRACE
00372                 printf("complementing deletion vector\n");
00373 #             endif
00374                 for (t = delv; t < delv + delv_len_w; t++) {
00375                   *t = ~(*t);
00376                 }
00377             }
00378           }
00379         /* delete components from signature */
00380           sig = lock(delcomp(sig, delv));
00381           if (changed_strings) {
00382             sig -> ts_string_code = NIL;
00383             sig -> ts_element_code = NIL;
00384           }
00385 #         ifdef TRACE
00386             printf("sig after hide deletion = %X\n", sig);
00387             unparse_file = stdout;
00388             unparse(sig);
00389             printf("\nrefcount = %X\n", sig -> refcount);
00390 #         endif
00391         break;
00392 
00393 #     ifdef DEBUG
00394         default:
00395             dbgmsg("findsig: bad type modifier\n");
00396 #     endif
00397     }
00398     p -> mp_delete_v = (char *)delv;
00399     /* Fix up local type ids */
00400       {
00401         NODE * old_sig = sig;
00402         NODE * new_id;
00403 
00404 #       ifdef TRACE
00405           printf("Fixing local id references\n");
00406 #       endif
00407         if (sig -> ts_local_type_id == NIL) {
00408             new_id = mknode(LETTERID, UNDEFNAME);
00409         } else {
00410             new_id = copynode(sig -> ts_local_type_id);
00411         }
00412         new_id -> id_last_definition = sig;
00413         new_id -> id_def_found = TRUE;
00414         sig = tsubst(old_sig, sig, new_id, TRUE);
00415         vfree(unlock(old_sig));
00416 #       ifdef TRACE
00417           printf("sig after substitution = %X\n", sig);
00418           unparse_file = stdout;
00419           unparse(sig);
00420           printf("\nrefcount = %X\n", sig -> refcount);
00421 #       endif
00422         new_id -> id_last_definition = sig;
00423       }
00424     if (!Nflag || !(p -> mp_no_surr_loop)) {
00425         /* May need to introduce separate block and a.r. later */
00426         clear_slink_known(sig);
00427     }
00428     initsig(p, sig);
00429 #   ifdef TRACE
00430       printf("final sig = %X\n", p -> signature);
00431       printf("refcount = %X\n", p -> signature -> refcount);
00432       printf("primary sig = %X\n", p -> mp_primary -> signature);
00433       unparse_file = stdout;
00434       unparse(p -> mp_primary -> signature);
00435       printf("\nrefcount = %X\n",
00436              p -> mp_primary -> signature -> refcount);
00437 #   endif
00438     p -> sig_done = SIG_DONE;
00439     return(SUCCESS);
00440 }
00441 
00442 
00443 /* compare 2 with list components */
00444 int comp_wlc(p, q)
00445 NODE **p, **q;
00446 
00447 {
00448     register int i;
00449     char *s, *t;
00450     boolean p_is_const, q_is_const;
00451     NODE * p_sig, * q_sig;
00452 
00453     s = (char *)getname((*p) -> decl_id -> id_str_table_index);
00454     t = (char *)getname((*q) -> decl_id -> id_str_table_index);
00455     i = strcmp(s, t);
00456 
00457     p_sig = (*p) -> decl_signature;
00458     q_sig = (*q) -> decl_signature;
00459 
00460     p_is_const = s[0] == '\'' && s[2] == '\'';
00461     if (p_is_const) {
00462         p_is_const = is_const(p_sig, current_type);
00463 #       ifdef TRACE
00464             printf("character: %c, p_is_const: %d, current_type: %X\n",
00465                    s[1], p_is_const, current_type);
00466             unparse_file = stdout;
00467             unparse(p_sig);
00468             printf("\n");
00469             unparse(current_type);
00470             printf("\n");
00471 #       endif
00472     }
00473     q_is_const = t[0] == '\'' && t[2] == '\'';
00474     if (q_is_const) {
00475         q_is_const = is_const(q_sig, current_type);
00476 #       ifdef TRACE
00477             printf("character: %c, q_is_const: %d, current_type: %X\n",
00478                    t[1], q_is_const, current_type);
00479             unparse_file = stdout;
00480             unparse(q_sig);
00481             printf("\n");
00482             unparse(current_type);
00483             printf("\n");
00484 #       endif
00485     }
00486 
00487     if (p_is_const && !q_is_const) return(-1);
00488     if (q_is_const && !p_is_const) return(1);
00489 
00490     if (i == 0)
00491         return(comp_st(p_sig, q_sig,
00492                        current_type, current_type));
00493     else
00494         return(i);
00495 }
00496 

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