00001 # include "parm.h"
00002 # include <stdio.h>
00003 # include "stree/ststructs.mh"
00004 # include "stree/Array.h"
00005 # include "pass5c/codeutil.h"
00006
00007 extern int yynerrs;
00008
00009 Array * (list_to_array());
00010
00011
00012
00013 static int pre_order(p, q)
00014 NODE **p, **q;
00015 {
00016 if ((*p) -> pre_num < (*q) -> pre_num) {
00017 return(-1);
00018 } else if ((*p) -> pre_num > (*q) -> pre_num) {
00019 return(1);
00020 } else {
00021 return(0);
00022 }
00023 }
00024
00025
00026
00027 NODE * decl_sort(decl_l)
00028 NODE * decl_l;
00029 {
00030 Array * a = list_to_array(decl_l);
00031 NODE * result = emptylist();
00032 NODE **p;
00033 int i;
00034
00035 qsort(a -> a_body, a -> a_size, sizeof(NODE *), pre_order);
00036
00037
00038 for (p = a -> a_body; p < &(a -> a_body[a -> a_size]); p++) {
00039 addright(result, *p);
00040 }
00041
00042 return(result);
00043 }
00044
00045 #define NOT_REFD 0x7fffffff
00046
00047 void label_refd_decls();
00048 void find_forward_refs();
00049
00050 static NODE * current_scope;
00051 static NODE * current_mp;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 NODE * label_decls(decl_l)
00069 NODE * decl_l;
00070 {
00071 int len = length(decl_l);
00072 register int i;
00073
00074 if (len == 0) return(decl_l);
00075 ASSERT(decl_l -> kind == LISTHEADER, "label_decls: bad declaration list\n");
00076
00077 current_scope = first(decl_l) -> decl_scope;
00078 current_mp = NIL;
00079
00080 maplist(p ,decl_l, {
00081 p -> decl_can_be_refd = NOT_REFD;
00082 });
00083 maplist(p, decl_l, {
00084
00085
00086
00087 switch(p -> decl_denotation -> kind) {
00088 case FUNCCONSTR:
00089
00090
00091
00092 break;
00093 case MODPRIMARY:
00094 {
00095 NODE * den = p -> decl_denotation;
00096
00097
00098
00099 while (den -> kind == MODPRIMARY) {
00100 if (den -> mp_type_modifier == NIL
00101 || den -> mp_type_modifier -> kind == EXPORTLIST
00102 || den -> mp_type_modifier -> kind == HIDELIST) {
00103 den = den -> mp_primary;
00104 } else {
00105 ASSERT(den -> mp_type_modifier -> kind
00106 == WITHLIST, "label_decls: bad mp\n");
00107 maplist(s, den -> mp_type_modifier
00108 -> wl_component_list, {
00109 ASSERT(s -> kind == DECLARATION,
00110 "label_decls: bad wl\n");
00111 if (s -> decl_denotation -> kind != FUNCCONSTR) {
00112 label_refd_decls(s -> decl_denotation,
00113 p -> pre_num);
00114 }
00115 });
00116 den = den -> mp_primary;
00117 }
00118 }
00119 label_refd_decls(den, p -> pre_num);
00120 break;
00121 }
00122 default:
00123 label_refd_decls(p -> decl_denotation, p -> pre_num);
00124 break;
00125 }
00126 });
00127
00128 maplist(p, decl_l, {
00129 if (p -> decl_denotation -> kind == FUNCCONSTR) {
00130 if (p -> decl_can_be_refd != NOT_REFD) {
00131 find_forward_refs(p -> decl_denotation, p -> decl_can_be_refd);
00132 }
00133 } else {
00134 if (p -> decl_can_be_refd < p -> pre_num) {
00135 find_forward_refs(p -> decl_denotation, p -> decl_can_be_refd);
00136 } else {
00137 find_forward_refs(p -> decl_denotation, p -> pre_num);
00138 }
00139 }
00140 });
00141 return(decl_l);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 LIST
00151 label_wl(mp)
00152 NODE * mp;
00153 {
00154 int len;
00155 NODE * decl_l;
00156
00157 ASSERT(mp -> kind == MODPRIMARY
00158 && mp -> mp_type_modifier -> kind == WITHLIST,
00159 "label_wl: bad with list");
00160 decl_l = mp -> mp_type_modifier -> wl_component_list;
00161 len = length(decl_l);
00162 if (len == 0) return(decl_l);
00163 ASSERT(decl_l -> kind == LISTHEADER, "wl_sort: bad declaration list\n");
00164
00165 current_scope = NIL;
00166 current_mp = mp;
00167
00168 maplist(p ,decl_l, {
00169 p -> decl_can_be_refd = NOT_REFD;
00170 });
00171 maplist(p, decl_l, {
00172
00173
00174
00175 if (p -> decl_denotation -> kind != FUNCCONSTR) {
00176 label_refd_decls(p -> decl_denotation, p -> pre_num);
00177 }
00178 });
00179
00180 maplist(p, decl_l, {
00181 if (p -> decl_denotation -> kind == FUNCCONSTR) {
00182 if (p -> decl_can_be_refd != NOT_REFD) {
00183 find_forward_refs(p -> decl_denotation, p -> decl_can_be_refd);
00184 }
00185 } else {
00186 if (p -> decl_can_be_refd < p -> pre_num) {
00187 find_forward_refs(p -> decl_denotation, p -> decl_can_be_refd);
00188 } else {
00189 find_forward_refs(p -> decl_denotation, p -> pre_num);
00190 }
00191 }
00192 });
00193 return(decl_l);
00194 }
00195
00196
00197
00198
00199
00200
00201 void label_refd_decls(p, prenum)
00202 NODE * p;
00203 int prenum;
00204 {
00205 switch(p -> kind) {
00206 case BLOCKDENOTATION:
00207 maplist(s, p -> bld_declaration_list, {
00208 label_refd_decls(s -> decl_denotation, prenum);
00209 });
00210 maplist(s, p -> bld_den_seq, {
00211 label_refd_decls(s, prenum);
00212 });
00213 break;
00214
00215 case USELIST:
00216 maplist(s, p -> usl_type_list, {
00217 label_refd_decls(s, prenum);
00218 });
00219 maplist(s, p -> usl_den_seq, {
00220 label_refd_decls(s, prenum);
00221 });
00222 break;
00223
00224 case APPLICATION:
00225 label_refd_decls(p -> ap_operator, prenum);
00226 maplist(s, p -> ap_args, {
00227 label_refd_decls(s, prenum);
00228 });
00229 break;
00230
00231 case EXTENSION:
00232
00233
00234 label_refd_decls(p -> ext_denotation, prenum);
00235 break;
00236
00237 case RECORDCONSTRUCTION:
00238 maplist(s, p -> rec_component_list, {
00239 label_refd_decls(s -> re_denotation, prenum);
00240 });
00241 break;
00242
00243 case WORDELSE:
00244 case ENUMERATION:
00245 case PRODCONSTRUCTION:
00246 case UNIONCONSTRUCTION:
00247 case EXTERNDEF:
00248 case REXTERNDEF:
00249
00250 break;
00251
00252 case MODPRIMARY:
00253 {
00254 NODE * tm = p -> mp_type_modifier;
00255
00256 label_refd_decls(p -> mp_primary, prenum);
00257 if (tm != NIL && tm -> kind == WITHLIST) {
00258 maplist(s, tm -> wl_component_list, {
00259 label_refd_decls(s -> decl_denotation, prenum);
00260 });
00261 }
00262 }
00263 break;
00264
00265 case GUARDEDLIST:
00266 case LOOPDENOTATION:
00267 maplist(s, p -> gl_list, {
00268 label_refd_decls(s -> ge_guard, prenum);
00269 label_refd_decls(s -> ge_element, prenum);
00270 });
00271 break;
00272
00273 case OPRID:
00274 case LETTERID:
00275 ASSERT(p -> id_str_table_index != -1,
00276 "label_refd_decls: Funny identifier\n");
00277 if (current_mp == NIL) {
00278 NODE * def = p -> id_last_definition;
00279
00280 if (p -> sel_type != NIL) {
00281 label_refd_decls(p -> sel_type, prenum);
00282 } else if (def -> kind == DECLARATION
00283 && def -> decl_scope == current_scope) {
00284
00285
00286 if (prenum < def -> decl_can_be_refd) {
00287 def -> decl_can_be_refd = prenum;
00288 label_refd_decls(def -> decl_denotation, prenum);
00289 }
00290 }
00291 } else {
00292 NODE * sel_t = p -> sel_type;
00293
00294 if (sel_t == NIL) {
00295 if (p -> id_last_definition == current_mp) {
00296
00297 errmsg0(p, "Warning - forward reference to local type identifier - no runtime check inserted");
00298 yynerrs--;
00299 }
00300 } else {
00301
00302 if (( sel_t -> kind == LETTERID
00303 || sel_t -> kind == OPRID)
00304 && sel_t -> sel_type == NIL
00305 && sel_t -> id_last_definition == current_mp) {
00306
00307
00308
00309 maplist(s, current_mp -> mp_type_modifier
00310 -> wl_component_list, {
00311 if (s -> decl_sel_index
00312 == p -> sel_index) {
00313
00314 if (prenum < s -> decl_can_be_refd) {
00315 s -> decl_can_be_refd = prenum;
00316 label_refd_decls(s -> decl_denotation,
00317 prenum);
00318 }
00319 }
00320 });
00321 } else {
00322 label_refd_decls(sel_t, prenum);
00323 }
00324 }
00325 }
00326 break;
00327
00328 case QSTR:
00329 case UQSTR:
00330 if (current_mp != NIL) {
00331
00332
00333
00334 if (p -> sel_type -> signature -> ts_string_code != NIL &&
00335 p -> sel_type -> signature -> ts_element_code != NIL) {
00336
00337 } else {
00338 label_refd_decls(p -> str_expansion, prenum);
00339 }
00340 } else {
00341
00342
00343 label_refd_decls(p -> sel_type, prenum);
00344 }
00345 break;
00346
00347 case FUNCCONSTR:
00348
00349 label_refd_decls(p -> fc_body, prenum);
00350 break;
00351
00352 # ifdef DEBUG
00353 default:
00354 dbgmsg("label_refd_decls: bad kind encountered\n");
00355 abort();
00356 # endif
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365 void find_forward_refs(p, prenum)
00366 NODE * p;
00367 int prenum;
00368 {
00369 switch(p -> kind) {
00370 case BLOCKDENOTATION:
00371 maplist(s, p -> bld_declaration_list, {
00372 find_forward_refs(s -> decl_denotation, prenum);
00373 });
00374 maplist(s, p -> bld_den_seq, {
00375 find_forward_refs(s, prenum);
00376 });
00377 break;
00378
00379 case USELIST:
00380 maplist(s, p -> usl_type_list, {
00381 find_forward_refs(s, prenum);
00382 });
00383 maplist(s, p -> usl_den_seq, {
00384 find_forward_refs(s, prenum);
00385 });
00386 break;
00387
00388 case APPLICATION:
00389 find_forward_refs(p -> ap_operator, prenum);
00390 maplist(s, p -> ap_args, {
00391 find_forward_refs(s, prenum);
00392 });
00393 break;
00394
00395 case EXTENSION:
00396
00397
00398 find_forward_refs(p -> ext_denotation, prenum);
00399 break;
00400
00401 case RECORDCONSTRUCTION:
00402 maplist(s, p -> rec_component_list, {
00403 find_forward_refs(s -> re_denotation, prenum);
00404 });
00405 break;
00406
00407 case WORDELSE:
00408 case ENUMERATION:
00409 case PRODCONSTRUCTION:
00410 case UNIONCONSTRUCTION:
00411 case EXTERNDEF:
00412 case REXTERNDEF:
00413
00414 break;
00415
00416 case MODPRIMARY:
00417 {
00418 NODE * tm = p -> mp_type_modifier;
00419
00420 find_forward_refs(p -> mp_primary, prenum);
00421 if (tm != NIL && tm -> kind == WITHLIST) {
00422 maplist(s, tm -> wl_component_list, {
00423 label_refd_decls(s -> decl_denotation, prenum);
00424 });
00425 }
00426 }
00427 break;
00428
00429 case GUARDEDLIST:
00430 case LOOPDENOTATION:
00431 maplist(s, p -> gl_list, {
00432 find_forward_refs(s -> ge_guard, prenum);
00433 find_forward_refs(s -> ge_element, prenum);
00434 });
00435 break;
00436
00437 case OPRID:
00438 case LETTERID:
00439 ASSERT(p -> id_str_table_index != -1,
00440 "find_forward_refs: Funny identifier\n");
00441 if (current_mp == NIL) {
00442 NODE * def = p -> id_last_definition;
00443
00444 if (p -> sel_type != NIL) {
00445 find_forward_refs(p -> sel_type, prenum);
00446 } else if (def -> kind == DECLARATION
00447 && def -> decl_scope == current_scope) {
00448
00449
00450 if (prenum <= def -> pre_num) {
00451 p -> id_forward_ref = TRUE;
00452 }
00453 }
00454 } else {
00455 NODE * sel_t = p -> sel_type;
00456
00457 if (sel_t != NIL) {
00458
00459 if (( sel_t -> kind == LETTERID
00460 || sel_t -> kind == OPRID)
00461 && sel_t -> sel_type == NIL
00462 && sel_t -> id_last_definition == current_mp) {
00463
00464
00465 maplist(s, current_mp -> mp_type_modifier
00466 -> wl_component_list, {
00467 if (s -> decl_sel_index
00468 == p -> sel_index) {
00469
00470 if (prenum <= s -> pre_num) {
00471 p -> id_forward_ref = TRUE;
00472 }
00473 }
00474 });
00475 } else {
00476 find_forward_refs(sel_t, prenum);
00477 }
00478 }
00479 }
00480 break;
00481
00482 case QSTR:
00483 case UQSTR:
00484 if (current_mp != NIL) {
00485
00486
00487
00488 if (p -> sel_type -> signature -> ts_string_code != NIL &&
00489 p -> sel_type -> signature -> ts_string_code != NIL) {
00490
00491 } else {
00492 find_forward_refs(p -> str_expansion, prenum);
00493 }
00494 } else {
00495
00496
00497 find_forward_refs(p -> sel_type, prenum);
00498 }
00499 break;
00500
00501 case FUNCCONSTR:
00502
00503 find_forward_refs(p -> fc_body, prenum);
00504 break;
00505
00506 # ifdef DEBUG
00507 default:
00508 dbgmsg("find_forward_refs: bad kind encountered\n");
00509 abort();
00510 # endif
00511 }
00512 }