gengtype.c revision 117395
11844Swollman/* Process source files and output type information. 250476Speter Copyright (C) 2002 Free Software Foundation, Inc. 323549Swosch 423549SwoschThis file is part of GCC. 5139761Skrion 623549SwoschGCC is free software; you can redistribute it and/or modify it under 723549Swoschthe terms of the GNU General Public License as published by the Free 823549SwoschSoftware Foundation; either version 2, or (at your option) any later 923549Swoschversion. 1023549Swosch 1123549SwoschGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1223549SwoschWARRANTY; without even the implied warranty of MERCHANTABILITY or 1323549SwoschFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1423549Swoschfor more details. 1595327Sobrien 1623549SwoschYou should have received a copy of the GNU General Public License 1723549Swoschalong with GCC; see the file COPYING. If not, write to the Free 1823549SwoschSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 1923549Swosch02111-1307, USA. */ 2023549Swosch 2123549Swosch#include "hconfig.h" 2223549Swosch#include "system.h" 2323549Swosch#include "gengtype.h" 2423549Swosch#include "gtyp-gen.h" 2523549Swosch 2623549Swosch/* Nonzero iff an error has occurred. */ 27200178Sedstatic int hit_error = 0; 28200178Sed 29200178Sedstatic void gen_rtx_next PARAMS ((void)); 3023549Swoschstatic void write_rtx_next PARAMS ((void)); 311638Srgrimesstatic void open_base_files PARAMS ((void)); 3294940Srustatic void close_output_files PARAMS ((void)); 3323549Swosch 3499875Sru/* Report an error at POS, printing MSG. */ 3599875Sru 3699875Sruvoid 3799875Sruerror_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...)) 38133369Sharti{ 3999875Sru VA_OPEN (ap, msg); 4099875Sru VA_FIXEDARG (ap, struct fileloc *, pos); 4199875Sru VA_FIXEDARG (ap, const char *, msg); 4299875Sru 4395306Sru fprintf (stderr, "%s:%d: ", pos->file, pos->line); 4499875Sru vfprintf (stderr, msg, ap); 45133369Sharti fputc ('\n', stderr); 4695306Sru hit_error = 1; 47134903Simp 4890311Sru VA_CLOSE (ap); 4990311Sru} 5090311Sru 51134903Simp/* vasprintf, but produces fatal message on out-of-memory. */ 5290311Sruint 5390311Sruxvasprintf (result, format, args) 5490311Sru char ** result; 5590311Sru const char *format; 5695306Sru va_list args; 571638Srgrimes{ 5895306Sru int ret = vasprintf (result, format, args); 591638Srgrimes if (*result == NULL || ret < 0) 60146817Sru { 61133369Sharti fputs ("gengtype: out of memory", stderr); 6253152Smarcel xexit (1); 631638Srgrimes } 641638Srgrimes return ret; 651638Srgrimes} 66146817Sru 671638Srgrimes/* Wrapper for xvasprintf. */ 6895509Sruchar * 69200178Sedxasprintf VPARAMS ((const char *format, ...)) 70200178Sed{ 7195306Sru char *result; 7215061Swosch VA_OPEN (ap, format); 731638Srgrimes VA_FIXEDARG (ap, const char *, format); 7497769Sru xvasprintf (&result, format, ap); 7596668Sru VA_CLOSE (ap); 7696668Sru return result; 7796668Sru} 7896668Sru 7996668Sru/* The one and only TYPE_STRING. */ 8096668Sru 8196668Srustruct type string_type = { 82133369Sharti TYPE_STRING, NULL, NULL, GC_USED 8396668Sru UNION_INIT_ZERO 8496668Sru}; 851638Srgrimes 861638Srgrimes/* Lists of various things. */ 871638Srgrimes 881638Srgrimesstatic pair_p typedefs; 891638Srgrimesstatic type_p structures; 901638Srgrimesstatic type_p param_structs; 911638Srgrimesstatic pair_p variables; 9299215Sru 9399215Srustatic void do_scalar_typedef PARAMS ((const char *, struct fileloc *)); 941638Srgrimesstatic type_p find_param_structure 95 PARAMS ((type_p t, type_p param[NUM_PARAM])); 96static type_p adjust_field_tree_exp PARAMS ((type_p t, options_p opt)); 97static type_p adjust_field_rtx_def PARAMS ((type_p t, options_p opt)); 98 99/* Define S as a typedef to T at POS. */ 100 101void 102do_typedef (s, t, pos) 103 const char *s; 104 type_p t; 105 struct fileloc *pos; 106{ 107 pair_p p; 108 109 for (p = typedefs; p != NULL; p = p->next) 110 if (strcmp (p->name, s) == 0) 111 { 112 if (p->type != t) 113 { 114 error_at_line (pos, "type `%s' previously defined", s); 115 error_at_line (&p->line, "previously defined here"); 116 } 117 return; 118 } 119 120 p = xmalloc (sizeof (struct pair)); 121 p->next = typedefs; 122 p->name = s; 123 p->type = t; 124 p->line = *pos; 125 typedefs = p; 126} 127 128/* Define S as a typename of a scalar. */ 129 130static void 131do_scalar_typedef (s, pos) 132 const char *s; 133 struct fileloc *pos; 134{ 135 do_typedef (s, create_scalar_type (s, strlen (s)), pos); 136} 137 138/* Return the type previously defined for S. Use POS to report errors. */ 139 140type_p 141resolve_typedef (s, pos) 142 const char *s; 143 struct fileloc *pos; 144{ 145 pair_p p; 146 for (p = typedefs; p != NULL; p = p->next) 147 if (strcmp (p->name, s) == 0) 148 return p->type; 149 error_at_line (pos, "unidentified type `%s'", s); 150 return create_scalar_type ("char", 4); 151} 152 153/* Create a new structure with tag NAME (or a union iff ISUNION is nonzero), 154 at POS with fields FIELDS and options O. */ 155 156void 157new_structure (name, isunion, pos, fields, o) 158 const char *name; 159 int isunion; 160 struct fileloc *pos; 161 pair_p fields; 162 options_p o; 163{ 164 type_p si; 165 type_p s = NULL; 166 lang_bitmap bitmap = get_base_file_bitmap (pos->file); 167 168 for (si = structures; si != NULL; si = si->next) 169 if (strcmp (name, si->u.s.tag) == 0 170 && UNION_P (si) == isunion) 171 { 172 type_p ls = NULL; 173 if (si->kind == TYPE_LANG_STRUCT) 174 { 175 ls = si; 176 177 for (si = ls->u.s.lang_struct; si != NULL; si = si->next) 178 if (si->u.s.bitmap == bitmap) 179 s = si; 180 } 181 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap) 182 { 183 ls = si; 184 si = xcalloc (1, sizeof (struct type)); 185 memcpy (si, ls, sizeof (struct type)); 186 ls->kind = TYPE_LANG_STRUCT; 187 ls->u.s.lang_struct = si; 188 ls->u.s.fields = NULL; 189 si->next = NULL; 190 si->pointer_to = NULL; 191 si->u.s.lang_struct = ls; 192 } 193 else 194 s = si; 195 196 if (ls != NULL && s == NULL) 197 { 198 s = xcalloc (1, sizeof (struct type)); 199 s->next = ls->u.s.lang_struct; 200 ls->u.s.lang_struct = s; 201 s->u.s.lang_struct = ls; 202 } 203 break; 204 } 205 206 if (s == NULL) 207 { 208 s = xcalloc (1, sizeof (struct type)); 209 s->next = structures; 210 structures = s; 211 } 212 213 if (s->u.s.line.file != NULL 214 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap))) 215 { 216 error_at_line (pos, "duplicate structure definition"); 217 error_at_line (&s->u.s.line, "previous definition here"); 218 } 219 220 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT; 221 s->u.s.tag = name; 222 s->u.s.line = *pos; 223 s->u.s.fields = fields; 224 s->u.s.opt = o; 225 s->u.s.bitmap = bitmap; 226 if (s->u.s.lang_struct) 227 s->u.s.lang_struct->u.s.bitmap |= bitmap; 228} 229 230/* Return the previously-defined structure with tag NAME (or a union 231 iff ISUNION is nonzero), or a new empty structure or union if none 232 was defined previously. */ 233 234type_p 235find_structure (name, isunion) 236 const char *name; 237 int isunion; 238{ 239 type_p s; 240 241 for (s = structures; s != NULL; s = s->next) 242 if (strcmp (name, s->u.s.tag) == 0 243 && UNION_P (s) == isunion) 244 return s; 245 246 s = xcalloc (1, sizeof (struct type)); 247 s->next = structures; 248 structures = s; 249 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT; 250 s->u.s.tag = name; 251 structures = s; 252 return s; 253} 254 255/* Return the previously-defined parameterised structure for structure 256 T and parameters PARAM, or a new parameterised empty structure or 257 union if none was defined previously. */ 258 259static type_p 260find_param_structure (t, param) 261 type_p t; 262 type_p param[NUM_PARAM]; 263{ 264 type_p res; 265 266 for (res = param_structs; res; res = res->next) 267 if (res->u.param_struct.stru == t 268 && memcmp (res->u.param_struct.param, param, 269 sizeof (type_p) * NUM_PARAM) == 0) 270 break; 271 if (res == NULL) 272 { 273 res = xcalloc (1, sizeof (*res)); 274 res->kind = TYPE_PARAM_STRUCT; 275 res->next = param_structs; 276 param_structs = res; 277 res->u.param_struct.stru = t; 278 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM); 279 } 280 return res; 281} 282 283/* Return a scalar type with name NAME. */ 284 285type_p 286create_scalar_type (name, name_len) 287 const char *name; 288 size_t name_len; 289{ 290 type_p r = xcalloc (1, sizeof (struct type)); 291 r->kind = TYPE_SCALAR; 292 r->u.sc = xmemdup (name, name_len, name_len + 1); 293 return r; 294} 295 296/* Return a pointer to T. */ 297 298type_p 299create_pointer (t) 300 type_p t; 301{ 302 if (! t->pointer_to) 303 { 304 type_p r = xcalloc (1, sizeof (struct type)); 305 r->kind = TYPE_POINTER; 306 r->u.p = t; 307 t->pointer_to = r; 308 } 309 return t->pointer_to; 310} 311 312/* Return an array of length LEN. */ 313 314type_p 315create_array (t, len) 316 type_p t; 317 const char *len; 318{ 319 type_p v; 320 321 v = xcalloc (1, sizeof (*v)); 322 v->kind = TYPE_ARRAY; 323 v->u.a.p = t; 324 v->u.a.len = len; 325 return v; 326} 327 328/* Add a variable named S of type T with options O defined at POS, 329 to `variables'. */ 330 331void 332note_variable (s, t, o, pos) 333 const char *s; 334 type_p t; 335 options_p o; 336 struct fileloc *pos; 337{ 338 pair_p n; 339 n = xmalloc (sizeof (*n)); 340 n->name = s; 341 n->type = t; 342 n->line = *pos; 343 n->opt = o; 344 n->next = variables; 345 variables = n; 346} 347 348enum rtx_code { 349#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM , 350#include "rtl.def" 351#undef DEF_RTL_EXPR 352 NUM_RTX_CODE 353}; 354 355/* We really don't care how long a CONST_DOUBLE is. */ 356#define CONST_DOUBLE_FORMAT "ww" 357static const char * const rtx_format[NUM_RTX_CODE] = { 358#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT , 359#include "rtl.def" 360#undef DEF_RTL_EXPR 361}; 362 363static int rtx_next[NUM_RTX_CODE]; 364 365/* Generate the contents of the rtx_next array. This really doesn't belong 366 in gengtype at all, but it's needed for adjust_field_rtx_def. */ 367 368static void 369gen_rtx_next () 370{ 371 int i; 372 for (i = 0; i < NUM_RTX_CODE; i++) 373 { 374 int k; 375 376 rtx_next[i] = -1; 377 if (strncmp (rtx_format[i], "iuu", 3) == 0) 378 rtx_next[i] = 2; 379 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST) 380 rtx_next[i] = 1; 381 else 382 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--) 383 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u') 384 rtx_next[i] = k; 385 } 386} 387 388/* Write out the contents of the rtx_next array. */ 389static void 390write_rtx_next () 391{ 392 outf_p f = get_output_file_with_visibility (NULL); 393 int i; 394 395 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n"); 396 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n"); 397 for (i = 0; i < NUM_RTX_CODE; i++) 398 if (rtx_next[i] == -1) 399 oprintf (f, " 0,\n"); 400 else 401 oprintf (f, 402 " offsetof (struct rtx_def, fld) + %d * sizeof (rtunion),\n", 403 rtx_next[i]); 404 oprintf (f, "};\n"); 405} 406 407/* Handle `special("rtx_def")'. This is a special case for field 408 `fld' of struct rtx_def, which is an array of unions whose values 409 are based in a complex way on the type of RTL. */ 410 411static type_p 412adjust_field_rtx_def (t, opt) 413 type_p t; 414 options_p opt ATTRIBUTE_UNUSED; 415{ 416 pair_p flds = NULL; 417 options_p nodot; 418 int i; 419 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp; 420 type_p bitmap_tp, basic_block_tp; 421 422 static const char * const rtx_name[NUM_RTX_CODE] = { 423#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME , 424#include "rtl.def" 425#undef DEF_RTL_EXPR 426 }; 427 428 if (t->kind != TYPE_ARRAY) 429 { 430 error_at_line (&lexer_line, 431 "special `rtx_def' must be applied to an array"); 432 return &string_type; 433 } 434 435 nodot = xmalloc (sizeof (*nodot)); 436 nodot->next = NULL; 437 nodot->name = "dot"; 438 nodot->info = ""; 439 440 rtx_tp = create_pointer (find_structure ("rtx_def", 0)); 441 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0)); 442 tree_tp = create_pointer (find_structure ("tree_node", 1)); 443 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0)); 444 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0)); 445 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0)); 446 scalar_tp = create_scalar_type ("rtunion scalar", 14); 447 448 { 449 pair_p note_flds = NULL; 450 int c; 451 452 for (c = 0; c < 3; c++) 453 { 454 pair_p old_note_flds = note_flds; 455 456 note_flds = xmalloc (sizeof (*note_flds)); 457 note_flds->line.file = __FILE__; 458 note_flds->line.line = __LINE__; 459 note_flds->name = "rttree"; 460 note_flds->type = tree_tp; 461 note_flds->opt = xmalloc (sizeof (*note_flds->opt)); 462 note_flds->opt->next = nodot; 463 note_flds->opt->name = "tag"; 464 note_flds->next = old_note_flds; 465 } 466 467 note_flds->type = rtx_tp; 468 note_flds->name = "rtx"; 469 note_flds->opt->info = "NOTE_INSN_EXPECTED_VALUE"; 470 note_flds->next->opt->info = "NOTE_INSN_BLOCK_BEG"; 471 note_flds->next->next->opt->info = "NOTE_INSN_BLOCK_END"; 472 473 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL); 474 } 475 476 note_union_tp = find_structure ("rtx_def_note_subunion", 1); 477 478 for (i = 0; i < NUM_RTX_CODE; i++) 479 { 480 pair_p old_flds = flds; 481 pair_p subfields = NULL; 482 size_t aindex, nmindex; 483 const char *sname; 484 char *ftag; 485 486 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++) 487 { 488 pair_p old_subf = subfields; 489 type_p t; 490 const char *subname; 491 492 switch (rtx_format[i][aindex]) 493 { 494 case '*': 495 case 'i': 496 case 'n': 497 case 'w': 498 t = scalar_tp; 499 subname = "rtint"; 500 break; 501 502 case '0': 503 if (i == MEM && aindex == 1) 504 t = mem_attrs_tp, subname = "rtmem"; 505 else if (i == JUMP_INSN && aindex == 9) 506 t = rtx_tp, subname = "rtx"; 507 else if (i == CODE_LABEL && aindex == 4) 508 t = scalar_tp, subname = "rtint"; 509 else if (i == CODE_LABEL && aindex == 5) 510 t = rtx_tp, subname = "rtx"; 511 else if (i == LABEL_REF 512 && (aindex == 1 || aindex == 2)) 513 t = rtx_tp, subname = "rtx"; 514 else if (i == NOTE && aindex == 4) 515 t = note_union_tp, subname = ""; 516 else if (i == NOTE && aindex >= 7) 517 t = scalar_tp, subname = "rtint"; 518 else if (i == ADDR_DIFF_VEC && aindex == 4) 519 t = scalar_tp, subname = "rtint"; 520 else if (i == VALUE && aindex == 0) 521 t = scalar_tp, subname = "rtint"; 522 else if (i == REG && aindex == 1) 523 t = scalar_tp, subname = "rtint"; 524 else if (i == SCRATCH && aindex == 0) 525 t = scalar_tp, subname = "rtint"; 526 else if (i == BARRIER && aindex >= 3) 527 t = scalar_tp, subname = "rtint"; 528 else 529 { 530 error_at_line (&lexer_line, 531 "rtx type `%s' has `0' in position %lu, can't handle", 532 rtx_name[i], (unsigned long) aindex); 533 t = &string_type; 534 subname = "rtint"; 535 } 536 break; 537 538 case 's': 539 case 'S': 540 case 'T': 541 t = &string_type; 542 subname = "rtstr"; 543 break; 544 545 case 'e': 546 case 'u': 547 t = rtx_tp; 548 subname = "rtx"; 549 break; 550 551 case 'E': 552 case 'V': 553 t = rtvec_tp; 554 subname = "rtvec"; 555 break; 556 557 case 't': 558 t = tree_tp; 559 subname = "rttree"; 560 break; 561 562 case 'b': 563 t = bitmap_tp; 564 subname = "rtbit"; 565 break; 566 567 case 'B': 568 t = basic_block_tp; 569 subname = "bb"; 570 break; 571 572 default: 573 error_at_line (&lexer_line, 574 "rtx type `%s' has `%c' in position %lu, can't handle", 575 rtx_name[i], rtx_format[i][aindex], 576 (unsigned long)aindex); 577 t = &string_type; 578 subname = "rtint"; 579 break; 580 } 581 582 subfields = xmalloc (sizeof (*subfields)); 583 subfields->next = old_subf; 584 subfields->type = t; 585 subfields->name = xasprintf ("[%lu].%s", (unsigned long)aindex, 586 subname); 587 subfields->line.file = __FILE__; 588 subfields->line.line = __LINE__; 589 if (t == note_union_tp) 590 { 591 subfields->opt = xmalloc (sizeof (*subfields->opt)); 592 subfields->opt->next = nodot; 593 subfields->opt->name = "desc"; 594 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)"; 595 } 596 else if (t == basic_block_tp) 597 { 598 /* We don't presently GC basic block structures... */ 599 subfields->opt = xmalloc (sizeof (*subfields->opt)); 600 subfields->opt->next = nodot; 601 subfields->opt->name = "skip"; 602 subfields->opt->info = NULL; 603 } 604 else if ((size_t) rtx_next[i] == aindex) 605 { 606 /* The 'next' field will be marked by the chain_next option. */ 607 subfields->opt = xmalloc (sizeof (*subfields->opt)); 608 subfields->opt->next = nodot; 609 subfields->opt->name = "skip"; 610 subfields->opt->info = NULL; 611 } 612 else 613 subfields->opt = nodot; 614 } 615 616 flds = xmalloc (sizeof (*flds)); 617 flds->next = old_flds; 618 flds->name = ""; 619 sname = xasprintf ("rtx_def_%s", rtx_name[i]); 620 new_structure (sname, 0, &lexer_line, subfields, NULL); 621 flds->type = find_structure (sname, 0); 622 flds->line.file = __FILE__; 623 flds->line.line = __LINE__; 624 flds->opt = xmalloc (sizeof (*flds->opt)); 625 flds->opt->next = nodot; 626 flds->opt->name = "tag"; 627 ftag = xstrdup (rtx_name[i]); 628 for (nmindex = 0; nmindex < strlen (ftag); nmindex++) 629 ftag[nmindex] = TOUPPER (ftag[nmindex]); 630 flds->opt->info = ftag; 631 } 632 633 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot); 634 return find_structure ("rtx_def_subunion", 1); 635} 636 637/* Handle `special("tree_exp")'. This is a special case for 638 field `operands' of struct tree_exp, which although it claims to contain 639 pointers to trees, actually sometimes contains pointers to RTL too. 640 Passed T, the old type of the field, and OPT its options. Returns 641 a new type for the field. */ 642 643static type_p 644adjust_field_tree_exp (t, opt) 645 type_p t; 646 options_p opt ATTRIBUTE_UNUSED; 647{ 648 pair_p flds; 649 options_p nodot; 650 size_t i; 651 static const struct { 652 const char *name; 653 int first_rtl; 654 int num_rtl; 655 } data[] = { 656 { "SAVE_EXPR", 2, 1 }, 657 { "GOTO_SUBROUTINE_EXPR", 0, 2 }, 658 { "RTL_EXPR", 0, 2 }, 659 { "WITH_CLEANUP_EXPR", 2, 1 }, 660 { "METHOD_CALL_EXPR", 3, 1 } 661 }; 662 663 if (t->kind != TYPE_ARRAY) 664 { 665 error_at_line (&lexer_line, 666 "special `tree_exp' must be applied to an array"); 667 return &string_type; 668 } 669 670 nodot = xmalloc (sizeof (*nodot)); 671 nodot->next = NULL; 672 nodot->name = "dot"; 673 nodot->info = ""; 674 675 flds = xmalloc (sizeof (*flds)); 676 flds->next = NULL; 677 flds->name = ""; 678 flds->type = t; 679 flds->line.file = __FILE__; 680 flds->line.line = __LINE__; 681 flds->opt = xmalloc (sizeof (*flds->opt)); 682 flds->opt->next = nodot; 683 flds->opt->name = "length"; 684 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))"; 685 { 686 options_p oldopt = flds->opt; 687 flds->opt = xmalloc (sizeof (*flds->opt)); 688 flds->opt->next = oldopt; 689 flds->opt->name = "default"; 690 flds->opt->info = ""; 691 } 692 693 for (i = 0; i < ARRAY_SIZE (data); i++) 694 { 695 pair_p old_flds = flds; 696 pair_p subfields = NULL; 697 int r_index; 698 const char *sname; 699 700 for (r_index = 0; 701 r_index < data[i].first_rtl + data[i].num_rtl; 702 r_index++) 703 { 704 pair_p old_subf = subfields; 705 subfields = xmalloc (sizeof (*subfields)); 706 subfields->next = old_subf; 707 subfields->name = xasprintf ("[%d]", r_index); 708 if (r_index < data[i].first_rtl) 709 subfields->type = t->u.a.p; 710 else 711 subfields->type = create_pointer (find_structure ("rtx_def", 0)); 712 subfields->line.file = __FILE__; 713 subfields->line.line = __LINE__; 714 subfields->opt = nodot; 715 } 716 717 flds = xmalloc (sizeof (*flds)); 718 flds->next = old_flds; 719 flds->name = ""; 720 sname = xasprintf ("tree_exp_%s", data[i].name); 721 new_structure (sname, 0, &lexer_line, subfields, NULL); 722 flds->type = find_structure (sname, 0); 723 flds->line.file = __FILE__; 724 flds->line.line = __LINE__; 725 flds->opt = xmalloc (sizeof (*flds->opt)); 726 flds->opt->next = nodot; 727 flds->opt->name = "tag"; 728 flds->opt->info = data[i].name; 729 } 730 731 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot); 732 return find_structure ("tree_exp_subunion", 1); 733} 734 735/* Perform any special processing on a type T, about to become the type 736 of a field. Return the appropriate type for the field. 737 At present: 738 - Converts pointer-to-char, with no length parameter, to TYPE_STRING; 739 - Similarly for arrays of pointer-to-char; 740 - Converts structures for which a parameter is provided to 741 TYPE_PARAM_STRUCT; 742 - Handles "special" options. 743*/ 744 745type_p 746adjust_field_type (t, opt) 747 type_p t; 748 options_p opt; 749{ 750 int length_p = 0; 751 const int pointer_p = t->kind == TYPE_POINTER; 752 type_p params[NUM_PARAM]; 753 int params_p = 0; 754 int i; 755 756 for (i = 0; i < NUM_PARAM; i++) 757 params[i] = NULL; 758 759 for (; opt; opt = opt->next) 760 if (strcmp (opt->name, "length") == 0) 761 length_p = 1; 762 else if (strcmp (opt->name, "param_is") == 0 763 || (strncmp (opt->name, "param", 5) == 0 764 && ISDIGIT (opt->name[5]) 765 && strcmp (opt->name + 6, "_is") == 0)) 766 { 767 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0; 768 769 if (! UNION_OR_STRUCT_P (t) 770 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p))) 771 { 772 error_at_line (&lexer_line, 773 "option `%s' may only be applied to structures or structure pointers", 774 opt->name); 775 return t; 776 } 777 778 params_p = 1; 779 if (params[num] != NULL) 780 error_at_line (&lexer_line, "duplicate `%s' option", opt->name); 781 if (! ISDIGIT (opt->name[5])) 782 params[num] = create_pointer ((type_p) opt->info); 783 else 784 params[num] = (type_p) opt->info; 785 } 786 else if (strcmp (opt->name, "special") == 0) 787 { 788 const char *special_name = (const char *)opt->info; 789 if (strcmp (special_name, "tree_exp") == 0) 790 t = adjust_field_tree_exp (t, opt); 791 else if (strcmp (special_name, "rtx_def") == 0) 792 t = adjust_field_rtx_def (t, opt); 793 else 794 error_at_line (&lexer_line, "unknown special `%s'", special_name); 795 } 796 797 if (params_p) 798 { 799 type_p realt; 800 801 if (pointer_p) 802 t = t->u.p; 803 realt = find_param_structure (t, params); 804 t = pointer_p ? create_pointer (realt) : realt; 805 } 806 807 if (! length_p 808 && pointer_p 809 && t->u.p->kind == TYPE_SCALAR 810 && (strcmp (t->u.p->u.sc, "char") == 0 811 || strcmp (t->u.p->u.sc, "unsigned char") == 0)) 812 return &string_type; 813 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER 814 && t->u.a.p->u.p->kind == TYPE_SCALAR 815 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0 816 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0)) 817 return create_array (&string_type, t->u.a.len); 818 819 return t; 820} 821 822/* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS 823 and information about the correspondance between token types and fields 824 in TYPEINFO. POS is used for error messages. */ 825 826void 827note_yacc_type (o, fields, typeinfo, pos) 828 options_p o; 829 pair_p fields; 830 pair_p typeinfo; 831 struct fileloc *pos; 832{ 833 pair_p p; 834 pair_p *p_p; 835 836 for (p = typeinfo; p; p = p->next) 837 { 838 pair_p m; 839 840 if (p->name == NULL) 841 continue; 842 843 if (p->type == (type_p) 1) 844 { 845 pair_p pp; 846 int ok = 0; 847 848 for (pp = typeinfo; pp; pp = pp->next) 849 if (pp->type != (type_p) 1 850 && strcmp (pp->opt->info, p->opt->info) == 0) 851 { 852 ok = 1; 853 break; 854 } 855 if (! ok) 856 continue; 857 } 858 859 for (m = fields; m; m = m->next) 860 if (strcmp (m->name, p->name) == 0) 861 p->type = m->type; 862 if (p->type == NULL) 863 { 864 error_at_line (&p->line, 865 "couldn't match fieldname `%s'", p->name); 866 p->name = NULL; 867 } 868 } 869 870 p_p = &typeinfo; 871 while (*p_p) 872 { 873 pair_p p = *p_p; 874 875 if (p->name == NULL 876 || p->type == (type_p) 1) 877 *p_p = p->next; 878 else 879 p_p = &p->next; 880 } 881 882 new_structure ("yy_union", 1, pos, typeinfo, o); 883 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos); 884} 885 886static void process_gc_options PARAMS ((options_p, enum gc_used_enum, 887 int *, int *, int *)); 888static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum, type_p *)); 889static void set_gc_used PARAMS ((pair_p)); 890 891/* Handle OPT for set_gc_used_type. */ 892 893static void 894process_gc_options (opt, level, maybe_undef, pass_param, length) 895 options_p opt; 896 enum gc_used_enum level; 897 int *maybe_undef; 898 int *pass_param; 899 int *length; 900{ 901 options_p o; 902 for (o = opt; o; o = o->next) 903 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO) 904 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL); 905 else if (strcmp (o->name, "maybe_undef") == 0) 906 *maybe_undef = 1; 907 else if (strcmp (o->name, "use_params") == 0) 908 *pass_param = 1; 909 else if (strcmp (o->name, "length") == 0) 910 *length = 1; 911} 912 913/* Set the gc_used field of T to LEVEL, and handle the types it references. */ 914 915static void 916set_gc_used_type (t, level, param) 917 type_p t; 918 enum gc_used_enum level; 919 type_p param[NUM_PARAM]; 920{ 921 if (t->gc_used >= level) 922 return; 923 924 t->gc_used = level; 925 926 switch (t->kind) 927 { 928 case TYPE_STRUCT: 929 case TYPE_UNION: 930 { 931 pair_p f; 932 int dummy; 933 934 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy); 935 936 for (f = t->u.s.fields; f; f = f->next) 937 { 938 int maybe_undef = 0; 939 int pass_param = 0; 940 int length = 0; 941 process_gc_options (f->opt, level, &maybe_undef, &pass_param, 942 &length); 943 944 if (length && f->type->kind == TYPE_POINTER) 945 set_gc_used_type (f->type->u.p, GC_USED, NULL); 946 else if (maybe_undef && f->type->kind == TYPE_POINTER) 947 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL); 948 else if (pass_param && f->type->kind == TYPE_POINTER && param) 949 set_gc_used_type (find_param_structure (f->type->u.p, param), 950 GC_POINTED_TO, NULL); 951 else 952 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL); 953 } 954 break; 955 } 956 957 case TYPE_POINTER: 958 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL); 959 break; 960 961 case TYPE_ARRAY: 962 set_gc_used_type (t->u.a.p, GC_USED, param); 963 break; 964 965 case TYPE_LANG_STRUCT: 966 for (t = t->u.s.lang_struct; t; t = t->next) 967 set_gc_used_type (t, level, param); 968 break; 969 970 case TYPE_PARAM_STRUCT: 971 { 972 int i; 973 for (i = 0; i < NUM_PARAM; i++) 974 if (t->u.param_struct.param[i] != 0) 975 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL); 976 } 977 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO) 978 level = GC_POINTED_TO; 979 else 980 level = GC_USED; 981 t->u.param_struct.stru->gc_used = GC_UNUSED; 982 set_gc_used_type (t->u.param_struct.stru, level, 983 t->u.param_struct.param); 984 break; 985 986 default: 987 break; 988 } 989} 990 991/* Set the gc_used fields of all the types pointed to by VARIABLES. */ 992 993static void 994set_gc_used (variables) 995 pair_p variables; 996{ 997 pair_p p; 998 for (p = variables; p; p = p->next) 999 set_gc_used_type (p->type, GC_USED, NULL); 1000} 1001 1002/* File mapping routines. For each input file, there is one output .c file 1003 (but some output files have many input files), and there is one .h file 1004 for the whole build. */ 1005 1006/* The list of output files. */ 1007static outf_p output_files; 1008 1009/* The output header file that is included into pretty much every 1010 source file. */ 1011outf_p header_file; 1012 1013/* Number of files specified in gtfiles. */ 1014#define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1) 1015 1016/* Number of files in the language files array. */ 1017#define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1) 1018 1019/* Length of srcdir name. */ 1020static int srcdir_len = 0; 1021 1022#define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1) 1023outf_p base_files[NUM_BASE_FILES]; 1024 1025static outf_p create_file PARAMS ((const char *, const char *)); 1026static const char * get_file_basename PARAMS ((const char *)); 1027 1028/* Create and return an outf_p for a new file for NAME, to be called 1029 ONAME. */ 1030 1031static outf_p 1032create_file (name, oname) 1033 const char *name; 1034 const char *oname; 1035{ 1036 static const char *const hdr[] = { 1037 " Copyright (C) 2002 Free Software Foundation, Inc.\n", 1038 "\n", 1039 "This file is part of GCC.\n", 1040 "\n", 1041 "GCC is free software; you can redistribute it and/or modify it under\n", 1042 "the terms of the GNU General Public License as published by the Free\n", 1043 "Software Foundation; either version 2, or (at your option) any later\n", 1044 "version.\n", 1045 "\n", 1046 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n", 1047 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n", 1048 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n", 1049 "for more details.\n", 1050 "\n", 1051 "You should have received a copy of the GNU General Public License\n", 1052 "along with GCC; see the file COPYING. If not, write to the Free\n", 1053 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n", 1054 "02111-1307, USA. */\n", 1055 "\n", 1056 "/* This file is machine generated. Do not edit. */\n" 1057 }; 1058 outf_p f; 1059 size_t i; 1060 1061 f = xcalloc (sizeof (*f), 1); 1062 f->next = output_files; 1063 f->name = oname; 1064 output_files = f; 1065 1066 oprintf (f, "/* Type information for %s.\n", name); 1067 for (i = 0; i < ARRAY_SIZE (hdr); i++) 1068 oprintf (f, "%s", hdr[i]); 1069 return f; 1070} 1071 1072/* Print, like fprintf, to O. */ 1073void 1074oprintf VPARAMS ((outf_p o, const char *format, ...)) 1075{ 1076 char *s; 1077 size_t slength; 1078 1079 VA_OPEN (ap, format); 1080 VA_FIXEDARG (ap, outf_p, o); 1081 VA_FIXEDARG (ap, const char *, format); 1082 slength = xvasprintf (&s, format, ap); 1083 1084 if (o->bufused + slength > o->buflength) 1085 { 1086 size_t new_len = o->buflength; 1087 if (new_len == 0) 1088 new_len = 1024; 1089 do { 1090 new_len *= 2; 1091 } while (o->bufused + slength >= new_len); 1092 o->buf = xrealloc (o->buf, new_len); 1093 o->buflength = new_len; 1094 } 1095 memcpy (o->buf + o->bufused, s, slength); 1096 o->bufused += slength; 1097 free (s); 1098 VA_CLOSE (ap); 1099} 1100 1101/* Open the global header file and the language-specific header files. */ 1102 1103static void 1104open_base_files () 1105{ 1106 size_t i; 1107 1108 header_file = create_file ("GCC", "gtype-desc.h"); 1109 1110 for (i = 0; i < NUM_BASE_FILES; i++) 1111 base_files[i] = create_file (lang_dir_names[i], 1112 xasprintf ("gtype-%s.h", lang_dir_names[i])); 1113 1114 /* gtype-desc.c is a little special, so we create it here. */ 1115 { 1116 /* The order of files here matters very much. */ 1117 static const char *const ifiles [] = { 1118 "config.h", "system.h", "varray.h", "hashtab.h", "splay-tree.h", 1119 "bitmap.h", "tree.h", "rtl.h", "function.h", "insn-config.h", 1120 "expr.h", "hard-reg-set.h", "basic-block.h", "cselib.h", 1121 "insn-addr.h", "ssa.h", "optabs.h", "libfuncs.h", 1122 "debug.h", "ggc.h", 1123 NULL 1124 }; 1125 const char *const *ifp; 1126 outf_p gtype_desc_c; 1127 1128 gtype_desc_c = create_file ("GCC", "gtype-desc.c"); 1129 for (ifp = ifiles; *ifp; ifp++) 1130 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp); 1131 } 1132} 1133 1134/* Determine the pathname to F relative to $(srcdir). */ 1135 1136static const char * 1137get_file_basename (f) 1138 const char *f; 1139{ 1140 size_t len; 1141 const char *basename; 1142 unsigned i; 1143 1144 basename = strrchr (f, '/'); 1145 1146 if (!basename) 1147 return f; 1148 1149 len = strlen (f); 1150 basename++; 1151 1152 for (i = 1; i < NUM_BASE_FILES; i++) 1153 { 1154 const char * s1; 1155 const char * s2; 1156 int l1; 1157 int l2; 1158 s1 = basename - strlen (lang_dir_names [i]) - 1; 1159 s2 = lang_dir_names [i]; 1160 l1 = strlen (s1); 1161 l2 = strlen (s2); 1162 if (l1 >= l2 && !memcmp (s1, s2, l2)) 1163 { 1164 basename -= l2 + 1; 1165 if ((basename - f - 1) != srcdir_len) 1166 abort (); /* Match is wrong - should be preceded by $srcdir. */ 1167 break; 1168 } 1169 } 1170 1171 return basename; 1172} 1173 1174/* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff 1175 INPUT_FILE is used by <lang>. 1176 1177 This function should be written to assume that a file _is_ used 1178 if the situation is unclear. If it wrongly assumes a file _is_ used, 1179 a linker error will result. If it wrongly assumes a file _is not_ used, 1180 some GC roots may be missed, which is a much harder-to-debug problem. */ 1181 1182unsigned 1183get_base_file_bitmap (input_file) 1184 const char *input_file; 1185{ 1186 const char *basename = get_file_basename (input_file); 1187 const char *slashpos = strchr (basename, '/'); 1188 unsigned j; 1189 unsigned k; 1190 unsigned bitmap; 1191 1192 if (slashpos) 1193 { 1194 size_t i; 1195 for (i = 1; i < NUM_BASE_FILES; i++) 1196 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i]) 1197 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0) 1198 { 1199 /* It's in a language directory, set that language. */ 1200 bitmap = 1 << i; 1201 return bitmap; 1202 } 1203 1204 abort (); /* Should have found the language. */ 1205 } 1206 1207 /* If it's in any config-lang.in, then set for the languages 1208 specified. */ 1209 1210 bitmap = 0; 1211 1212 for (j = 0; j < NUM_LANG_FILES; j++) 1213 { 1214 if (!strcmp(input_file, lang_files[j])) 1215 { 1216 for (k = 0; k < NUM_BASE_FILES; k++) 1217 { 1218 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j])) 1219 bitmap |= (1 << k); 1220 } 1221 } 1222 } 1223 1224 /* Otherwise, set all languages. */ 1225 if (!bitmap) 1226 bitmap = (1 << NUM_BASE_FILES) - 1; 1227 1228 return bitmap; 1229} 1230 1231/* An output file, suitable for definitions, that can see declarations 1232 made in INPUT_FILE and is linked into every language that uses 1233 INPUT_FILE. */ 1234 1235outf_p 1236get_output_file_with_visibility (input_file) 1237 const char *input_file; 1238{ 1239 outf_p r; 1240 size_t len; 1241 const char *basename; 1242 const char *for_name; 1243 const char *output_name; 1244 1245 /* This can happen when we need a file with visibility on a 1246 structure that we've never seen. We have to just hope that it's 1247 globally visible. */ 1248 if (input_file == NULL) 1249 input_file = "system.h"; 1250 1251 /* Determine the output file name. */ 1252 basename = get_file_basename (input_file); 1253 1254 len = strlen (basename); 1255 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0) 1256 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0) 1257 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0)) 1258 { 1259 char *s; 1260 1261 output_name = s = xasprintf ("gt-%s", basename); 1262 for (; *s != '.'; s++) 1263 if (! ISALNUM (*s) && *s != '-') 1264 *s = '-'; 1265 memcpy (s, ".h", sizeof (".h")); 1266 for_name = basename; 1267 } 1268 else if (strcmp (basename, "c-common.h") == 0) 1269 output_name = "gt-c-common.h", for_name = "c-common.c"; 1270 else if (strcmp (basename, "c-tree.h") == 0) 1271 output_name = "gt-c-decl.h", for_name = "c-decl.c"; 1272 else 1273 { 1274 size_t i; 1275 1276 for (i = 0; i < NUM_BASE_FILES; i++) 1277 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0 1278 && basename[strlen(lang_dir_names[i])] == '/') 1279 return base_files[i]; 1280 1281 output_name = "gtype-desc.c"; 1282 for_name = NULL; 1283 } 1284 1285 /* Look through to see if we've ever seen this output filename before. */ 1286 for (r = output_files; r; r = r->next) 1287 if (strcmp (r->name, output_name) == 0) 1288 return r; 1289 1290 /* If not, create it. */ 1291 r = create_file (for_name, output_name); 1292 1293 return r; 1294} 1295 1296/* The name of an output file, suitable for definitions, that can see 1297 declarations made in INPUT_FILE and is linked into every language 1298 that uses INPUT_FILE. */ 1299 1300const char * 1301get_output_file_name (input_file) 1302 const char *input_file; 1303{ 1304 return get_output_file_with_visibility (input_file)->name; 1305} 1306 1307/* Copy the output to its final destination, 1308 but don't unnecessarily change modification times. */ 1309 1310static void close_output_files PARAMS ((void)); 1311 1312static void 1313close_output_files () 1314{ 1315 outf_p of; 1316 1317 for (of = output_files; of; of = of->next) 1318 { 1319 FILE * newfile; 1320 1321 newfile = fopen (of->name, "r"); 1322 if (newfile != NULL ) 1323 { 1324 int no_write_p; 1325 size_t i; 1326 1327 for (i = 0; i < of->bufused; i++) 1328 { 1329 int ch; 1330 ch = fgetc (newfile); 1331 if (ch == EOF || ch != (unsigned char) of->buf[i]) 1332 break; 1333 } 1334 no_write_p = i == of->bufused && fgetc (newfile) == EOF; 1335 fclose (newfile); 1336 1337 if (no_write_p) 1338 continue; 1339 } 1340 1341 newfile = fopen (of->name, "w"); 1342 if (newfile == NULL) 1343 { 1344 perror ("opening output file"); 1345 exit (1); 1346 } 1347 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused) 1348 { 1349 perror ("writing output file"); 1350 exit (1); 1351 } 1352 if (fclose (newfile) != 0) 1353 { 1354 perror ("closing output file"); 1355 exit (1); 1356 } 1357 } 1358} 1359 1360struct flist { 1361 struct flist *next; 1362 int started_p; 1363 const char *name; 1364 outf_p f; 1365}; 1366 1367static void output_escaped_param PARAMS ((outf_p , const char *, const char *, 1368 const char *, const char *, 1369 struct fileloc *)); 1370static void output_mangled_typename PARAMS ((outf_p, type_p)); 1371static void write_gc_structure_fields 1372 PARAMS ((outf_p , type_p, const char *, const char *, options_p, 1373 int, struct fileloc *, lang_bitmap, type_p *)); 1374static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p, 1375 type_p *)); 1376static void write_gc_types PARAMS ((type_p structures, type_p param_structs)); 1377static void write_enum_defn PARAMS ((type_p structures, type_p param_structs)); 1378static void put_mangled_filename PARAMS ((outf_p , const char *)); 1379static void finish_root_table PARAMS ((struct flist *flp, const char *pfx, 1380 const char *tname, const char *lastname, 1381 const char *name)); 1382static void write_gc_root PARAMS ((outf_p , pair_p, type_p, const char *, int, 1383 struct fileloc *, const char *)); 1384static void write_gc_roots PARAMS ((pair_p)); 1385 1386static int gc_counter; 1387 1388/* Print PARAM to OF processing escapes. VAL references the current object, 1389 PREV_VAL the object containing the current object, ONAME is the name 1390 of the option and LINE is used to print error messages. */ 1391 1392static void 1393output_escaped_param (of, param, val, prev_val, oname, line) 1394 outf_p of; 1395 const char *param; 1396 const char *val; 1397 const char *prev_val; 1398 const char *oname; 1399 struct fileloc *line; 1400{ 1401 const char *p; 1402 1403 for (p = param; *p; p++) 1404 if (*p != '%') 1405 oprintf (of, "%c", *p); 1406 else switch (*++p) 1407 { 1408 case 'h': 1409 oprintf (of, "(%s)", val); 1410 break; 1411 case '0': 1412 oprintf (of, "(*x)"); 1413 break; 1414 case '1': 1415 oprintf (of, "(%s)", prev_val); 1416 break; 1417 case 'a': 1418 { 1419 const char *pp = val + strlen (val); 1420 while (pp[-1] == ']') 1421 while (*pp != '[') 1422 pp--; 1423 oprintf (of, "%s", pp); 1424 } 1425 break; 1426 default: 1427 error_at_line (line, "`%s' option contains bad escape %c%c", 1428 oname, '%', *p); 1429 } 1430} 1431 1432/* Print a mangled name representing T to OF. */ 1433 1434static void 1435output_mangled_typename (of, t) 1436 outf_p of; 1437 type_p t; 1438{ 1439 if (t == NULL) 1440 oprintf (of, "Z"); 1441 else switch (t->kind) 1442 { 1443 case TYPE_POINTER: 1444 oprintf (of, "P"); 1445 output_mangled_typename (of, t->u.p); 1446 break; 1447 case TYPE_SCALAR: 1448 oprintf (of, "I"); 1449 break; 1450 case TYPE_STRING: 1451 oprintf (of, "S"); 1452 break; 1453 case TYPE_STRUCT: 1454 case TYPE_UNION: 1455 case TYPE_LANG_STRUCT: 1456 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag); 1457 break; 1458 case TYPE_PARAM_STRUCT: 1459 { 1460 int i; 1461 for (i = 0; i < NUM_PARAM; i++) 1462 if (t->u.param_struct.param[i] != NULL) 1463 output_mangled_typename (of, t->u.param_struct.param[i]); 1464 output_mangled_typename (of, t->u.param_struct.stru); 1465 } 1466 break; 1467 case TYPE_ARRAY: 1468 abort (); 1469 } 1470} 1471 1472/* Write out code to OF which marks the fields of S. VAL references 1473 the current object, PREV_VAL the object containing the current 1474 object, OPTS is a list of options to apply, INDENT is the current 1475 indentation level, LINE is used to print error messages, BITMAP 1476 indicates which languages to print the structure for, and PARAM is 1477 the current parameter (from an enclosing param_is option). */ 1478 1479static void 1480write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap, 1481 param) 1482 outf_p of; 1483 type_p s; 1484 const char *val; 1485 const char *prev_val; 1486 options_p opts; 1487 int indent; 1488 struct fileloc *line; 1489 lang_bitmap bitmap; 1490 type_p * param; 1491{ 1492 pair_p f; 1493 int seen_default = 0; 1494 1495 if (! s->u.s.line.file) 1496 error_at_line (line, "incomplete structure `%s'", s->u.s.tag); 1497 else if ((s->u.s.bitmap & bitmap) != bitmap) 1498 { 1499 error_at_line (line, "structure defined for mismatching languages"); 1500 error_at_line (&s->u.s.line, "one structure defined here"); 1501 } 1502 1503 if (s->kind == TYPE_UNION) 1504 { 1505 const char *tagexpr = NULL; 1506 options_p oo; 1507 1508 for (oo = opts; oo; oo = oo->next) 1509 if (strcmp (oo->name, "desc") == 0) 1510 tagexpr = (const char *)oo->info; 1511 if (tagexpr == NULL) 1512 { 1513 tagexpr = "1"; 1514 error_at_line (line, "missing `desc' option"); 1515 } 1516 1517 oprintf (of, "%*sswitch (", indent, ""); 1518 output_escaped_param (of, tagexpr, val, prev_val, "desc", line); 1519 oprintf (of, ")\n"); 1520 indent += 2; 1521 oprintf (of, "%*s{\n", indent, ""); 1522 } 1523 1524 for (f = s->u.s.fields; f; f = f->next) 1525 { 1526 const char *tagid = NULL; 1527 const char *length = NULL; 1528 int skip_p = 0; 1529 int default_p = 0; 1530 int maybe_undef_p = 0; 1531 int use_param_num = -1; 1532 int use_params_p = 0; 1533 int needs_cast_p = 0; 1534 options_p oo; 1535 type_p t = f->type; 1536 const char *dot = "."; 1537 1538 for (oo = f->opt; oo; oo = oo->next) 1539 if (strcmp (oo->name, "length") == 0) 1540 length = (const char *)oo->info; 1541 else if (strcmp (oo->name, "maybe_undef") == 0) 1542 maybe_undef_p = 1; 1543 else if (strcmp (oo->name, "tag") == 0) 1544 tagid = (const char *)oo->info; 1545 else if (strcmp (oo->name, "special") == 0) 1546 ; 1547 else if (strcmp (oo->name, "skip") == 0) 1548 skip_p = 1; 1549 else if (strcmp (oo->name, "default") == 0) 1550 default_p = 1; 1551 else if (strcmp (oo->name, "desc") == 0) 1552 ; 1553 else if (strcmp (oo->name, "descbits") == 0) 1554 ; 1555 else if (strcmp (oo->name, "param_is") == 0) 1556 ; 1557 else if (strncmp (oo->name, "use_param", 9) == 0 1558 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9]))) 1559 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0'; 1560 else if (strcmp (oo->name, "use_params") == 0) 1561 use_params_p = 1; 1562 else if (strcmp (oo->name, "dot") == 0) 1563 dot = (const char *)oo->info; 1564 else 1565 error_at_line (&f->line, "unknown field option `%s'\n", oo->name); 1566 1567 if (skip_p) 1568 continue; 1569 1570 if (use_params_p) 1571 { 1572 int pointer_p = t->kind == TYPE_POINTER; 1573 1574 if (pointer_p) 1575 t = t->u.p; 1576 t = find_param_structure (t, param); 1577 if (pointer_p) 1578 t = create_pointer (t); 1579 } 1580 1581 if (use_param_num != -1) 1582 { 1583 if (param != NULL && param[use_param_num] != NULL) 1584 { 1585 type_p nt = param[use_param_num]; 1586 1587 if (t->kind == TYPE_ARRAY) 1588 nt = create_array (nt, t->u.a.len); 1589 else if (length != NULL && t->kind == TYPE_POINTER) 1590 nt = create_pointer (nt); 1591 needs_cast_p = (t->kind != TYPE_POINTER 1592 && nt->kind == TYPE_POINTER); 1593 t = nt; 1594 } 1595 else if (s->kind != TYPE_UNION) 1596 error_at_line (&f->line, "no parameter defined"); 1597 } 1598 1599 if (t->kind == TYPE_SCALAR 1600 || (t->kind == TYPE_ARRAY 1601 && t->u.a.p->kind == TYPE_SCALAR)) 1602 continue; 1603 1604 seen_default |= default_p; 1605 1606 if (maybe_undef_p 1607 && (t->kind != TYPE_POINTER 1608 || t->u.p->kind != TYPE_STRUCT)) 1609 error_at_line (&f->line, 1610 "field `%s' has invalid option `maybe_undef_p'\n", 1611 f->name); 1612 if (s->kind == TYPE_UNION) 1613 { 1614 if (tagid) 1615 { 1616 oprintf (of, "%*scase %s:\n", indent, "", tagid); 1617 1618 } 1619 else if (default_p) 1620 { 1621 oprintf (of, "%*sdefault:\n", indent, ""); 1622 } 1623 else 1624 { 1625 error_at_line (&f->line, "field `%s' has no tag", f->name); 1626 continue; 1627 } 1628 indent += 2; 1629 } 1630 1631 switch (t->kind) 1632 { 1633 case TYPE_STRING: 1634 /* Do nothing; strings go in the string pool. */ 1635 break; 1636 1637 case TYPE_LANG_STRUCT: 1638 { 1639 type_p ti; 1640 for (ti = t->u.s.lang_struct; ti; ti = ti->next) 1641 if (ti->u.s.bitmap & bitmap) 1642 { 1643 t = ti; 1644 break; 1645 } 1646 if (ti == NULL) 1647 { 1648 error_at_line (&f->line, 1649 "structure not defined for this language"); 1650 break; 1651 } 1652 } 1653 /* Fall through... */ 1654 case TYPE_STRUCT: 1655 case TYPE_UNION: 1656 { 1657 char *newval; 1658 1659 newval = xasprintf ("%s%s%s", val, dot, f->name); 1660 write_gc_structure_fields (of, t, newval, val, f->opt, indent, 1661 &f->line, bitmap, param); 1662 free (newval); 1663 break; 1664 } 1665 1666 case TYPE_POINTER: 1667 if (! length) 1668 { 1669 if (maybe_undef_p 1670 && t->u.p->u.s.line.file == NULL) 1671 oprintf (of, "%*sif (%s%s%s) abort();\n", indent, "", 1672 val, dot, f->name); 1673 else if (UNION_OR_STRUCT_P (t->u.p) 1674 || t->u.p->kind == TYPE_PARAM_STRUCT) 1675 { 1676 oprintf (of, "%*sgt_ggc_m_", indent, ""); 1677 output_mangled_typename (of, t->u.p); 1678 oprintf (of, " ("); 1679 if (needs_cast_p) 1680 oprintf (of, "(%s %s *)", 1681 UNION_P (t->u.p) ? "union" : "struct", 1682 t->u.p->u.s.tag); 1683 oprintf (of, "%s%s%s);\n", val, dot, f->name); 1684 } 1685 else 1686 error_at_line (&f->line, "field `%s' is pointer to scalar", 1687 f->name); 1688 break; 1689 } 1690 else if (t->u.p->kind == TYPE_SCALAR 1691 || t->u.p->kind == TYPE_STRING) 1692 oprintf (of, "%*sggc_mark (%s%s%s);\n", indent, "", 1693 val, dot, f->name); 1694 else 1695 { 1696 int loopcounter = ++gc_counter; 1697 1698 oprintf (of, "%*sif (%s%s%s != NULL) {\n", indent, "", 1699 val, dot, f->name); 1700 indent += 2; 1701 oprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter); 1702 oprintf (of, "%*sggc_set_mark (%s%s%s);\n", indent, "", 1703 val, dot, f->name); 1704 oprintf (of, "%*sfor (i%d = 0; i%d < (size_t)(", indent, "", 1705 loopcounter, loopcounter); 1706 output_escaped_param (of, length, val, prev_val, "length", line); 1707 oprintf (of, "); i%d++) {\n", loopcounter); 1708 indent += 2; 1709 switch (t->u.p->kind) 1710 { 1711 case TYPE_STRUCT: 1712 case TYPE_UNION: 1713 { 1714 char *newval; 1715 1716 newval = xasprintf ("%s%s%s[i%d]", val, dot, f->name, 1717 loopcounter); 1718 write_gc_structure_fields (of, t->u.p, newval, val, 1719 f->opt, indent, &f->line, 1720 bitmap, param); 1721 free (newval); 1722 break; 1723 } 1724 case TYPE_POINTER: 1725 if (UNION_OR_STRUCT_P (t->u.p->u.p) 1726 || t->u.p->u.p->kind == TYPE_PARAM_STRUCT) 1727 { 1728 oprintf (of, "%*sgt_ggc_m_", indent, ""); 1729 output_mangled_typename (of, t->u.p->u.p); 1730 oprintf (of, " (%s%s%s[i%d]);\n", val, dot, f->name, 1731 loopcounter); 1732 } 1733 else 1734 error_at_line (&f->line, 1735 "field `%s' is array of pointer to scalar", 1736 f->name); 1737 break; 1738 default: 1739 error_at_line (&f->line, 1740 "field `%s' is array of unimplemented type", 1741 f->name); 1742 break; 1743 } 1744 indent -= 2; 1745 oprintf (of, "%*s}\n", indent, ""); 1746 indent -= 2; 1747 oprintf (of, "%*s}\n", indent, ""); 1748 } 1749 break; 1750 1751 case TYPE_ARRAY: 1752 { 1753 int loopcounter = ++gc_counter; 1754 type_p ta; 1755 int i; 1756 1757 if (! length && 1758 (strcmp (t->u.a.len, "0") == 0 1759 || strcmp (t->u.a.len, "1") == 0)) 1760 error_at_line (&f->line, 1761 "field `%s' is array of size %s", 1762 f->name, t->u.a.len); 1763 1764 /* Arrays of scalars can be ignored. */ 1765 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p) 1766 ; 1767 if (ta->kind == TYPE_SCALAR 1768 || ta->kind == TYPE_STRING) 1769 break; 1770 1771 oprintf (of, "%*s{\n", indent, ""); 1772 indent += 2; 1773 1774 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++) 1775 { 1776 oprintf (of, "%*ssize_t i%d_%d;\n", 1777 indent, "", loopcounter, i); 1778 oprintf (of, "%*sconst size_t ilimit%d_%d = (", 1779 indent, "", loopcounter, i); 1780 if (i == 0 && length != NULL) 1781 output_escaped_param (of, length, val, prev_val, 1782 "length", line); 1783 else 1784 oprintf (of, "%s", ta->u.a.len); 1785 oprintf (of, ");\n"); 1786 } 1787 1788 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++) 1789 { 1790 oprintf (of, 1791 "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n", 1792 indent, "", loopcounter, i, loopcounter, i, 1793 loopcounter, i, loopcounter, i); 1794 indent += 2; 1795 } 1796 1797 if (ta->kind == TYPE_POINTER 1798 && (UNION_OR_STRUCT_P (ta->u.p) 1799 || ta->u.p->kind == TYPE_PARAM_STRUCT)) 1800 { 1801 oprintf (of, "%*sgt_ggc_m_", indent, ""); 1802 output_mangled_typename (of, ta->u.p); 1803 oprintf (of, " (%s%s%s", val, dot, f->name); 1804 for (ta = t, i = 0; 1805 ta->kind == TYPE_ARRAY; 1806 ta = ta->u.a.p, i++) 1807 oprintf (of, "[i%d_%d]", loopcounter, i); 1808 oprintf (of, ");\n"); 1809 } 1810 else if (ta->kind == TYPE_STRUCT || ta->kind == TYPE_UNION) 1811 { 1812 char *newval; 1813 int len; 1814 1815 len = strlen (val) + strlen (f->name) + 2; 1816 for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p) 1817 len += sizeof ("[i_]") + 2*6; 1818 1819 newval = xmalloc (len); 1820 sprintf (newval, "%s%s%s", val, dot, f->name); 1821 for (ta = t, i = 0; 1822 ta->kind == TYPE_ARRAY; 1823 ta = ta->u.a.p, i++) 1824 sprintf (newval + strlen (newval), "[i%d_%d]", 1825 loopcounter, i); 1826 write_gc_structure_fields (of, t->u.p, newval, val, 1827 f->opt, indent, &f->line, bitmap, 1828 param); 1829 free (newval); 1830 } 1831 else if (ta->kind == TYPE_POINTER && ta->u.p->kind == TYPE_SCALAR 1832 && use_param_num != -1 && param == NULL) 1833 oprintf (of, "%*sabort();\n", indent, ""); 1834 else 1835 error_at_line (&f->line, 1836 "field `%s' is array of unimplemented type", 1837 f->name); 1838 for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++) 1839 { 1840 indent -= 2; 1841 oprintf (of, "%*s}\n", indent, ""); 1842 } 1843 1844 indent -= 2; 1845 oprintf (of, "%*s}\n", indent, ""); 1846 break; 1847 } 1848 1849 default: 1850 error_at_line (&f->line, 1851 "field `%s' is unimplemented type", 1852 f->name); 1853 break; 1854 } 1855 1856 if (s->kind == TYPE_UNION) 1857 { 1858 oprintf (of, "%*sbreak;\n", indent, ""); 1859 indent -= 2; 1860 } 1861 } 1862 if (s->kind == TYPE_UNION) 1863 { 1864 if (! seen_default) 1865 { 1866 oprintf (of, "%*sdefault:\n", indent, ""); 1867 oprintf (of, "%*s break;\n", indent, ""); 1868 } 1869 oprintf (of, "%*s}\n", indent, ""); 1870 indent -= 2; 1871 } 1872} 1873 1874/* Write out a marker routine for S. PARAM is the parameter from an 1875 enclosing PARAM_IS option. */ 1876 1877static void 1878write_gc_marker_routine_for_structure (orig_s, s, param) 1879 type_p orig_s; 1880 type_p s; 1881 type_p * param; 1882{ 1883 outf_p f; 1884 const char *fn = s->u.s.line.file; 1885 int i; 1886 const char *chain_next = NULL; 1887 const char *chain_prev = NULL; 1888 options_p opt; 1889 1890 /* This is a hack, and not the good kind either. */ 1891 for (i = NUM_PARAM - 1; i >= 0; i--) 1892 if (param && param[i] && param[i]->kind == TYPE_POINTER 1893 && UNION_OR_STRUCT_P (param[i]->u.p)) 1894 fn = param[i]->u.p->u.s.line.file; 1895 1896 f = get_output_file_with_visibility (fn); 1897 1898 for (opt = s->u.s.opt; opt; opt = opt->next) 1899 if (strcmp (opt->name, "chain_next") == 0) 1900 chain_next = (const char *) opt->info; 1901 else if (strcmp (opt->name, "chain_prev") == 0) 1902 chain_prev = (const char *) opt->info; 1903 1904 if (chain_prev != NULL && chain_next == NULL) 1905 error_at_line (&s->u.s.line, "chain_prev without chain_next"); 1906 1907 oprintf (f, "\n"); 1908 oprintf (f, "void\n"); 1909 if (param == NULL) 1910 oprintf (f, "gt_ggc_mx_%s", s->u.s.tag); 1911 else 1912 { 1913 oprintf (f, "gt_ggc_m_"); 1914 output_mangled_typename (f, orig_s); 1915 } 1916 oprintf (f, " (x_p)\n"); 1917 oprintf (f, " void *x_p;\n"); 1918 oprintf (f, "{\n"); 1919 oprintf (f, " %s %s * %sx = (%s %s *)x_p;\n", 1920 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, 1921 chain_next == NULL ? "const " : "", 1922 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); 1923 if (chain_next != NULL) 1924 oprintf (f, " %s %s * xlimit = x;\n", 1925 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); 1926 if (chain_next == NULL) 1927 oprintf (f, " if (ggc_test_and_set_mark (x))\n"); 1928 else 1929 { 1930 oprintf (f, " while (ggc_test_and_set_mark (xlimit))\n"); 1931 oprintf (f, " xlimit = ("); 1932 output_escaped_param (f, chain_next, "*xlimit", "*xlimit", 1933 "chain_next", &s->u.s.line); 1934 oprintf (f, ");\n"); 1935 if (chain_prev != NULL) 1936 { 1937 oprintf (f, " if (x != xlimit)\n"); 1938 oprintf (f, " for (;;)\n"); 1939 oprintf (f, " {\n"); 1940 oprintf (f, " %s %s * const xprev = (", 1941 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); 1942 output_escaped_param (f, chain_prev, "*x", "*x", 1943 "chain_prev", &s->u.s.line); 1944 oprintf (f, ");\n"); 1945 oprintf (f, " if (xprev == NULL) break;\n"); 1946 oprintf (f, " x = xprev;\n"); 1947 oprintf (f, " ggc_set_mark (xprev);\n"); 1948 oprintf (f, " }\n"); 1949 } 1950 oprintf (f, " while (x != xlimit)\n"); 1951 } 1952 oprintf (f, " {\n"); 1953 1954 gc_counter = 0; 1955 write_gc_structure_fields (f, s, "(*x)", "not valid postage", 1956 s->u.s.opt, 6, &s->u.s.line, s->u.s.bitmap, 1957 param); 1958 1959 if (chain_next != NULL) 1960 { 1961 oprintf (f, " x = ("); 1962 output_escaped_param (f, chain_next, "*x", "*x", 1963 "chain_next", &s->u.s.line); 1964 oprintf (f, ");\n"); 1965 } 1966 1967 oprintf (f, " }\n"); 1968 oprintf (f, "}\n"); 1969} 1970 1971/* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */ 1972 1973static void 1974write_gc_types (structures, param_structs) 1975 type_p structures; 1976 type_p param_structs; 1977{ 1978 type_p s; 1979 1980 oprintf (header_file, "\n/* GC marker procedures. */\n"); 1981 for (s = structures; s; s = s->next) 1982 if (s->gc_used == GC_POINTED_TO 1983 || s->gc_used == GC_MAYBE_POINTED_TO) 1984 { 1985 options_p opt; 1986 1987 if (s->gc_used == GC_MAYBE_POINTED_TO 1988 && s->u.s.line.file == NULL) 1989 continue; 1990 1991 oprintf (header_file, "#define gt_ggc_m_"); 1992 output_mangled_typename (header_file, s); 1993 oprintf (header_file, "(X) do { \\\n"); 1994 oprintf (header_file, 1995 " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s->u.s.tag); 1996 oprintf (header_file, 1997 " } while (0)\n"); 1998 1999 for (opt = s->u.s.opt; opt; opt = opt->next) 2000 if (strcmp (opt->name, "ptr_alias") == 0) 2001 { 2002 type_p t = (type_p) opt->info; 2003 if (t->kind == TYPE_STRUCT 2004 || t->kind == TYPE_UNION 2005 || t->kind == TYPE_LANG_STRUCT) 2006 oprintf (header_file, 2007 "#define gt_ggc_mx_%s gt_ggc_mx_%s\n", 2008 s->u.s.tag, t->u.s.tag); 2009 else 2010 error_at_line (&s->u.s.line, 2011 "structure alias is not a structure"); 2012 break; 2013 } 2014 if (opt) 2015 continue; 2016 2017 /* Declare the marker procedure only once. */ 2018 oprintf (header_file, 2019 "extern void gt_ggc_mx_%s PARAMS ((void *));\n", 2020 s->u.s.tag); 2021 2022 if (s->u.s.line.file == NULL) 2023 { 2024 fprintf (stderr, "warning: structure `%s' used but not defined\n", 2025 s->u.s.tag); 2026 continue; 2027 } 2028 2029 if (s->kind == TYPE_LANG_STRUCT) 2030 { 2031 type_p ss; 2032 for (ss = s->u.s.lang_struct; ss; ss = ss->next) 2033 write_gc_marker_routine_for_structure (s, ss, NULL); 2034 } 2035 else 2036 write_gc_marker_routine_for_structure (s, s, NULL); 2037 } 2038 2039 for (s = param_structs; s; s = s->next) 2040 if (s->gc_used == GC_POINTED_TO) 2041 { 2042 type_p * param = s->u.param_struct.param; 2043 type_p stru = s->u.param_struct.stru; 2044 2045 /* Declare the marker procedure. */ 2046 oprintf (header_file, "extern void gt_ggc_m_"); 2047 output_mangled_typename (header_file, s); 2048 oprintf (header_file, " PARAMS ((void *));\n"); 2049 2050 if (stru->u.s.line.file == NULL) 2051 { 2052 fprintf (stderr, "warning: structure `%s' used but not defined\n", 2053 s->u.s.tag); 2054 continue; 2055 } 2056 2057 if (stru->kind == TYPE_LANG_STRUCT) 2058 { 2059 type_p ss; 2060 for (ss = stru->u.s.lang_struct; ss; ss = ss->next) 2061 write_gc_marker_routine_for_structure (s, ss, param); 2062 } 2063 else 2064 write_gc_marker_routine_for_structure (s, stru, param); 2065 } 2066} 2067 2068/* Write out the 'enum' definition for gt_types_enum. */ 2069 2070static void 2071write_enum_defn (structures, param_structs) 2072 type_p structures; 2073 type_p param_structs; 2074{ 2075 type_p s; 2076 2077 oprintf (header_file, "\n/* Enumeration of types known. */\n"); 2078 oprintf (header_file, "enum gt_types_enum {\n"); 2079 for (s = structures; s; s = s->next) 2080 if (s->gc_used == GC_POINTED_TO 2081 || s->gc_used == GC_MAYBE_POINTED_TO) 2082 { 2083 if (s->gc_used == GC_MAYBE_POINTED_TO 2084 && s->u.s.line.file == NULL) 2085 continue; 2086 2087 oprintf (header_file, " gt_ggc_e_"); 2088 output_mangled_typename (header_file, s); 2089 oprintf (header_file, ", \n"); 2090 } 2091 for (s = param_structs; s; s = s->next) 2092 if (s->gc_used == GC_POINTED_TO) 2093 { 2094 oprintf (header_file, " gt_e_"); 2095 output_mangled_typename (header_file, s); 2096 oprintf (header_file, ", \n"); 2097 } 2098 oprintf (header_file, " gt_types_enum_last\n"); 2099 oprintf (header_file, "};\n"); 2100} 2101 2102 2103/* Mangle FN and print it to F. */ 2104 2105static void 2106put_mangled_filename (f, fn) 2107 outf_p f; 2108 const char *fn; 2109{ 2110 const char *name = get_output_file_name (fn); 2111 for (; *name != 0; name++) 2112 if (ISALNUM (*name)) 2113 oprintf (f, "%c", *name); 2114 else 2115 oprintf (f, "%c", '_'); 2116} 2117 2118/* Finish off the currently-created root tables in FLP. PFX, TNAME, 2119 LASTNAME, and NAME are all strings to insert in various places in 2120 the resulting code. */ 2121 2122static void 2123finish_root_table (flp, pfx, lastname, tname, name) 2124 struct flist *flp; 2125 const char *pfx; 2126 const char *tname; 2127 const char *lastname; 2128 const char *name; 2129{ 2130 struct flist *fli2; 2131 unsigned started_bitmap = 0; 2132 2133 for (fli2 = flp; fli2; fli2 = fli2->next) 2134 if (fli2->started_p) 2135 { 2136 oprintf (fli2->f, " %s\n", lastname); 2137 oprintf (fli2->f, "};\n\n"); 2138 } 2139 2140 for (fli2 = flp; fli2; fli2 = fli2->next) 2141 if (fli2->started_p) 2142 { 2143 lang_bitmap bitmap = get_base_file_bitmap (fli2->name); 2144 int fnum; 2145 2146 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1) 2147 if (bitmap & 1) 2148 { 2149 oprintf (base_files[fnum], 2150 "extern const struct %s gt_ggc_%s_", 2151 tname, pfx); 2152 put_mangled_filename (base_files[fnum], fli2->name); 2153 oprintf (base_files[fnum], "[];\n"); 2154 } 2155 } 2156 2157 for (fli2 = flp; fli2; fli2 = fli2->next) 2158 if (fli2->started_p) 2159 { 2160 lang_bitmap bitmap = get_base_file_bitmap (fli2->name); 2161 int fnum; 2162 2163 fli2->started_p = 0; 2164 2165 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1) 2166 if (bitmap & 1) 2167 { 2168 if (! (started_bitmap & (1 << fnum))) 2169 { 2170 oprintf (base_files [fnum], 2171 "const struct %s * const %s[] = {\n", 2172 tname, name); 2173 started_bitmap |= 1 << fnum; 2174 } 2175 oprintf (base_files[fnum], " gt_ggc_%s_", pfx); 2176 put_mangled_filename (base_files[fnum], fli2->name); 2177 oprintf (base_files[fnum], ",\n"); 2178 } 2179 } 2180 2181 { 2182 unsigned bitmap; 2183 int fnum; 2184 2185 for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1) 2186 if (bitmap & 1) 2187 { 2188 oprintf (base_files[fnum], " NULL\n"); 2189 oprintf (base_files[fnum], "};\n"); 2190 } 2191 } 2192} 2193 2194/* Write out to F the table entry and any marker routines needed to 2195 mark NAME as TYPE. The original variable is V, at LINE. 2196 HAS_LENGTH is nonzero iff V was a variable-length array. IF_MARKED 2197 is nonzero iff we are building the root table for hash table caches. */ 2198 2199static void 2200write_gc_root (f, v, type, name, has_length, line, if_marked) 2201 outf_p f; 2202 pair_p v; 2203 type_p type; 2204 const char *name; 2205 int has_length; 2206 struct fileloc *line; 2207 const char *if_marked; 2208{ 2209 switch (type->kind) 2210 { 2211 case TYPE_STRUCT: 2212 { 2213 pair_p fld; 2214 for (fld = type->u.s.fields; fld; fld = fld->next) 2215 { 2216 int skip_p = 0; 2217 const char *desc = NULL; 2218 options_p o; 2219 2220 for (o = fld->opt; o; o = o->next) 2221 if (strcmp (o->name, "skip") == 0) 2222 skip_p = 1; 2223 else if (strcmp (o->name, "desc") == 0) 2224 desc = (const char *)o->info; 2225 else 2226 error_at_line (line, 2227 "field `%s' of global `%s' has unknown option `%s'", 2228 fld->name, name, o->name); 2229 2230 if (skip_p) 2231 continue; 2232 else if (desc && fld->type->kind == TYPE_UNION) 2233 { 2234 pair_p validf = NULL; 2235 pair_p ufld; 2236 2237 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next) 2238 { 2239 const char *tag = NULL; 2240 options_p oo; 2241 2242 for (oo = ufld->opt; oo; oo = oo->next) 2243 if (strcmp (oo->name, "tag") == 0) 2244 tag = (const char *)oo->info; 2245 if (tag == NULL || strcmp (tag, desc) != 0) 2246 continue; 2247 if (validf != NULL) 2248 error_at_line (line, 2249 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'", 2250 name, fld->name, validf->name, 2251 name, fld->name, ufld->name, 2252 tag); 2253 validf = ufld; 2254 } 2255 if (validf != NULL) 2256 { 2257 char *newname; 2258 newname = xasprintf ("%s.%s.%s", 2259 name, fld->name, validf->name); 2260 write_gc_root (f, v, validf->type, newname, 0, line, 2261 if_marked); 2262 free (newname); 2263 } 2264 } 2265 else if (desc) 2266 error_at_line (line, 2267 "global `%s.%s' has `desc' option but is not union", 2268 name, fld->name); 2269 else 2270 { 2271 char *newname; 2272 newname = xasprintf ("%s.%s", name, fld->name); 2273 write_gc_root (f, v, fld->type, newname, 0, line, if_marked); 2274 free (newname); 2275 } 2276 } 2277 } 2278 break; 2279 2280 case TYPE_ARRAY: 2281 { 2282 char *newname; 2283 newname = xasprintf ("%s[0]", name); 2284 write_gc_root (f, v, type->u.a.p, newname, has_length, line, if_marked); 2285 free (newname); 2286 } 2287 break; 2288 2289 case TYPE_POINTER: 2290 { 2291 type_p ap, tp; 2292 2293 oprintf (f, " {\n"); 2294 oprintf (f, " &%s,\n", name); 2295 oprintf (f, " 1"); 2296 2297 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p) 2298 if (ap->u.a.len[0]) 2299 oprintf (f, " * (%s)", ap->u.a.len); 2300 else if (ap == v->type) 2301 oprintf (f, " * ARRAY_SIZE (%s)", v->name); 2302 oprintf (f, ",\n"); 2303 oprintf (f, " sizeof (%s", v->name); 2304 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p) 2305 oprintf (f, "[0]"); 2306 oprintf (f, "),\n"); 2307 2308 tp = type->u.p; 2309 2310 if (! has_length && UNION_OR_STRUCT_P (tp)) 2311 { 2312 oprintf (f, " >_ggc_mx_%s\n", tp->u.s.tag); 2313 } 2314 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT) 2315 { 2316 oprintf (f, " >_ggc_m_"); 2317 output_mangled_typename (f, tp); 2318 } 2319 else if (has_length 2320 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp))) 2321 { 2322 oprintf (f, " >_ggc_ma_%s", name); 2323 } 2324 else 2325 { 2326 error_at_line (line, 2327 "global `%s' is pointer to unimplemented type", 2328 name); 2329 } 2330 if (if_marked) 2331 oprintf (f, ",\n &%s", if_marked); 2332 oprintf (f, "\n },\n"); 2333 } 2334 break; 2335 2336 case TYPE_SCALAR: 2337 case TYPE_STRING: 2338 break; 2339 2340 default: 2341 error_at_line (line, 2342 "global `%s' is unimplemented type", 2343 name); 2344 } 2345} 2346 2347/* Output a table describing the locations and types of VARIABLES. */ 2348 2349static void 2350write_gc_roots (variables) 2351 pair_p variables; 2352{ 2353 pair_p v; 2354 struct flist *flp = NULL; 2355 2356 for (v = variables; v; v = v->next) 2357 { 2358 outf_p f = get_output_file_with_visibility (v->line.file); 2359 struct flist *fli; 2360 const char *length = NULL; 2361 int deletable_p = 0; 2362 options_p o; 2363 2364 for (o = v->opt; o; o = o->next) 2365 if (strcmp (o->name, "length") == 0) 2366 length = (const char *)o->info; 2367 else if (strcmp (o->name, "deletable") == 0) 2368 deletable_p = 1; 2369 else if (strcmp (o->name, "param_is") == 0) 2370 ; 2371 else if (strncmp (o->name, "param", 5) == 0 2372 && ISDIGIT (o->name[5]) 2373 && strcmp (o->name + 6, "_is") == 0) 2374 ; 2375 else if (strcmp (o->name, "if_marked") == 0) 2376 ; 2377 else 2378 error_at_line (&v->line, 2379 "global `%s' has unknown option `%s'", 2380 v->name, o->name); 2381 2382 for (fli = flp; fli; fli = fli->next) 2383 if (fli->f == f) 2384 break; 2385 if (fli == NULL) 2386 { 2387 fli = xmalloc (sizeof (*fli)); 2388 fli->f = f; 2389 fli->next = flp; 2390 fli->started_p = 0; 2391 fli->name = v->line.file; 2392 flp = fli; 2393 2394 oprintf (f, "\n/* GC roots. */\n\n"); 2395 } 2396 2397 if (! deletable_p 2398 && length 2399 && v->type->kind == TYPE_POINTER 2400 && (v->type->u.p->kind == TYPE_POINTER 2401 || v->type->u.p->kind == TYPE_STRUCT)) 2402 { 2403 oprintf (f, "static void gt_ggc_ma_%s PARAMS ((void *));\n", 2404 v->name); 2405 oprintf (f, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n", 2406 v->name); 2407 oprintf (f, "{\n"); 2408 oprintf (f, " size_t i;\n"); 2409 2410 if (v->type->u.p->kind == TYPE_POINTER) 2411 { 2412 type_p s = v->type->u.p->u.p; 2413 2414 oprintf (f, " %s %s ** const x = (%s %s **)x_p;\n", 2415 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, 2416 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); 2417 oprintf (f, " if (ggc_test_and_set_mark (x))\n"); 2418 oprintf (f, " for (i = 0; i < (%s); i++)\n", length); 2419 if (! UNION_OR_STRUCT_P (s) 2420 && ! s->kind == TYPE_PARAM_STRUCT) 2421 { 2422 error_at_line (&v->line, 2423 "global `%s' has unsupported ** type", 2424 v->name); 2425 continue; 2426 } 2427 2428 oprintf (f, " gt_ggc_m_"); 2429 output_mangled_typename (f, s); 2430 oprintf (f, " (x[i]);\n"); 2431 } 2432 else 2433 { 2434 type_p s = v->type->u.p; 2435 2436 oprintf (f, " %s %s * const x = (%s %s *)x_p;\n", 2437 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag, 2438 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag); 2439 oprintf (f, " if (ggc_test_and_set_mark (x))\n"); 2440 oprintf (f, " for (i = 0; i < (%s); i++)\n", length); 2441 oprintf (f, " {\n"); 2442 write_gc_structure_fields (f, s, "x[i]", "x[i]", 2443 v->opt, 8, &v->line, s->u.s.bitmap, 2444 NULL); 2445 oprintf (f, " }\n"); 2446 } 2447 2448 oprintf (f, "}\n\n"); 2449 } 2450 } 2451 2452 for (v = variables; v; v = v->next) 2453 { 2454 outf_p f = get_output_file_with_visibility (v->line.file); 2455 struct flist *fli; 2456 int skip_p = 0; 2457 int length_p = 0; 2458 options_p o; 2459 2460 for (o = v->opt; o; o = o->next) 2461 if (strcmp (o->name, "length") == 0) 2462 length_p = 1; 2463 else if (strcmp (o->name, "deletable") == 0 2464 || strcmp (o->name, "if_marked") == 0) 2465 skip_p = 1; 2466 2467 if (skip_p) 2468 continue; 2469 2470 for (fli = flp; fli; fli = fli->next) 2471 if (fli->f == f) 2472 break; 2473 if (! fli->started_p) 2474 { 2475 fli->started_p = 1; 2476 2477 oprintf (f, "const struct ggc_root_tab gt_ggc_r_"); 2478 put_mangled_filename (f, v->line.file); 2479 oprintf (f, "[] = {\n"); 2480 } 2481 2482 write_gc_root (f, v, v->type, v->name, length_p, &v->line, NULL); 2483 } 2484 2485 finish_root_table (flp, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab", 2486 "gt_ggc_rtab"); 2487 2488 for (v = variables; v; v = v->next) 2489 { 2490 outf_p f = get_output_file_with_visibility (v->line.file); 2491 struct flist *fli; 2492 int skip_p = 1; 2493 options_p o; 2494 2495 for (o = v->opt; o; o = o->next) 2496 if (strcmp (o->name, "deletable") == 0) 2497 skip_p = 0; 2498 else if (strcmp (o->name, "if_marked") == 0) 2499 skip_p = 1; 2500 2501 if (skip_p) 2502 continue; 2503 2504 for (fli = flp; fli; fli = fli->next) 2505 if (fli->f == f) 2506 break; 2507 if (! fli->started_p) 2508 { 2509 fli->started_p = 1; 2510 2511 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_"); 2512 put_mangled_filename (f, v->line.file); 2513 oprintf (f, "[] = {\n"); 2514 } 2515 2516 oprintf (f, " { &%s, 1, sizeof (%s), NULL },\n", 2517 v->name, v->name); 2518 } 2519 2520 finish_root_table (flp, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab", 2521 "gt_ggc_deletable_rtab"); 2522 2523 for (v = variables; v; v = v->next) 2524 { 2525 outf_p f = get_output_file_with_visibility (v->line.file); 2526 struct flist *fli; 2527 const char *if_marked = NULL; 2528 int length_p = 0; 2529 options_p o; 2530 2531 for (o = v->opt; o; o = o->next) 2532 if (strcmp (o->name, "length") == 0) 2533 length_p = 1; 2534 else if (strcmp (o->name, "if_marked") == 0) 2535 if_marked = (const char *) o->info; 2536 2537 if (if_marked == NULL) 2538 continue; 2539 2540 if (v->type->kind != TYPE_POINTER 2541 || v->type->u.p->kind != TYPE_PARAM_STRUCT 2542 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0)) 2543 { 2544 error_at_line (&v->line, "if_marked option used but not hash table"); 2545 continue; 2546 } 2547 2548 for (fli = flp; fli; fli = fli->next) 2549 if (fli->f == f) 2550 break; 2551 if (! fli->started_p) 2552 { 2553 fli->started_p = 1; 2554 2555 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_"); 2556 put_mangled_filename (f, v->line.file); 2557 oprintf (f, "[] = {\n"); 2558 } 2559 2560 write_gc_root (f, v, v->type->u.p->u.param_struct.param[0], 2561 v->name, length_p, &v->line, if_marked); 2562 } 2563 2564 finish_root_table (flp, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab", 2565 "gt_ggc_cache_rtab"); 2566} 2567 2568 2569extern int main PARAMS ((int argc, char **argv)); 2570int 2571main(argc, argv) 2572 int argc ATTRIBUTE_UNUSED; 2573 char **argv ATTRIBUTE_UNUSED; 2574{ 2575 unsigned i; 2576 static struct fileloc pos = { __FILE__, __LINE__ }; 2577 unsigned j; 2578 2579 gen_rtx_next (); 2580 2581 srcdir_len = strlen (srcdir); 2582 2583 do_scalar_typedef ("CUMULATIVE_ARGS", &pos); 2584 do_scalar_typedef ("REAL_VALUE_TYPE", &pos); 2585 do_scalar_typedef ("uint8", &pos); 2586 do_scalar_typedef ("jword", &pos); 2587 do_scalar_typedef ("JCF_u2", &pos); 2588 2589 do_typedef ("PTR", create_pointer (create_scalar_type ("void", 2590 strlen ("void"))), 2591 &pos); 2592 do_typedef ("HARD_REG_SET", create_array ( 2593 create_scalar_type ("unsigned long", strlen ("unsigned long")), 2594 "2"), &pos); 2595 2596 for (i = 0; i < NUM_GT_FILES; i++) 2597 { 2598 int dupflag = 0; 2599 /* Omit if already seen. */ 2600 for (j = 0; j < i; j++) 2601 { 2602 if (!strcmp (all_files[i], all_files[j])) 2603 { 2604 dupflag = 1; 2605 break; 2606 } 2607 } 2608 if (!dupflag) 2609 parse_file (all_files[i]); 2610 } 2611 2612 if (hit_error != 0) 2613 exit (1); 2614 2615 set_gc_used (variables); 2616 2617 open_base_files (); 2618 write_enum_defn (structures, param_structs); 2619 write_gc_types (structures, param_structs); 2620 write_gc_roots (variables); 2621 write_rtx_next (); 2622 close_output_files (); 2623 2624 return (hit_error != 0); 2625} 2626