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