00001
00002
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
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)
00032
00033 extern int yynerrs;
00034
00035 extern int next_pre;
00036
00037
00038 # define ERR_NODE_DEFINED
00039 extern NODE * err_node;
00040
00041 extern char * err_msg;
00042
00043 NODE * declerr;
00044
00045 NODE * substerr;
00046
00047
00048
00049
00050
00051 extern int match_len;
00052 extern unsigned * match_delv;
00053
00054
00055 struct cn * dontsubst;
00056
00057
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;
00076
00077
00078 static NODE * current_type;
00079
00080 NODE * findmpsig(p)
00081 NODE * p;
00082 {
00083 NODE * sig;
00084 NODE * tm = p -> mp_type_modifier;
00085 NODE * q;
00086 Array *a;
00087 int a_len;
00088 unsigned * delv;
00089
00090 extern boolean changed_strings;
00091
00092
00093
00094 int i;
00095
00096
00097
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
00137 a = list_to_array(tm -> wl_component_list);
00138 a_len = a -> a_size;
00139
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
00170
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
00187 current_type = p;
00188 qsort(&a->a_body[0], a_len,
00189 (sizeof (NODE *)), comp_wlc);
00190
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
00200 {
00201 int delv_len;
00202 int delv_len_w;
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
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
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
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
00257 free_array(a);
00258 break;
00259
00260 case HIDELIST:
00261 case EXPORTLIST:
00262
00263 {
00264 int delv_len;
00265 int delv_len_w;
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
00292 || tm -> el_local_type_id != NIL
00293
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;
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
00342 nconstants = 0;
00343 for(i = 0; i < NVECTORS; i++) {
00344 nconstants += bitcnt(base[i]);
00345 }
00346
00347 for (t = delv;
00348 nconstants >= WORDLENGTH;) {
00349 *t = -1;
00350 nconstants -= WORDLENGTH;
00351 t++;
00352 }
00353
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 }
00368 } end_maplist;
00369 if (tm -> kind == EXPORTLIST) {
00370
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
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
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
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
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