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