00001 # define DEBUG
00002 # define TRACE
00003 # undef TRACE
00004
00005 # ifdef TRACE
00006 # define IFTRACE(x) x
00007 # else
00008 # define IFTRACE(x)
00009 # endif
00010 # include <stdio.h>
00011 # include "parm.h"
00012
00013 # include "stree/ststructs.mh"
00014
00015 # include "pass1/stt/sttdefs.h"
00016
00017 # include "sigs.h"
00018
00019 # include "../pass3/is_local.h"
00020
00021 extern unsigned stplinks[];
00022
00023 extern FILE * unparse_file;
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 NODE * fixhints(sig,sig2)
00038 NODE * sig,*sig2;
00039 {
00040 boolean mod_flag = FALSE;
00041 boolean in_line_differs, special_differs, constr_differs;
00042 boolean slink_known_differs;
00043 NODE * tmpcopy[MAXFIELDS];
00044 NODE ** s;
00045 NODE * p, *r;
00046 NODE * ncopy;
00047 register int i;
00048 register struct cn * c;
00049 int j;
00050
00051 if (sig == ERR_SIG || sig == NIL || sig2 == ERR_SIG ) {
00052 return(sig);
00053 }
00054
00055 switch ( sig -> kind ) {
00056 case VALSIGNATURE:
00057 case VARSIGNATURE:
00058 return(sig);
00059
00060 case TSCOMPONENT:
00061 if (sig2 -> kind != TSCOMPONENT) return(sig);
00062 p = fixhints(sig -> tsc_signature, sig2 -> tsc_signature);
00063 if (p != sig -> tsc_signature) {
00064 ncopy = copynode(sig);
00065 chgfld(&(ncopy -> tsc_signature), p);
00066 return(ncopy);
00067 } else {
00068 return(sig);
00069 }
00070
00071 case DEFCHARSIGS:
00072
00073
00074 if (sig -> dcs_exceptions != NIL) {
00075 p = copynode(sig);
00076 chgfld(&(p -> dcs_exceptions), NIL);
00077 }
00078 return(p);
00079
00080 case TYPESIGNATURE:
00081 # ifdef TRACE
00082 printf("fixhints: \n");
00083 unparse_file = stdout;
00084 unparse(sig);
00085 printf("\n");
00086 unparse(sig2);
00087 printf("refcounts: %d, %d\n", sig -> refcount, sig2 -> refcount);
00088 # endif
00089 if (sig2 == NIL) {
00090 ncopy = copynode(sig);
00091
00092 ncopy -> ts_simple_type = FALSE;
00093 ncopy -> ts_const_code = NIL;
00094 ncopy -> ts_string_code = NIL;
00095 ncopy -> ts_element_code = NIL;
00096 return(ncopy);
00097 }
00098 if (sig2 -> kind != TYPESIGNATURE) return(sig);
00099 p = sig -> ts_clist;
00100 r = sig2 -> ts_clist;
00101 i = 0;
00102 j = length(p);
00103
00104
00105 if (j <= MAXFIELDS) {
00106 s = tmpcopy;
00107 } else {
00108 s = (NODE **) malloc(j * sizeof(NODE *));
00109 }
00110 map2lists(q, p, t, r, {
00111 IFTRACE(
00112 printf("fixhints: tsc:\n");
00113 unparse_file = stdout;
00114 unparse(q);
00115 printf("\n");
00116 unparse(t);
00117 printf("refcounts: %d, %d\n", q -> refcount, t -> refcount);
00118 )
00119 s[i] = fixhints(q, t);
00120 IFTRACE(
00121 printf("Returned refcount: %d\n", s[i] -> refcount);
00122 )
00123
00124 if(s[i] != q) {
00125 IFTRACE(
00126 printf("Modified\n");
00127 )
00128 mod_flag = TRUE;
00129 }
00130 i++;
00131 });
00132 if (mod_flag) {
00133
00134
00135 NODE * result;
00136 result = emptylist();
00137 for (i = 0; i < j; i++) {
00138 addright(result,s[i]);
00139 # ifdef TRACE
00140 printf("Added %X(%d)\n", s[i], s[i] -> refcount);
00141 if (s[i] -> kind == TSCOMPONENT) {
00142 unparse_file = stdout;
00143 unparse(s[i] -> tsc_id);
00144 printf(":");
00145 unparse(s[i] -> tsc_signature);
00146 printf("\n");
00147 } else {
00148 printf("constants");
00149 }
00150 # endif
00151 }
00152 if (j > MAXFIELDS) free(s);
00153 ncopy = copynode(sig);
00154
00155 chgfld(&(ncopy -> ts_clist), result);
00156 } else {
00157 if (j > MAXFIELDS) free(s);
00158 if (sig -> ts_simple_type && !(sig2 -> ts_simple_type)
00159 || sig -> ts_const_code != sig2 -> ts_const_code
00160 || sig -> ts_string_code != sig2 -> ts_string_code
00161 || sig -> ts_element_code != sig -> ts_element_code) {
00162 ncopy = copynode(sig);
00163 } else {
00164 return(sig);
00165 }
00166 }
00167 # define make_consistent(field,val) \
00168 if (sig -> field != sig2 -> field) {ncopy -> field = val;}
00169 make_consistent(ts_simple_type, FALSE);
00170 make_consistent(ts_const_code, NIL);
00171 make_consistent(ts_string_code, NIL);
00172 make_consistent(ts_element_code, NIL);
00173 return(ncopy);
00174
00175 case FUNCSIGNATURE:
00176 if (sig2 == NIL) {
00177 ncopy = copynode(sig);
00178 ncopy -> fsig_inline_code = NIL;
00179 return(ncopy);
00180 }
00181 if (sig2 -> kind != FUNCSIGNATURE) return(sig);
00182 p = fixhints(sig -> fsig_result_sig, sig2 -> fsig_result_sig);
00183 in_line_differs =
00184 (sig -> fsig_inline_code != sig2 -> fsig_inline_code);
00185 special_differs =
00186 (sig -> fsig_special != sig2 -> fsig_special);
00187 constr_differs =
00188 (sig -> fsig_construction != sig2 -> fsig_construction);
00189 slink_known_differs =
00190 (sig -> fsig_slink_known != sig2 -> fsig_slink_known);
00191 if (p != sig -> fsig_result_sig || in_line_differs
00192 || special_differs || constr_differs || slink_known_differs) {
00193 ncopy = copynode(sig);
00194 } else {
00195 ncopy = sig;
00196 }
00197 if (p != sig -> fsig_result_sig) {
00198 chgfld(&ncopy -> fsig_result_sig, p);
00199 }
00200 if (in_line_differs) {
00201 ncopy -> fsig_inline_code = NIL;
00202 }
00203 if (special_differs) {
00204 ncopy -> fsig_special = NOT_SPECIAL;
00205 }
00206 if (constr_differs) {
00207 ncopy -> fsig_construction = NIL;
00208 }
00209 if (slink_known_differs) {
00210 ncopy -> fsig_slink_known = FALSE;
00211 }
00212 return(ncopy);
00213
00214 # ifdef DEBUG
00215 default:
00216 dbgmsg("fixhints: bad signature");
00217 abort(sig,sig2);
00218 # endif
00219
00220 }
00221 }
00222
00223
00224
00225
00226
00227
00228 # define UNKNOWN -1
00229
00230 long int_value(e)
00231 NODE * e;
00232 {
00233 extern NODE * id_Integer;
00234
00235 switch (e -> kind) {
00236 case LETTERID:
00237 if (e -> id_def_found && e -> sel_type == NIL &&
00238 e -> id_last_definition -> kind == DECLARATION &&
00239 e -> id_last_definition -> post_num < e -> post_num) {
00240
00241 return(int_value(e -> id_last_definition -> decl_denotation));
00242 } else {
00243 return(UNKNOWN);
00244 }
00245
00246 case UQSTR:
00247 {
00248 NODE * sel_tp = e -> sel_type;
00249
00250 if (sel_tp -> kind != LETTERID
00251 || (!sel_tp -> id_def_found)
00252 || (!is_declared_by(sel_tp,
00253 id_Integer -> id_last_definition))) {
00254 return(UNKNOWN);
00255 } else {
00256
00257 return(atoi(e -> str_string));
00258 }
00259 }
00260
00261 case APPLICATION:
00262 if (e -> ap_operator -> kind != OPRID
00263 || e -> ap_operator -> sel_type == NIL) {
00264 return(UNKNOWN);
00265 } else {
00266 NODE * sel_tp = e -> ap_operator -> sel_type;
00267 extern long indx_plus;
00268
00269 if (sel_tp -> kind != LETTERID
00270 || (!sel_tp -> id_def_found)
00271 || (!is_declared_by(sel_tp,
00272 id_Integer -> id_last_definition))) {
00273 return(UNKNOWN);
00274 }
00275 if (e -> ap_operator -> id_str_table_index == indx_plus) {
00276 long arg1 = int_value(first(e -> ap_args));
00277 long arg2 = int_value(last(e -> ap_args));
00278 if (arg1 != UNKNOWN && arg2 != UNKNOWN) {
00279 return(arg1 + arg2);
00280 } else {
00281 return(UNKNOWN);
00282 }
00283 } else {
00284
00285 return(UNKNOWN);
00286 }
00287 }
00288
00289 default:
00290 return(UNKNOWN);
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301 void fix_array_sig(sig, size, etype)
00302 NODE * sig;
00303 NODE * size;
00304 NODE * etype;
00305 {
00306 long size_val = int_value(size);
00307 NODE * e_sig = sig_structure(etype -> signature);
00308 NODE * e_V_sig;
00309 NODE * e_New_sig;
00310 sttrelptr comp_id;
00311 extern sttrelptr indx_subscr;
00312 extern sttrelptr indx_New;
00313 extern sttrelptr indx_ValueOf;
00314 extern sttrelptr indx_size;
00315 boolean std_e_V;
00316 boolean std_e_New;
00317 boolean ptr_e_New;
00318 extern NODE * id_New;
00319 extern NODE * id_ValueOf;
00320 extern FILE * unparse_file;
00321 int tp;
00322
00323 # ifdef VERBOSE
00324 printf("entering fix_array_sig(%X, ...)\nelement sig:\n", sig);
00325 unparse_file = stdout;
00326 unparse(e_sig);
00327 printf("\n");
00328 # endif
00329 if (sig == ERR_SIG || e_sig == ERR_SIG
00330 || e_sig -> kind != TYPESIGNATURE) return;
00331 if (size_val == UNKNOWN || size_val > MAX_SP_VAL) {
00332 size_val = 0;
00333 }
00334 e_V_sig = getcomp(e_sig, id_ValueOf, NIL,
00335 NIL, NIL, NIL, FALSE);
00336 if (e_V_sig == ERR_SIG) return;
00337 e_New_sig = getcomp(e_sig, id_New, NIL,
00338 NIL, NIL, NIL, FALSE);
00339 if (e_New_sig == ERR_SIG) return;
00340 if (e_V_sig == NIL || e_New_sig == NIL) {
00341 return;
00342
00343 }
00344 std_e_V = (special_tp(e_V_sig -> fsig_special) == STD_VALUEOF
00345 && special_val(e_V_sig -> fsig_special) == 1);
00346 tp = special_tp(e_New_sig -> fsig_special);
00347 std_e_New = (tp == STD_NEW
00348 && special_val(e_New_sig -> fsig_special) == 1);
00349 ptr_e_New = (tp == UNION_NEW || tp == PROD_NEW ||
00350 (tp == PTR_NEW
00351 && special_val(e_New_sig -> fsig_special) == 1));
00352 # ifdef VERBOSE
00353 printf("V special = 0x%X, New special = 0x%X\n",
00354 e_V_sig -> fsig_special, e_New_sig -> fsig_special);
00355 printf("std_e_V = %d, std_e_New = %d, ptr_e_New = %d\n",
00356 std_e_V, std_e_New, ptr_e_New);
00357 # endif
00358 maplist(s, sig -> ts_clist, {
00359 if (s -> kind == TSCOMPONENT) {
00360 comp_id = s -> tsc_id -> id_str_table_index;
00361 if (comp_id == indx_New) {
00362 if (std_e_New) {
00363 s -> tsc_signature -> fsig_special =
00364 special(ARRAY_STD_NEW, size_val);
00365 } else if (ptr_e_New) {
00366 s -> tsc_signature -> fsig_special =
00367 special(ARRAY_PTR_NEW, size_val);
00368 }
00369 } else if (comp_id == indx_ValueOf) {
00370 if (std_e_V) {
00371 s -> tsc_signature -> fsig_special =
00372 special(ARRAY_VALUEOF, size_val);
00373 }
00374 } else if (comp_id == indx_size) {
00375 s -> tsc_signature -> fsig_special =
00376 special(ARRAY_SIZE, size_val);
00377 } else if (comp_id == indx_subscr) {
00378 if (s -> tsc_signature -> fsig_result_sig -> kind
00379 == VARSIGNATURE) {
00380 s -> tsc_signature -> fsig_special =
00381 special(ARRAY_VAR_SUB, size_val);
00382 } else {
00383 s -> tsc_signature -> fsig_special =
00384 special(ARRAY_VAL_SUB, size_val);
00385 }
00386 }
00387 }
00388 });
00389 }
00390
00391
00392
00393 void clear_slink_known(sig)
00394 NODE * sig;
00395 {
00396 NODE * p;
00397 NODE * q;
00398
00399 if (sig == ERR_SIG || sig == NIL) {
00400 return;
00401 }
00402
00403 switch ( sig -> kind ) {
00404 case LETTERID:
00405 case OPRID:
00406 if (p -> id_last_definition == NIL) {
00407 dbgmsg("clear_slink_known: unresolved id reference\n");
00408 }
00409
00410
00411
00412 break;
00413
00414 case VARSIGNATURE:
00415 case VALSIGNATURE:
00416 case SIGNATURESIG:
00417 break;
00418
00419 case TYPESIGNATURE:
00420 p = sig -> ts_clist;
00421 maplist(q, p, {
00422 if (q -> kind == TSCOMPONENT) {
00423 clear_slink_known(q -> tsc_signature);
00424 }
00425 });
00426 break;
00427
00428 case FUNCSIGNATURE:
00429 sig -> fsig_slink_known = FALSE;
00430 break;
00431
00432 # ifdef DEBUG
00433 default:
00434 dbgmsg("clear_slink_known: bad signature");
00435 abort(sig);
00436 # endif
00437
00438 }
00439 }
00440
00441
00442
00443 NODE * clear_construction(sig)
00444 NODE * sig;
00445 {
00446 NODE * p;
00447 NODE * q;
00448
00449 if (sig == ERR_SIG || sig == NIL) {
00450 return(sig);
00451 }
00452
00453 switch ( sig -> kind ) {
00454 case LETTERID:
00455 case OPRID:
00456 # ifdef DEBUG
00457 if (p -> id_last_definition == NIL) {
00458 dbgmsg("clear_construction: unresolved id reference\n");
00459 }
00460 # endif
00461
00462
00463
00464 return(sig);
00465
00466 case VARSIGNATURE:
00467 case VALSIGNATURE:
00468 case SIGNATURESIG:
00469 return(sig);
00470
00471 case TYPESIGNATURE:
00472 {
00473 boolean modified = FALSE;
00474 NODE * new_comp_list = emptylist();
00475 NODE * new_comp;
00476
00477 maplist(s, sig -> ts_clist, {
00478 if (s -> kind == TSCOMPONENT) {
00479 p = clear_construction(s -> tsc_signature);
00480 if (p != s -> tsc_signature) {
00481 modified = TRUE;
00482 new_comp = copynode(s);
00483 chgfld(&(new_comp -> tsc_signature), p);
00484 addright(new_comp_list, new_comp);
00485 } else {
00486 addright(new_comp_list, s);
00487 }
00488 } else if (s -> kind == DEFCHARSIGS) {
00489 if (s -> dcs_exceptions != NIL) {
00490
00491 modified = TRUE;
00492 new_comp = copynode(s);
00493 chgfld(&(new_comp -> dcs_exceptions), NIL);
00494 addright(new_comp_list, new_comp);
00495 } else {
00496 addright(new_comp_list, s);
00497 }
00498 } else {
00499 dbgmsg("clear_construction: bad typesignature\n");
00500 }
00501 });
00502 if (modified) {
00503 p = copynode(sig);
00504 chgfld(&(p -> ts_clist), new_comp_list);
00505 return(p);
00506 } else {
00507 vfree(new_comp_list);
00508 return(sig);
00509 }
00510 }
00511
00512 case FUNCSIGNATURE:
00513 p = clear_construction(sig -> fsig_result_sig);
00514 if (p != sig -> fsig_result_sig
00515 || sig -> fsig_construction != NIL) {
00516 q = copynode(sig);
00517 chgfld (&(q -> fsig_result_sig),p);
00518 q -> fsig_construction = NIL;
00519 return(q);
00520 } else {
00521 return(sig);
00522 }
00523
00524 # ifdef DEBUG
00525 default:
00526 dbgmsg("clear_construction: bad signature");
00527 abort(sig);
00528 # endif
00529
00530 }
00531 }
00532