00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "bconfig.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "gengtype.h"
00026 #include "gtyp-gen.h"
00027 #include "errors.h"
00028
00029
00030 static int hit_error = 0;
00031
00032 static void gen_rtx_next (void);
00033 static void write_rtx_next (void);
00034 static void open_base_files (void);
00035 static void close_output_files (void);
00036
00037
00038
00039 void
00040 error_at_line (struct fileloc *pos, const char *msg, ...)
00041 {
00042 va_list ap;
00043
00044 va_start (ap, msg);
00045
00046 fprintf (stderr, "%s:%d: ", pos->file, pos->line);
00047 vfprintf (stderr, msg, ap);
00048 fputc ('\n', stderr);
00049 hit_error = 1;
00050
00051 va_end (ap);
00052 }
00053
00054
00055 int
00056 xvasprintf (char **result, const char *format, va_list args)
00057 {
00058 int ret = vasprintf (result, format, args);
00059 if (*result == NULL || ret < 0)
00060 {
00061 fputs ("gengtype: out of memory", stderr);
00062 xexit (1);
00063 }
00064 return ret;
00065 }
00066
00067
00068 char *
00069 xasprintf (const char *format, ...)
00070 {
00071 char *result;
00072 va_list ap;
00073
00074 va_start (ap, format);
00075 xvasprintf (&result, format, ap);
00076 va_end (ap);
00077 return result;
00078 }
00079
00080
00081
00082 struct type string_type = {
00083 TYPE_STRING, NULL, NULL, GC_USED, {0}
00084 };
00085
00086
00087
00088 static pair_p typedefs;
00089 static type_p structures;
00090 static type_p param_structs;
00091 static pair_p variables;
00092
00093 static void do_scalar_typedef (const char *, struct fileloc *);
00094 static type_p find_param_structure
00095 (type_p t, type_p param[NUM_PARAM]);
00096 static type_p adjust_field_tree_exp (type_p t, options_p opt);
00097 static type_p adjust_field_rtx_def (type_p t, options_p opt);
00098
00099
00100
00101 void
00102 do_typedef (const char *s, type_p t, struct fileloc *pos)
00103 {
00104 pair_p p;
00105
00106 for (p = typedefs; p != NULL; p = p->next)
00107 if (strcmp (p->name, s) == 0)
00108 {
00109 if (p->type != t)
00110 {
00111 error_at_line (pos, "type `%s' previously defined", s);
00112 error_at_line (&p->line, "previously defined here");
00113 }
00114 return;
00115 }
00116
00117 p = XNEW (struct pair);
00118 p->next = typedefs;
00119 p->name = s;
00120 p->type = t;
00121 p->line = *pos;
00122 typedefs = p;
00123 }
00124
00125
00126
00127 static void
00128 do_scalar_typedef (const char *s, struct fileloc *pos)
00129 {
00130 do_typedef (s, create_scalar_type (s, strlen (s)), pos);
00131 }
00132
00133
00134
00135 type_p
00136 resolve_typedef (const char *s, struct fileloc *pos)
00137 {
00138 pair_p p;
00139 for (p = typedefs; p != NULL; p = p->next)
00140 if (strcmp (p->name, s) == 0)
00141 return p->type;
00142 error_at_line (pos, "unidentified type `%s'", s);
00143 return create_scalar_type ("char", 4);
00144 }
00145
00146
00147
00148
00149 void
00150 new_structure (const char *name, int isunion, struct fileloc *pos,
00151 pair_p fields, options_p o)
00152 {
00153 type_p si;
00154 type_p s = NULL;
00155 lang_bitmap bitmap = get_base_file_bitmap (pos->file);
00156
00157 for (si = structures; si != NULL; si = si->next)
00158 if (strcmp (name, si->u.s.tag) == 0
00159 && UNION_P (si) == isunion)
00160 {
00161 type_p ls = NULL;
00162 if (si->kind == TYPE_LANG_STRUCT)
00163 {
00164 ls = si;
00165
00166 for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
00167 if (si->u.s.bitmap == bitmap)
00168 s = si;
00169 }
00170 else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
00171 {
00172 ls = si;
00173 si = XCNEW (struct type);
00174 memcpy (si, ls, sizeof (struct type));
00175 ls->kind = TYPE_LANG_STRUCT;
00176 ls->u.s.lang_struct = si;
00177 ls->u.s.fields = NULL;
00178 si->next = NULL;
00179 si->pointer_to = NULL;
00180 si->u.s.lang_struct = ls;
00181 }
00182 else
00183 s = si;
00184
00185 if (ls != NULL && s == NULL)
00186 {
00187 s = XCNEW (struct type);
00188 s->next = ls->u.s.lang_struct;
00189 ls->u.s.lang_struct = s;
00190 s->u.s.lang_struct = ls;
00191 }
00192 break;
00193 }
00194
00195 if (s == NULL)
00196 {
00197 s = XCNEW (struct type);
00198 s->next = structures;
00199 structures = s;
00200 }
00201
00202 if (s->u.s.line.file != NULL
00203 || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
00204 {
00205 error_at_line (pos, "duplicate structure definition");
00206 error_at_line (&s->u.s.line, "previous definition here");
00207 }
00208
00209 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
00210 s->u.s.tag = name;
00211 s->u.s.line = *pos;
00212 s->u.s.fields = fields;
00213 s->u.s.opt = o;
00214 s->u.s.bitmap = bitmap;
00215 if (s->u.s.lang_struct)
00216 s->u.s.lang_struct->u.s.bitmap |= bitmap;
00217 }
00218
00219
00220
00221
00222
00223 type_p
00224 find_structure (const char *name, int isunion)
00225 {
00226 type_p s;
00227
00228 for (s = structures; s != NULL; s = s->next)
00229 if (strcmp (name, s->u.s.tag) == 0
00230 && UNION_P (s) == isunion)
00231 return s;
00232
00233 s = XCNEW (struct type);
00234 s->next = structures;
00235 structures = s;
00236 s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
00237 s->u.s.tag = name;
00238 structures = s;
00239 return s;
00240 }
00241
00242
00243
00244
00245
00246 static type_p
00247 find_param_structure (type_p t, type_p param[NUM_PARAM])
00248 {
00249 type_p res;
00250
00251 for (res = param_structs; res; res = res->next)
00252 if (res->u.param_struct.stru == t
00253 && memcmp (res->u.param_struct.param, param,
00254 sizeof (type_p) * NUM_PARAM) == 0)
00255 break;
00256 if (res == NULL)
00257 {
00258 res = XCNEW (struct type);
00259 res->kind = TYPE_PARAM_STRUCT;
00260 res->next = param_structs;
00261 param_structs = res;
00262 res->u.param_struct.stru = t;
00263 memcpy (res->u.param_struct.param, param, sizeof (type_p) * NUM_PARAM);
00264 }
00265 return res;
00266 }
00267
00268
00269
00270 type_p
00271 create_scalar_type (const char *name, size_t name_len)
00272 {
00273 type_p r = XCNEW (struct type);
00274 r->kind = TYPE_SCALAR;
00275 r->u.sc = (char *) xmemdup (name, name_len, name_len + 1);
00276 return r;
00277 }
00278
00279
00280
00281 type_p
00282 create_pointer (type_p t)
00283 {
00284 if (! t->pointer_to)
00285 {
00286 type_p r = XCNEW (struct type);
00287 r->kind = TYPE_POINTER;
00288 r->u.p = t;
00289 t->pointer_to = r;
00290 }
00291 return t->pointer_to;
00292 }
00293
00294
00295
00296 type_p
00297 create_array (type_p t, const char *len)
00298 {
00299 type_p v;
00300
00301 v = XCNEW (struct type);
00302 v->kind = TYPE_ARRAY;
00303 v->u.a.p = t;
00304 v->u.a.len = len;
00305 return v;
00306 }
00307
00308
00309 options_p
00310 create_option (const char *name, void *info)
00311 {
00312 options_p o = XNEW (struct options);
00313 o->name = name;
00314 o->info = (const char*) info;
00315 return o;
00316 }
00317
00318
00319
00320
00321 void
00322 note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
00323 {
00324 pair_p n;
00325 n = XNEW (struct pair);
00326 n->name = s;
00327 n->type = t;
00328 n->line = *pos;
00329 n->opt = o;
00330 n->next = variables;
00331 variables = n;
00332 }
00333
00334
00335 #define CONST_DOUBLE_FORMAT "ww"
00336
00337 #undef GENERATOR_FILE
00338
00339 enum rtx_code {
00340 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
00341 #include "rtl.def"
00342 #undef DEF_RTL_EXPR
00343 NUM_RTX_CODE
00344 };
00345
00346 static const char * const rtx_name[NUM_RTX_CODE] = {
00347 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
00348 #include "rtl.def"
00349 #undef DEF_RTL_EXPR
00350 };
00351
00352 static const char * const rtx_format[NUM_RTX_CODE] = {
00353 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
00354 #include "rtl.def"
00355 #undef DEF_RTL_EXPR
00356 };
00357
00358 static int rtx_next_new[NUM_RTX_CODE];
00359
00360
00361
00362 enum insn_note {
00363 #define DEF_INSN_NOTE(NAME) NAME,
00364 #include "insn-notes.def"
00365 #undef DEF_INSN_NOTE
00366
00367 NOTE_INSN_MAX
00368 };
00369
00370
00371
00372 static const char *const note_insn_name[NOTE_INSN_MAX+1] = {
00373 #define DEF_INSN_NOTE(NAME) #NAME,
00374 #include "insn-notes.def"
00375 #undef DEF_INSN_NOTE
00376 };
00377
00378 #undef CONST_DOUBLE_FORMAT
00379 #define GENERATOR_FILE
00380
00381
00382
00383
00384 static void
00385 gen_rtx_next (void)
00386 {
00387 int i;
00388 for (i = 0; i < NUM_RTX_CODE; i++)
00389 {
00390 int k;
00391
00392 rtx_next_new[i] = -1;
00393 if (strncmp (rtx_format[i], "iuu", 3) == 0)
00394 rtx_next_new[i] = 2;
00395 else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
00396 rtx_next_new[i] = 1;
00397 else
00398 for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
00399 if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
00400 rtx_next_new[i] = k;
00401 }
00402 }
00403
00404
00405 static void
00406 write_rtx_next (void)
00407 {
00408 outf_p f = get_output_file_with_visibility (NULL);
00409 int i;
00410
00411 oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
00412 oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
00413 for (i = 0; i < NUM_RTX_CODE; i++)
00414 if (rtx_next_new[i] == -1)
00415 oprintf (f, " 0,\n");
00416 else
00417 oprintf (f,
00418 " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
00419 rtx_next_new[i]);
00420 oprintf (f, "};\n");
00421 }
00422
00423
00424
00425
00426
00427 static type_p
00428 adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
00429 {
00430 pair_p flds = NULL;
00431 options_p nodot;
00432 int i;
00433 type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
00434 type_p bitmap_tp, basic_block_tp, reg_attrs_tp;
00435
00436 if (t->kind != TYPE_UNION)
00437 {
00438 error_at_line (&lexer_line,
00439 "special `rtx_def' must be applied to a union");
00440 return &string_type;
00441 }
00442
00443 nodot = XNEW (struct options);
00444 nodot->next = NULL;
00445 nodot->name = "dot";
00446 nodot->info = "";
00447
00448 rtx_tp = create_pointer (find_structure ("rtx_def", 0));
00449 rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
00450 tree_tp = create_pointer (find_structure ("tree_node", 1));
00451 mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
00452 reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
00453 bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
00454 basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
00455 scalar_tp = create_scalar_type ("rtunion scalar", 14);
00456
00457 {
00458 pair_p note_flds = NULL;
00459 int c;
00460
00461 for (c = 0; c <= NOTE_INSN_MAX; c++)
00462 {
00463 pair_p old_note_flds = note_flds;
00464
00465 note_flds = XNEW (struct pair);
00466 note_flds->line.file = __FILE__;
00467 note_flds->line.line = __LINE__;
00468 note_flds->opt = XNEW (struct options);
00469 note_flds->opt->next = nodot;
00470 note_flds->opt->name = "tag";
00471 note_flds->opt->info = note_insn_name[c];
00472 note_flds->next = old_note_flds;
00473
00474 switch (c)
00475 {
00476
00477
00478 case NOTE_INSN_MAX:
00479 note_flds->opt->name = "default";
00480 note_flds->name = "rt_str";
00481 note_flds->type = &string_type;
00482 break;
00483
00484 case NOTE_INSN_BLOCK_BEG:
00485 case NOTE_INSN_BLOCK_END:
00486 note_flds->name = "rt_tree";
00487 note_flds->type = tree_tp;
00488 break;
00489
00490 case NOTE_INSN_EXPECTED_VALUE:
00491 case NOTE_INSN_VAR_LOCATION:
00492 note_flds->name = "rt_rtx";
00493 note_flds->type = rtx_tp;
00494 break;
00495
00496 default:
00497 note_flds->name = "rt_int";
00498 note_flds->type = scalar_tp;
00499 break;
00500 }
00501 }
00502 new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
00503 }
00504
00505 note_union_tp = find_structure ("rtx_def_note_subunion", 1);
00506
00507 for (i = 0; i < NUM_RTX_CODE; i++)
00508 {
00509 pair_p old_flds = flds;
00510 pair_p subfields = NULL;
00511 size_t aindex, nmindex;
00512 const char *sname;
00513 char *ftag;
00514
00515 for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
00516 {
00517 pair_p old_subf = subfields;
00518 type_p t;
00519 const char *subname;
00520
00521 switch (rtx_format[i][aindex])
00522 {
00523 case '*':
00524 case 'i':
00525 case 'n':
00526 case 'w':
00527 t = scalar_tp;
00528 subname = "rt_int";
00529 break;
00530
00531 case '0':
00532 if (i == MEM && aindex == 1)
00533 t = mem_attrs_tp, subname = "rt_mem";
00534 else if (i == JUMP_INSN && aindex == 9)
00535 t = rtx_tp, subname = "rt_rtx";
00536 else if (i == CODE_LABEL && aindex == 4)
00537 t = scalar_tp, subname = "rt_int";
00538 else if (i == CODE_LABEL && aindex == 5)
00539 t = rtx_tp, subname = "rt_rtx";
00540 else if (i == LABEL_REF
00541 && (aindex == 1 || aindex == 2))
00542 t = rtx_tp, subname = "rt_rtx";
00543 else if (i == NOTE && aindex == 4)
00544 t = note_union_tp, subname = "";
00545 else if (i == NOTE && aindex >= 7)
00546 t = scalar_tp, subname = "rt_int";
00547 else if (i == ADDR_DIFF_VEC && aindex == 4)
00548 t = scalar_tp, subname = "rt_int";
00549 else if (i == VALUE && aindex == 0)
00550 t = scalar_tp, subname = "rt_int";
00551 else if (i == REG && aindex == 1)
00552 t = scalar_tp, subname = "rt_int";
00553 else if (i == REG && aindex == 2)
00554 t = reg_attrs_tp, subname = "rt_reg";
00555 else if (i == SCRATCH && aindex == 0)
00556 t = scalar_tp, subname = "rt_int";
00557 else if (i == SYMBOL_REF && aindex == 1)
00558 t = scalar_tp, subname = "rt_int";
00559 else if (i == SYMBOL_REF && aindex == 2)
00560 t = tree_tp, subname = "rt_tree";
00561 else if (i == BARRIER && aindex >= 3)
00562 t = scalar_tp, subname = "rt_int";
00563 else
00564 {
00565 error_at_line (&lexer_line,
00566 "rtx type `%s' has `0' in position %lu, can't handle",
00567 rtx_name[i], (unsigned long) aindex);
00568 t = &string_type;
00569 subname = "rt_int";
00570 }
00571 break;
00572
00573 case 's':
00574 case 'S':
00575 case 'T':
00576 t = &string_type;
00577 subname = "rt_str";
00578 break;
00579
00580 case 'e':
00581 case 'u':
00582 t = rtx_tp;
00583 subname = "rt_rtx";
00584 break;
00585
00586 case 'E':
00587 case 'V':
00588 t = rtvec_tp;
00589 subname = "rt_rtvec";
00590 break;
00591
00592 case 't':
00593 t = tree_tp;
00594 subname = "rt_tree";
00595 break;
00596
00597 case 'b':
00598 t = bitmap_tp;
00599 subname = "rt_bit";
00600 break;
00601
00602 case 'B':
00603 t = basic_block_tp;
00604 subname = "rt_bb";
00605 break;
00606
00607 default:
00608 error_at_line (&lexer_line,
00609 "rtx type `%s' has `%c' in position %lu, can't handle",
00610 rtx_name[i], rtx_format[i][aindex],
00611 (unsigned long)aindex);
00612 t = &string_type;
00613 subname = "rt_int";
00614 break;
00615 }
00616
00617 subfields = XNEW (struct pair);
00618 subfields->next = old_subf;
00619 subfields->type = t;
00620 subfields->name = xasprintf (".fld[%lu].%s", (unsigned long)aindex,
00621 subname);
00622 subfields->line.file = __FILE__;
00623 subfields->line.line = __LINE__;
00624 if (t == note_union_tp)
00625 {
00626 subfields->opt = XNEW (struct options);
00627 subfields->opt->next = nodot;
00628 subfields->opt->name = "desc";
00629 subfields->opt->info = "NOTE_LINE_NUMBER (&%0)";
00630 }
00631 else if (t == basic_block_tp)
00632 {
00633
00634 subfields->opt = XNEW (struct options);
00635 subfields->opt->next = nodot;
00636 subfields->opt->name = "skip";
00637 subfields->opt->info = NULL;
00638 }
00639 else
00640 subfields->opt = nodot;
00641 }
00642
00643 flds = XNEW (struct pair);
00644 flds->next = old_flds;
00645 flds->name = "";
00646 sname = xasprintf ("rtx_def_%s", rtx_name[i]);
00647 new_structure (sname, 0, &lexer_line, subfields, NULL);
00648 flds->type = find_structure (sname, 0);
00649 flds->line.file = __FILE__;
00650 flds->line.line = __LINE__;
00651 flds->opt = XNEW (struct options);
00652 flds->opt->next = nodot;
00653 flds->opt->name = "tag";
00654 ftag = xstrdup (rtx_name[i]);
00655 for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
00656 ftag[nmindex] = TOUPPER (ftag[nmindex]);
00657 flds->opt->info = ftag;
00658 }
00659
00660 new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
00661 return find_structure ("rtx_def_subunion", 1);
00662 }
00663
00664
00665
00666
00667
00668
00669
00670 static type_p
00671 adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
00672 {
00673 pair_p flds;
00674 options_p nodot;
00675
00676 if (t->kind != TYPE_ARRAY)
00677 {
00678 error_at_line (&lexer_line,
00679 "special `tree_exp' must be applied to an array");
00680 return &string_type;
00681 }
00682
00683 nodot = XNEW (struct options);
00684 nodot->next = NULL;
00685 nodot->name = "dot";
00686 nodot->info = "";
00687
00688 flds = XNEW (struct pair);
00689 flds->next = NULL;
00690 flds->name = "";
00691 flds->type = t;
00692 flds->line.file = __FILE__;
00693 flds->line.line = __LINE__;
00694 flds->opt = XNEW (struct options);
00695 flds->opt->next = nodot;
00696 flds->opt->name = "length";
00697 flds->opt->info = "TREE_CODE_LENGTH (TREE_CODE ((tree) &%0))";
00698 {
00699 options_p oldopt = flds->opt;
00700 flds->opt = XNEW (struct options);
00701 flds->opt->next = oldopt;
00702 flds->opt->name = "default";
00703 flds->opt->info = "";
00704 }
00705
00706 new_structure ("tree_exp_subunion", 1, &lexer_line, flds, nodot);
00707 return find_structure ("tree_exp_subunion", 1);
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 type_p
00721 adjust_field_type (type_p t, options_p opt)
00722 {
00723 int length_p = 0;
00724 const int pointer_p = t->kind == TYPE_POINTER;
00725 type_p params[NUM_PARAM];
00726 int params_p = 0;
00727 int i;
00728
00729 for (i = 0; i < NUM_PARAM; i++)
00730 params[i] = NULL;
00731
00732 for (; opt; opt = opt->next)
00733 if (strcmp (opt->name, "length") == 0)
00734 length_p = 1;
00735 else if (strcmp (opt->name, "param_is") == 0
00736 || (strncmp (opt->name, "param", 5) == 0
00737 && ISDIGIT (opt->name[5])
00738 && strcmp (opt->name + 6, "_is") == 0))
00739 {
00740 int num = ISDIGIT (opt->name[5]) ? opt->name[5] - '0' : 0;
00741
00742 if (! UNION_OR_STRUCT_P (t)
00743 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
00744 {
00745 error_at_line (&lexer_line,
00746 "option `%s' may only be applied to structures or structure pointers",
00747 opt->name);
00748 return t;
00749 }
00750
00751 params_p = 1;
00752 if (params[num] != NULL)
00753 error_at_line (&lexer_line, "duplicate `%s' option", opt->name);
00754 if (! ISDIGIT (opt->name[5]))
00755 params[num] = create_pointer ((type_p) opt->info);
00756 else
00757 params[num] = (type_p) opt->info;
00758 }
00759 else if (strcmp (opt->name, "special") == 0)
00760 {
00761 const char *special_name = opt->info;
00762 if (strcmp (special_name, "tree_exp") == 0)
00763 t = adjust_field_tree_exp (t, opt);
00764 else if (strcmp (special_name, "rtx_def") == 0)
00765 t = adjust_field_rtx_def (t, opt);
00766 else
00767 error_at_line (&lexer_line, "unknown special `%s'", special_name);
00768 }
00769
00770 if (params_p)
00771 {
00772 type_p realt;
00773
00774 if (pointer_p)
00775 t = t->u.p;
00776 realt = find_param_structure (t, params);
00777 t = pointer_p ? create_pointer (realt) : realt;
00778 }
00779
00780 if (! length_p
00781 && pointer_p
00782 && t->u.p->kind == TYPE_SCALAR
00783 && (strcmp (t->u.p->u.sc, "char") == 0
00784 || strcmp (t->u.p->u.sc, "unsigned char") == 0))
00785 return &string_type;
00786 if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
00787 && t->u.a.p->u.p->kind == TYPE_SCALAR
00788 && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
00789 || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
00790 return create_array (&string_type, t->u.a.len);
00791
00792 return t;
00793 }
00794
00795
00796
00797
00798
00799 void
00800 note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
00801 struct fileloc *pos)
00802 {
00803 pair_p p;
00804 pair_p *p_p;
00805
00806 for (p = typeinfo; p; p = p->next)
00807 {
00808 pair_p m;
00809
00810 if (p->name == NULL)
00811 continue;
00812
00813 if (p->type == (type_p) 1)
00814 {
00815 pair_p pp;
00816 int ok = 0;
00817
00818 for (pp = typeinfo; pp; pp = pp->next)
00819 if (pp->type != (type_p) 1
00820 && strcmp (pp->opt->info, p->opt->info) == 0)
00821 {
00822 ok = 1;
00823 break;
00824 }
00825 if (! ok)
00826 continue;
00827 }
00828
00829 for (m = fields; m; m = m->next)
00830 if (strcmp (m->name, p->name) == 0)
00831 p->type = m->type;
00832 if (p->type == NULL)
00833 {
00834 error_at_line (&p->line,
00835 "couldn't match fieldname `%s'", p->name);
00836 p->name = NULL;
00837 }
00838 }
00839
00840 p_p = &typeinfo;
00841 while (*p_p)
00842 {
00843 pair_p p = *p_p;
00844
00845 if (p->name == NULL
00846 || p->type == (type_p) 1)
00847 *p_p = p->next;
00848 else
00849 p_p = &p->next;
00850 }
00851
00852 new_structure ("yy_union", 1, pos, typeinfo, o);
00853 do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
00854 }
00855
00856 static void process_gc_options (options_p, enum gc_used_enum,
00857 int *, int *, int *, type_p *);
00858 static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
00859 static void set_gc_used (pair_p);
00860
00861
00862
00863 static void
00864 process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
00865 int *pass_param, int *length, type_p *nested_ptr)
00866 {
00867 options_p o;
00868 for (o = opt; o; o = o->next)
00869 if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
00870 set_gc_used_type ((type_p) o->info, GC_POINTED_TO, NULL);
00871 else if (strcmp (o->name, "maybe_undef") == 0)
00872 *maybe_undef = 1;
00873 else if (strcmp (o->name, "use_params") == 0)
00874 *pass_param = 1;
00875 else if (strcmp (o->name, "length") == 0)
00876 *length = 1;
00877 else if (strcmp (o->name, "nested_ptr") == 0)
00878 *nested_ptr = ((const struct nested_ptr_data *) o->info)->type;
00879 }
00880
00881
00882
00883 static void
00884 set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
00885 {
00886 if (t->gc_used >= level)
00887 return;
00888
00889 t->gc_used = level;
00890
00891 switch (t->kind)
00892 {
00893 case TYPE_STRUCT:
00894 case TYPE_UNION:
00895 {
00896 pair_p f;
00897 int dummy;
00898 type_p dummy2;
00899
00900 process_gc_options (t->u.s.opt, level, &dummy, &dummy, &dummy,
00901 &dummy2);
00902
00903 for (f = t->u.s.fields; f; f = f->next)
00904 {
00905 int maybe_undef = 0;
00906 int pass_param = 0;
00907 int length = 0;
00908 type_p nested_ptr = NULL;
00909 process_gc_options (f->opt, level, &maybe_undef, &pass_param,
00910 &length, &nested_ptr);
00911
00912 if (nested_ptr && f->type->kind == TYPE_POINTER)
00913 set_gc_used_type (nested_ptr, GC_POINTED_TO,
00914 pass_param ? param : NULL);
00915 else if (length && f->type->kind == TYPE_POINTER)
00916 set_gc_used_type (f->type->u.p, GC_USED, NULL);
00917 else if (maybe_undef && f->type->kind == TYPE_POINTER)
00918 set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO, NULL);
00919 else if (pass_param && f->type->kind == TYPE_POINTER && param)
00920 set_gc_used_type (find_param_structure (f->type->u.p, param),
00921 GC_POINTED_TO, NULL);
00922 else
00923 set_gc_used_type (f->type, GC_USED, pass_param ? param : NULL);
00924 }
00925 break;
00926 }
00927
00928 case TYPE_POINTER:
00929 set_gc_used_type (t->u.p, GC_POINTED_TO, NULL);
00930 break;
00931
00932 case TYPE_ARRAY:
00933 set_gc_used_type (t->u.a.p, GC_USED, param);
00934 break;
00935
00936 case TYPE_LANG_STRUCT:
00937 for (t = t->u.s.lang_struct; t; t = t->next)
00938 set_gc_used_type (t, level, param);
00939 break;
00940
00941 case TYPE_PARAM_STRUCT:
00942 {
00943 int i;
00944 for (i = 0; i < NUM_PARAM; i++)
00945 if (t->u.param_struct.param[i] != 0)
00946 set_gc_used_type (t->u.param_struct.param[i], GC_USED, NULL);
00947 }
00948 if (t->u.param_struct.stru->gc_used == GC_POINTED_TO)
00949 level = GC_POINTED_TO;
00950 else
00951 level = GC_USED;
00952 t->u.param_struct.stru->gc_used = GC_UNUSED;
00953 set_gc_used_type (t->u.param_struct.stru, level,
00954 t->u.param_struct.param);
00955 break;
00956
00957 default:
00958 break;
00959 }
00960 }
00961
00962
00963
00964 static void
00965 set_gc_used (pair_p variables)
00966 {
00967 pair_p p;
00968 for (p = variables; p; p = p->next)
00969 set_gc_used_type (p->type, GC_USED, NULL);
00970 }
00971
00972
00973
00974
00975
00976
00977 static outf_p output_files;
00978
00979
00980
00981 static outf_p header_file;
00982
00983
00984 #define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
00985
00986
00987 #define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
00988
00989
00990 static int srcdir_len = 0;
00991
00992 #define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
00993 outf_p base_files[NUM_BASE_FILES];
00994
00995 static outf_p create_file (const char *, const char *);
00996 static const char * get_file_basename (const char *);
00997
00998
00999
01000
01001 static outf_p
01002 create_file (const char *name, const char *oname)
01003 {
01004 static const char *const hdr[] = {
01005 " Copyright (C) 2004 Free Software Foundation, Inc.\n",
01006 "\n",
01007 "This file is part of GCC.\n",
01008 "\n",
01009 "GCC is free software; you can redistribute it and/or modify it under\n",
01010 "the terms of the GNU General Public License as published by the Free\n",
01011 "Software Foundation; either version 2, or (at your option) any later\n",
01012 "version.\n",
01013 "\n",
01014 "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
01015 "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
01016 "FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n",
01017 "for more details.\n",
01018 "\n",
01019 "You should have received a copy of the GNU General Public License\n",
01020 "along with GCC; see the file COPYING. If not, write to the Free\n",
01021 "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
01022 "02111-1307, USA. */\n",
01023 "\n",
01024 "/* This file is machine generated. Do not edit. */\n"
01025 };
01026 outf_p f;
01027 size_t i;
01028
01029 f = XCNEW (struct outf);
01030 f->next = output_files;
01031 f->name = oname;
01032 output_files = f;
01033
01034 oprintf (f, "/* Type information for %s.\n", name);
01035 for (i = 0; i < ARRAY_SIZE (hdr); i++)
01036 oprintf (f, "%s", hdr[i]);
01037 return f;
01038 }
01039
01040
01041 void
01042 oprintf (outf_p o, const char *format, ...)
01043 {
01044 char *s;
01045 size_t slength;
01046 va_list ap;
01047
01048 va_start (ap, format);
01049 slength = xvasprintf (&s, format, ap);
01050
01051 if (o->bufused + slength > o->buflength)
01052 {
01053 size_t new_len = o->buflength;
01054 if (new_len == 0)
01055 new_len = 1024;
01056 do {
01057 new_len *= 2;
01058 } while (o->bufused + slength >= new_len);
01059 o->buf = XRESIZEVEC (char, o->buf, new_len);
01060 o->buflength = new_len;
01061 }
01062 memcpy (o->buf + o->bufused, s, slength);
01063 o->bufused += slength;
01064 free (s);
01065 va_end (ap);
01066 }
01067
01068
01069
01070 static void
01071 open_base_files (void)
01072 {
01073 size_t i;
01074
01075 header_file = create_file ("GCC", "gtype-desc.h");
01076
01077 for (i = 0; i < NUM_BASE_FILES; i++)
01078 base_files[i] = create_file (lang_dir_names[i],
01079 xasprintf ("gtype-%s.h", lang_dir_names[i]));
01080
01081
01082 {
01083
01084 static const char *const ifiles [] = {
01085 "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
01086 "hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
01087 "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
01088 "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
01089 "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
01090 "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
01091 NULL
01092 };
01093 const char *const *ifp;
01094 outf_p gtype_desc_c;
01095
01096 gtype_desc_c = create_file ("GCC", "gtype-desc.c");
01097 for (ifp = ifiles; *ifp; ifp++)
01098 oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
01099 }
01100 }
01101
01102
01103
01104 static const char *
01105 get_file_basename (const char *f)
01106 {
01107 const char *basename;
01108 unsigned i;
01109
01110 basename = strrchr (f, '/');
01111
01112 if (!basename)
01113 return f;
01114
01115 basename++;
01116
01117 for (i = 1; i < NUM_BASE_FILES; i++)
01118 {
01119 const char * s1;
01120 const char * s2;
01121 int l1;
01122 int l2;
01123 s1 = basename - strlen (lang_dir_names [i]) - 1;
01124 s2 = lang_dir_names [i];
01125 l1 = strlen (s1);
01126 l2 = strlen (s2);
01127 if (l1 >= l2 && IS_DIR_SEPARATOR (s1[-1]) && !memcmp (s1, s2, l2))
01128 {
01129 basename -= l2 + 1;
01130 if ((basename - f - 1) != srcdir_len)
01131 fatal ("filename `%s' should be preceded by $srcdir", f);
01132 break;
01133 }
01134 }
01135
01136 return basename;
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 unsigned
01148 get_base_file_bitmap (const char *input_file)
01149 {
01150 const char *basename = get_file_basename (input_file);
01151 const char *slashpos = strchr (basename, '/');
01152 unsigned j;
01153 unsigned k;
01154 unsigned bitmap;
01155
01156
01157
01158
01159
01160 if (slashpos)
01161 {
01162 size_t i;
01163 for (i = 1; i < NUM_BASE_FILES; i++)
01164 if ((size_t)(slashpos - basename) == strlen (lang_dir_names [i])
01165 && memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0)
01166 {
01167
01168 bitmap = 1 << i;
01169 }
01170 }
01171
01172
01173
01174
01175 bitmap = 0;
01176
01177 for (j = 0; j < NUM_LANG_FILES; j++)
01178 {
01179 if (!strcmp(input_file, lang_files[j]))
01180 {
01181 for (k = 0; k < NUM_BASE_FILES; k++)
01182 {
01183 if (!strcmp(lang_dir_names[k], langs_for_lang_files[j]))
01184 bitmap |= (1 << k);
01185 }
01186 }
01187 }
01188
01189
01190 if (!bitmap)
01191 bitmap = (1 << NUM_BASE_FILES) - 1;
01192
01193 return bitmap;
01194 }
01195
01196
01197
01198
01199
01200 outf_p
01201 get_output_file_with_visibility (const char *input_file)
01202 {
01203 outf_p r;
01204 size_t len;
01205 const char *basename;
01206 const char *for_name;
01207 const char *output_name;
01208
01209
01210
01211
01212 if (input_file == NULL)
01213 input_file = "system.h";
01214
01215
01216 basename = get_file_basename (input_file);
01217
01218 len = strlen (basename);
01219 if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
01220 || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
01221 || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
01222 {
01223 char *s;
01224
01225 output_name = s = xasprintf ("gt-%s", basename);
01226 for (; *s != '.'; s++)
01227 if (! ISALNUM (*s) && *s != '-')
01228 *s = '-';
01229 memcpy (s, ".h", sizeof (".h"));
01230 for_name = basename;
01231 }
01232
01233
01234
01235
01236
01237 else if (strcmp (basename, "c-common.h") == 0)
01238 output_name = "gt-c-common.h", for_name = "c-common.c";
01239 else if (strcmp (basename, "c-tree.h") == 0)
01240 output_name = "gt-c-decl.h", for_name = "c-decl.c";
01241 else if (strncmp (basename, "objc", 4) == 0 && IS_DIR_SEPARATOR (basename[4])
01242 && strcmp (basename + 5, "objc-act.h") == 0)
01243 output_name = "gt-objc-objc-act.h", for_name = "objc/objc-act.c";
01244 else
01245 {
01246 size_t i;
01247
01248 for (i = 0; i < NUM_BASE_FILES; i++)
01249 if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
01250 && basename[strlen(lang_dir_names[i])] == '/')
01251 return base_files[i];
01252
01253 output_name = "gtype-desc.c";
01254 for_name = NULL;
01255 }
01256
01257
01258 for (r = output_files; r; r = r->next)
01259 if (strcmp (r->name, output_name) == 0)
01260 return r;
01261
01262
01263 r = create_file (for_name, output_name);
01264
01265 return r;
01266 }
01267
01268
01269
01270
01271
01272 const char *
01273 get_output_file_name (const char *input_file)
01274 {
01275 return get_output_file_with_visibility (input_file)->name;
01276 }
01277
01278
01279
01280
01281 static void
01282 close_output_files (void)
01283 {
01284 outf_p of;
01285
01286 for (of = output_files; of; of = of->next)
01287 {
01288 FILE * newfile;
01289
01290 newfile = fopen (of->name, "r");
01291 if (newfile != NULL )
01292 {
01293 int no_write_p;
01294 size_t i;
01295
01296 for (i = 0; i < of->bufused; i++)
01297 {
01298 int ch;
01299 ch = fgetc (newfile);
01300 if (ch == EOF || ch != (unsigned char) of->buf[i])
01301 break;
01302 }
01303 no_write_p = i == of->bufused && fgetc (newfile) == EOF;
01304 fclose (newfile);
01305
01306 if (no_write_p)
01307 continue;
01308 }
01309
01310 newfile = fopen (of->name, "w");
01311 if (newfile == NULL)
01312 {
01313 perror ("opening output file");
01314 exit (1);
01315 }
01316 if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
01317 {
01318 perror ("writing output file");
01319 exit (1);
01320 }
01321 if (fclose (newfile) != 0)
01322 {
01323 perror ("closing output file");
01324 exit (1);
01325 }
01326 }
01327 }
01328
01329 struct flist {
01330 struct flist *next;
01331 int started_p;
01332 const char *name;
01333 outf_p f;
01334 };
01335
01336 struct walk_type_data;
01337
01338
01339
01340
01341
01342 typedef void (*process_field_fn)
01343 (type_p f, const struct walk_type_data *p);
01344 typedef void (*func_name_fn)
01345 (type_p s, const struct walk_type_data *p);
01346
01347
01348
01349 struct write_types_data
01350 {
01351 const char *prefix;
01352 const char *param_prefix;
01353 const char *subfield_marker_routine;
01354 const char *marker_routine;
01355 const char *reorder_note_routine;
01356 const char *comment;
01357 };
01358
01359 static void output_escaped_param (struct walk_type_data *d,
01360 const char *, const char *);
01361 static void output_mangled_typename (outf_p, type_p);
01362 static void walk_type (type_p t, struct walk_type_data *d);
01363 static void write_func_for_structure
01364 (type_p orig_s, type_p s, type_p * param,
01365 const struct write_types_data *wtd);
01366 static void write_types_process_field
01367 (type_p f, const struct walk_type_data *d);
01368 static void write_types (type_p structures,
01369 type_p param_structs,
01370 const struct write_types_data *wtd);
01371 static void write_types_local_process_field
01372 (type_p f, const struct walk_type_data *d);
01373 static void write_local_func_for_structure
01374 (type_p orig_s, type_p s, type_p * param);
01375 static void write_local (type_p structures,
01376 type_p param_structs);
01377 static void write_enum_defn (type_p structures, type_p param_structs);
01378 static int contains_scalar_p (type_p t);
01379 static void put_mangled_filename (outf_p , const char *);
01380 static void finish_root_table (struct flist *flp, const char *pfx,
01381 const char *tname, const char *lastname,
01382 const char *name);
01383 static void write_root (outf_p , pair_p, type_p, const char *, int,
01384 struct fileloc *, const char *);
01385 static void write_array (outf_p f, pair_p v,
01386 const struct write_types_data *wtd);
01387 static void write_roots (pair_p);
01388
01389
01390
01391 struct walk_type_data
01392 {
01393 process_field_fn process_field;
01394 const void *cookie;
01395 outf_p of;
01396 options_p opt;
01397 const char *val;
01398 const char *prev_val[4];
01399 int indent;
01400 int counter;
01401 struct fileloc *line;
01402 lang_bitmap bitmap;
01403 type_p *param;
01404 int used_length;
01405 type_p orig_s;
01406 const char *reorder_fn;
01407 bool needs_cast_p;
01408 bool fn_wants_lvalue;
01409 };
01410
01411
01412
01413 static void
01414 output_mangled_typename (outf_p of, type_p t)
01415 {
01416 if (t == NULL)
01417 oprintf (of, "Z");
01418 else switch (t->kind)
01419 {
01420 case TYPE_POINTER:
01421 oprintf (of, "P");
01422 output_mangled_typename (of, t->u.p);
01423 break;
01424 case TYPE_SCALAR:
01425 oprintf (of, "I");
01426 break;
01427 case TYPE_STRING:
01428 oprintf (of, "S");
01429 break;
01430 case TYPE_STRUCT:
01431 case TYPE_UNION:
01432 case TYPE_LANG_STRUCT:
01433 oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag), t->u.s.tag);
01434 break;
01435 case TYPE_PARAM_STRUCT:
01436 {
01437 int i;
01438 for (i = 0; i < NUM_PARAM; i++)
01439 if (t->u.param_struct.param[i] != NULL)
01440 output_mangled_typename (of, t->u.param_struct.param[i]);
01441 output_mangled_typename (of, t->u.param_struct.stru);
01442 }
01443 break;
01444 case TYPE_ARRAY:
01445 gcc_unreachable ();
01446 }
01447 }
01448
01449
01450
01451
01452
01453
01454 static void
01455 output_escaped_param (struct walk_type_data *d, const char *param,
01456 const char *oname)
01457 {
01458 const char *p;
01459
01460 for (p = param; *p; p++)
01461 if (*p != '%')
01462 oprintf (d->of, "%c", *p);
01463 else switch (*++p)
01464 {
01465 case 'h':
01466 oprintf (d->of, "(%s)", d->prev_val[2]);
01467 break;
01468 case '0':
01469 oprintf (d->of, "(%s)", d->prev_val[0]);
01470 break;
01471 case '1':
01472 oprintf (d->of, "(%s)", d->prev_val[1]);
01473 break;
01474 case 'a':
01475 {
01476 const char *pp = d->val + strlen (d->val);
01477 while (pp[-1] == ']')
01478 while (*pp != '[')
01479 pp--;
01480 oprintf (d->of, "%s", pp);
01481 }
01482 break;
01483 default:
01484 error_at_line (d->line, "`%s' option contains bad escape %c%c",
01485 oname, '%', *p);
01486 }
01487 }
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500 static void
01501 walk_type (type_p t, struct walk_type_data *d)
01502 {
01503 const char *length = NULL;
01504 const char *desc = NULL;
01505 int maybe_undef_p = 0;
01506 int use_param_num = -1;
01507 int use_params_p = 0;
01508 options_p oo;
01509 const struct nested_ptr_data *nested_ptr_d = NULL;
01510
01511 d->needs_cast_p = false;
01512 for (oo = d->opt; oo; oo = oo->next)
01513 if (strcmp (oo->name, "length") == 0)
01514 length = oo->info;
01515 else if (strcmp (oo->name, "maybe_undef") == 0)
01516 maybe_undef_p = 1;
01517 else if (strncmp (oo->name, "use_param", 9) == 0
01518 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
01519 use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
01520 else if (strcmp (oo->name, "use_params") == 0)
01521 use_params_p = 1;
01522 else if (strcmp (oo->name, "desc") == 0)
01523 desc = oo->info;
01524 else if (strcmp (oo->name, "nested_ptr") == 0)
01525 nested_ptr_d = (const struct nested_ptr_data *) oo->info;
01526 else if (strcmp (oo->name, "dot") == 0)
01527 ;
01528 else if (strcmp (oo->name, "tag") == 0)
01529 ;
01530 else if (strcmp (oo->name, "special") == 0)
01531 ;
01532 else if (strcmp (oo->name, "skip") == 0)
01533 ;
01534 else if (strcmp (oo->name, "default") == 0)
01535 ;
01536 else if (strcmp (oo->name, "descbits") == 0)
01537 ;
01538 else if (strcmp (oo->name, "param_is") == 0)
01539 ;
01540 else if (strncmp (oo->name, "param", 5) == 0
01541 && ISDIGIT (oo->name[5])
01542 && strcmp (oo->name + 6, "_is") == 0)
01543 ;
01544 else if (strcmp (oo->name, "chain_next") == 0)
01545 ;
01546 else if (strcmp (oo->name, "chain_prev") == 0)
01547 ;
01548 else if (strcmp (oo->name, "reorder") == 0)
01549 ;
01550 else
01551 error_at_line (d->line, "unknown option `%s'\n", oo->name);
01552
01553 if (d->used_length)
01554 length = NULL;
01555
01556 if (use_params_p)
01557 {
01558 int pointer_p = t->kind == TYPE_POINTER;
01559
01560 if (pointer_p)
01561 t = t->u.p;
01562 if (! UNION_OR_STRUCT_P (t))
01563 error_at_line (d->line, "`use_params' option on unimplemented type");
01564 else
01565 t = find_param_structure (t, d->param);
01566 if (pointer_p)
01567 t = create_pointer (t);
01568 }
01569
01570 if (use_param_num != -1)
01571 {
01572 if (d->param != NULL && d->param[use_param_num] != NULL)
01573 {
01574 type_p nt = d->param[use_param_num];
01575
01576 if (t->kind == TYPE_ARRAY)
01577 nt = create_array (nt, t->u.a.len);
01578 else if (length != NULL && t->kind == TYPE_POINTER)
01579 nt = create_pointer (nt);
01580 d->needs_cast_p = (t->kind != TYPE_POINTER
01581 && (nt->kind == TYPE_POINTER
01582 || nt->kind == TYPE_STRING));
01583 t = nt;
01584 }
01585 else
01586 error_at_line (d->line, "no parameter defined for `%s'",
01587 d->val);
01588 }
01589
01590 if (maybe_undef_p
01591 && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
01592 {
01593 error_at_line (d->line,
01594 "field `%s' has invalid option `maybe_undef_p'\n",
01595 d->val);
01596 return;
01597 }
01598
01599 switch (t->kind)
01600 {
01601 case TYPE_SCALAR:
01602 case TYPE_STRING:
01603 d->process_field (t, d);
01604 break;
01605
01606 case TYPE_POINTER:
01607 {
01608 if (maybe_undef_p
01609 && t->u.p->u.s.line.file == NULL)
01610 {
01611 oprintf (d->of, "%*sgcc_assert (!%s);\n", d->indent, "", d->val);
01612 break;
01613 }
01614
01615 if (! length)
01616 {
01617 if (! UNION_OR_STRUCT_P (t->u.p)
01618 && t->u.p->kind != TYPE_PARAM_STRUCT)
01619 {
01620 error_at_line (d->line,
01621 "field `%s' is pointer to unimplemented type",
01622 d->val);
01623 break;
01624 }
01625
01626 if (nested_ptr_d)
01627 {
01628 const char *oldprevval2 = d->prev_val[2];
01629
01630 if (! UNION_OR_STRUCT_P (nested_ptr_d->type))
01631 {
01632 error_at_line (d->line,
01633 "field `%s' has invalid "
01634 "option `nested_ptr'\n",
01635 d->val);
01636 return;
01637 }
01638
01639 d->prev_val[2] = d->val;
01640 oprintf (d->of, "%*s{\n", d->indent, "");
01641 d->indent += 2;
01642 d->val = xasprintf ("x%d", d->counter++);
01643 oprintf (d->of, "%*s%s %s * %s%s =\n", d->indent, "",
01644 (nested_ptr_d->type->kind == TYPE_UNION
01645 ? "union" : "struct"),
01646 nested_ptr_d->type->u.s.tag,
01647 d->fn_wants_lvalue ? "" : "const ",
01648 d->val);
01649 oprintf (d->of, "%*s", d->indent + 2, "");
01650 output_escaped_param (d, nested_ptr_d->convert_from,
01651 "nested_ptr");
01652 oprintf (d->of, ";\n");
01653
01654 d->process_field (nested_ptr_d->type, d);
01655
01656 if (d->fn_wants_lvalue)
01657 {
01658 oprintf (d->of, "%*s%s = ", d->indent, "",
01659 d->prev_val[2]);
01660 d->prev_val[2] = d->val;
01661 output_escaped_param (d, nested_ptr_d->convert_to,
01662 "nested_ptr");
01663 oprintf (d->of, ";\n");
01664 }
01665
01666 d->indent -= 2;
01667 oprintf (d->of, "%*s}\n", d->indent, "");
01668 d->val = d->prev_val[2];
01669 d->prev_val[2] = oldprevval2;
01670 }
01671 else
01672 d->process_field (t->u.p, d);
01673 }
01674 else
01675 {
01676 int loopcounter = d->counter++;
01677 const char *oldval = d->val;
01678 const char *oldprevval3 = d->prev_val[3];
01679 char *newval;
01680
01681 oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
01682 d->indent += 2;
01683 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
01684 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
01685 loopcounter, loopcounter);
01686 output_escaped_param (d, length, "length");
01687 oprintf (d->of, "); i%d++) {\n", loopcounter);
01688 d->indent += 2;
01689 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
01690 d->used_length = 1;
01691 d->prev_val[3] = oldval;
01692 walk_type (t->u.p, d);
01693 free (newval);
01694 d->val = oldval;
01695 d->prev_val[3] = oldprevval3;
01696 d->used_length = 0;
01697 d->indent -= 2;
01698 oprintf (d->of, "%*s}\n", d->indent, "");
01699 d->process_field(t, d);
01700 d->indent -= 2;
01701 oprintf (d->of, "%*s}\n", d->indent, "");
01702 }
01703 }
01704 break;
01705
01706 case TYPE_ARRAY:
01707 {
01708 int loopcounter = d->counter++;
01709 const char *oldval = d->val;
01710 char *newval;
01711
01712
01713
01714 if (t->u.a.p->kind == TYPE_SCALAR)
01715 break;
01716
01717 oprintf (d->of, "%*s{\n", d->indent, "");
01718 d->indent += 2;
01719 oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
01720 oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, "",
01721 loopcounter, loopcounter);
01722 if (length)
01723 output_escaped_param (d, length, "length");
01724 else
01725 oprintf (d->of, "%s", t->u.a.len);
01726 oprintf (d->of, "); i%d++) {\n", loopcounter);
01727 d->indent += 2;
01728 d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
01729 d->used_length = 1;
01730 walk_type (t->u.a.p, d);
01731 free (newval);
01732 d->used_length = 0;
01733 d->val = oldval;
01734 d->indent -= 2;
01735 oprintf (d->of, "%*s}\n", d->indent, "");
01736 d->indent -= 2;
01737 oprintf (d->of, "%*s}\n", d->indent, "");
01738 }
01739 break;
01740
01741 case TYPE_STRUCT:
01742 case TYPE_UNION:
01743 {
01744 pair_p f;
01745 const char *oldval = d->val;
01746 const char *oldprevval1 = d->prev_val[1];
01747 const char *oldprevval2 = d->prev_val[2];
01748 const int union_p = t->kind == TYPE_UNION;
01749 int seen_default_p = 0;
01750 options_p o;
01751
01752 if (! t->u.s.line.file)
01753 error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
01754
01755 if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
01756 {
01757 error_at_line (d->line,
01758 "structure `%s' defined for mismatching languages",
01759 t->u.s.tag);
01760 error_at_line (&t->u.s.line, "one structure defined here");
01761 }
01762
01763
01764 for (o = t->u.s.opt; o; o = o->next)
01765 if (! desc && strcmp (o->name, "desc") == 0)
01766 desc = o->info;
01767
01768 d->prev_val[2] = oldval;
01769 d->prev_val[1] = oldprevval2;
01770 if (union_p)
01771 {
01772 if (desc == NULL)
01773 {
01774 error_at_line (d->line, "missing `desc' option for union `%s'",
01775 t->u.s.tag);
01776 desc = "1";
01777 }
01778 oprintf (d->of, "%*sswitch (", d->indent, "");
01779 output_escaped_param (d, desc, "desc");
01780 oprintf (d->of, ")\n");
01781 d->indent += 2;
01782 oprintf (d->of, "%*s{\n", d->indent, "");
01783 }
01784 for (f = t->u.s.fields; f; f = f->next)
01785 {
01786 options_p oo;
01787 const char *dot = ".";
01788 const char *tagid = NULL;
01789 int skip_p = 0;
01790 int default_p = 0;
01791 int use_param_p = 0;
01792 char *newval;
01793
01794 d->reorder_fn = NULL;
01795 for (oo = f->opt; oo; oo = oo->next)
01796 if (strcmp (oo->name, "dot") == 0)
01797 dot = oo->info;
01798 else if (strcmp (oo->name, "tag") == 0)
01799 tagid = oo->info;
01800 else if (strcmp (oo->name, "skip") == 0)
01801 skip_p = 1;
01802 else if (strcmp (oo->name, "default") == 0)
01803 default_p = 1;
01804 else if (strcmp (oo->name, "reorder") == 0)
01805 d->reorder_fn = oo->info;
01806 else if (strncmp (oo->name, "use_param", 9) == 0
01807 && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
01808 use_param_p = 1;
01809
01810 if (skip_p)
01811 continue;
01812
01813 if (union_p && tagid)
01814 {
01815 oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
01816 d->indent += 2;
01817 }
01818 else if (union_p && default_p)
01819 {
01820 oprintf (d->of, "%*sdefault:\n", d->indent, "");
01821 d->indent += 2;
01822 seen_default_p = 1;
01823 }
01824 else if (! union_p && (default_p || tagid))
01825 error_at_line (d->line,
01826 "can't use `%s' outside a union on field `%s'",
01827 default_p ? "default" : "tag", f->name);
01828 else if (union_p && ! (default_p || tagid)
01829 && f->type->kind == TYPE_SCALAR)
01830 {
01831 fprintf (stderr,
01832 "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
01833 d->line->file, d->line->line, f->name);
01834 continue;
01835 }
01836 else if (union_p && ! (default_p || tagid))
01837 error_at_line (d->line,
01838 "field `%s' is missing `tag' or `default' option",
01839 f->name);
01840
01841 d->line = &f->line;
01842 d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
01843 d->opt = f->opt;
01844 d->used_length = false;
01845
01846 if (union_p && use_param_p && d->param == NULL)
01847 oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
01848 else
01849 walk_type (f->type, d);
01850
01851 free (newval);
01852
01853 if (union_p)
01854 {
01855 oprintf (d->of, "%*sbreak;\n", d->indent, "");
01856 d->indent -= 2;
01857 }
01858 }
01859 d->reorder_fn = NULL;
01860
01861 d->val = oldval;
01862 d->prev_val[1] = oldprevval1;
01863 d->prev_val[2] = oldprevval2;
01864
01865 if (union_p && ! seen_default_p)
01866 {
01867 oprintf (d->of, "%*sdefault:\n", d->indent, "");
01868 oprintf (d->of, "%*s break;\n", d->indent, "");
01869 }
01870 if (union_p)
01871 {
01872 oprintf (d->of, "%*s}\n", d->indent, "");
01873 d->indent -= 2;
01874 }
01875 }
01876 break;
01877
01878 case TYPE_LANG_STRUCT:
01879 {
01880 type_p nt;
01881 for (nt = t->u.s.lang_struct; nt; nt = nt->next)
01882 if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
01883 break;
01884 if (nt == NULL)
01885 error_at_line (d->line, "structure `%s' differs between languages",
01886 t->u.s.tag);
01887 else
01888 walk_type (nt, d);
01889 }
01890 break;
01891
01892 case TYPE_PARAM_STRUCT:
01893 {
01894 type_p *oldparam = d->param;
01895
01896 d->param = t->u.param_struct.param;
01897 walk_type (t->u.param_struct.stru, d);
01898 d->param = oldparam;
01899 }
01900 break;
01901
01902 default:
01903 gcc_unreachable ();
01904 }
01905 }
01906
01907
01908
01909 static void
01910 write_types_process_field (type_p f, const struct walk_type_data *d)
01911 {
01912 const struct write_types_data *wtd;
01913 const char *cast = d->needs_cast_p ? "(void *)" : "";
01914 wtd = (const struct write_types_data *) d->cookie;
01915
01916 switch (f->kind)
01917 {
01918 case TYPE_POINTER:
01919 oprintf (d->of, "%*s%s (%s%s", d->indent, "",
01920 wtd->subfield_marker_routine, cast, d->val);
01921 if (wtd->param_prefix)
01922 {
01923 oprintf (d->of, ", %s", d->prev_val[3]);
01924 if (d->orig_s)
01925 {
01926 oprintf (d->of, ", gt_%s_", wtd->param_prefix);
01927 output_mangled_typename (d->of, d->orig_s);
01928 }
01929 else
01930 oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
01931 }
01932 oprintf (d->of, ");\n");
01933 if (d->reorder_fn && wtd->reorder_note_routine)
01934 oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
01935 wtd->reorder_note_routine, cast, d->val,
01936 d->prev_val[3], d->reorder_fn);
01937 break;
01938
01939 case TYPE_STRING:
01940 if (wtd->param_prefix == NULL)
01941 break;
01942
01943 case TYPE_STRUCT:
01944 case TYPE_UNION:
01945 case TYPE_LANG_STRUCT:
01946 case TYPE_PARAM_STRUCT:
01947 oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
01948 output_mangled_typename (d->of, f);
01949 oprintf (d->of, " (%s%s);\n", cast, d->val);
01950 if (d->reorder_fn && wtd->reorder_note_routine)
01951 oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
01952 wtd->reorder_note_routine, cast, d->val, cast, d->val,
01953 d->reorder_fn);
01954 break;
01955
01956 case TYPE_SCALAR:
01957 break;
01958
01959 default:
01960 gcc_unreachable ();
01961 }
01962 }
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972 static void
01973 write_func_for_structure (type_p orig_s, type_p s, type_p *param,
01974 const struct write_types_data *wtd)
01975 {
01976 const char *fn = s->u.s.line.file;
01977 int i;
01978 const char *chain_next = NULL;
01979 const char *chain_prev = NULL;
01980 options_p opt;
01981 struct walk_type_data d;
01982
01983
01984 for (i = NUM_PARAM - 1; i >= 0; i--)
01985 if (param && param[i] && param[i]->kind == TYPE_POINTER
01986 && UNION_OR_STRUCT_P (param[i]->u.p))
01987 fn = param[i]->u.p->u.s.line.file;
01988
01989 memset (&d, 0, sizeof (d));
01990 d.of = get_output_file_with_visibility (fn);
01991
01992 for (opt = s->u.s.opt; opt; opt = opt->next)
01993 if (strcmp (opt->name, "chain_next") == 0)
01994 chain_next = opt->info;
01995 else if (strcmp (opt->name, "chain_prev") == 0)
01996 chain_prev = opt->info;
01997
01998 if (chain_prev != NULL && chain_next == NULL)
01999 error_at_line (&s->u.s.line, "chain_prev without chain_next");
02000
02001 d.process_field = write_types_process_field;
02002 d.cookie = wtd;
02003 d.orig_s = orig_s;
02004 d.opt = s->u.s.opt;
02005 d.line = &s->u.s.line;
02006 d.bitmap = s->u.s.bitmap;
02007 d.param = param;
02008 d.prev_val[0] = "*x";
02009 d.prev_val[1] = "not valid postage";
02010 d.prev_val[3] = "x";
02011 d.val = "(*x)";
02012
02013 oprintf (d.of, "\n");
02014 oprintf (d.of, "void\n");
02015 if (param == NULL)
02016 oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
02017 else
02018 {
02019 oprintf (d.of, "gt_%s_", wtd->prefix);
02020 output_mangled_typename (d.of, orig_s);
02021 }
02022 oprintf (d.of, " (void *x_p)\n");
02023 oprintf (d.of, "{\n");
02024 oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
02025 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
02026 chain_next == NULL ? "const " : "",
02027 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
02028 if (chain_next != NULL)
02029 oprintf (d.of, " %s %s * xlimit = x;\n",
02030 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
02031 if (chain_next == NULL)
02032 {
02033 oprintf (d.of, " if (%s (x", wtd->marker_routine);
02034 if (wtd->param_prefix)
02035 {
02036 oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
02037 output_mangled_typename (d.of, orig_s);
02038 }
02039 oprintf (d.of, "))\n");
02040 }
02041 else
02042 {
02043 oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
02044 if (wtd->param_prefix)
02045 {
02046 oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
02047 output_mangled_typename (d.of, orig_s);
02048 }
02049 oprintf (d.of, "))\n");
02050 oprintf (d.of, " xlimit = (");
02051 d.prev_val[2] = "*xlimit";
02052 output_escaped_param (&d, chain_next, "chain_next");
02053 oprintf (d.of, ");\n");
02054 if (chain_prev != NULL)
02055 {
02056 oprintf (d.of, " if (x != xlimit)\n");
02057 oprintf (d.of, " for (;;)\n");
02058 oprintf (d.of, " {\n");
02059 oprintf (d.of, " %s %s * const xprev = (",
02060 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
02061
02062 d.prev_val[2] = "*x";
02063 output_escaped_param (&d, chain_prev, "chain_prev");
02064 oprintf (d.of, ");\n");
02065 oprintf (d.of, " if (xprev == NULL) break;\n");
02066 oprintf (d.of, " x = xprev;\n");
02067 oprintf (d.of, " (void) %s (xprev",
02068 wtd->marker_routine);
02069 if (wtd->param_prefix)
02070 {
02071 oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
02072 output_mangled_typename (d.of, orig_s);
02073 }
02074 oprintf (d.of, ");\n");
02075 oprintf (d.of, " }\n");
02076 }
02077 oprintf (d.of, " while (x != xlimit)\n");
02078 }
02079 oprintf (d.of, " {\n");
02080
02081 d.prev_val[2] = "*x";
02082 d.indent = 6;
02083 walk_type (s, &d);
02084
02085 if (chain_next != NULL)
02086 {
02087 oprintf (d.of, " x = (");
02088 output_escaped_param (&d, chain_next, "chain_next");
02089 oprintf (d.of, ");\n");
02090 }
02091
02092 oprintf (d.of, " }\n");
02093 oprintf (d.of, "}\n");
02094 }
02095
02096
02097
02098 static void
02099 write_types (type_p structures, type_p param_structs,
02100 const struct write_types_data *wtd)
02101 {
02102 type_p s;
02103
02104 oprintf (header_file, "\n/* %s*/\n", wtd->comment);
02105 for (s = structures; s; s = s->next)
02106 if (s->gc_used == GC_POINTED_TO
02107 || s->gc_used == GC_MAYBE_POINTED_TO)
02108 {
02109 options_p opt;
02110
02111 if (s->gc_used == GC_MAYBE_POINTED_TO
02112 && s->u.s.line.file == NULL)
02113 continue;
02114
02115 oprintf (header_file, "#define gt_%s_", wtd->prefix);
02116 output_mangled_typename (header_file, s);
02117 oprintf (header_file, "(X) do { \\\n");
02118 oprintf (header_file,
02119 " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
02120 s->u.s.tag);
02121 oprintf (header_file,
02122 " } while (0)\n");
02123
02124 for (opt = s->u.s.opt; opt; opt = opt->next)
02125 if (strcmp (opt->name, "ptr_alias") == 0)
02126 {
02127 type_p t = (type_p) opt->info;
02128 if (t->kind == TYPE_STRUCT
02129 || t->kind == TYPE_UNION
02130 || t->kind == TYPE_LANG_STRUCT)
02131 oprintf (header_file,
02132 "#define gt_%sx_%s gt_%sx_%s\n",
02133 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
02134 else
02135 error_at_line (&s->u.s.line,
02136 "structure alias is not a structure");
02137 break;
02138 }
02139 if (opt)
02140 continue;
02141
02142
02143 oprintf (header_file,
02144 "extern void gt_%sx_%s (void *);\n",
02145 wtd->prefix, s->u.s.tag);
02146
02147 if (s->u.s.line.file == NULL)
02148 {
02149 fprintf (stderr, "warning: structure `%s' used but not defined\n",
02150 s->u.s.tag);
02151 continue;
02152 }
02153
02154 if (s->kind == TYPE_LANG_STRUCT)
02155 {
02156 type_p ss;
02157 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
02158 write_func_for_structure (s, ss, NULL, wtd);
02159 }
02160 else
02161 write_func_for_structure (s, s, NULL, wtd);
02162 }
02163
02164 for (s = param_structs; s; s = s->next)
02165 if (s->gc_used == GC_POINTED_TO)
02166 {
02167 type_p * param = s->u.param_struct.param;
02168 type_p stru = s->u.param_struct.stru;
02169
02170
02171 oprintf (header_file, "extern void gt_%s_", wtd->prefix);
02172 output_mangled_typename (header_file, s);
02173 oprintf (header_file, " (void *);\n");
02174
02175 if (stru->u.s.line.file == NULL)
02176 {
02177 fprintf (stderr, "warning: structure `%s' used but not defined\n",
02178 s->u.s.tag);
02179 continue;
02180 }
02181
02182 if (stru->kind == TYPE_LANG_STRUCT)
02183 {
02184 type_p ss;
02185 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
02186 write_func_for_structure (s, ss, param, wtd);
02187 }
02188 else
02189 write_func_for_structure (s, stru, param, wtd);
02190 }
02191 }
02192
02193 static const struct write_types_data ggc_wtd =
02194 {
02195 "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
02196 "GC marker procedures. "
02197 };
02198
02199 static const struct write_types_data pch_wtd =
02200 {
02201 "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
02202 "gt_pch_note_reorder",
02203 "PCH type-walking procedures. "
02204 };
02205
02206
02207
02208
02209
02210 static void
02211 write_types_local_process_field (type_p f, const struct walk_type_data *d)
02212 {
02213 switch (f->kind)
02214 {
02215 case TYPE_POINTER:
02216 case TYPE_STRUCT:
02217 case TYPE_UNION:
02218 case TYPE_LANG_STRUCT:
02219 case TYPE_PARAM_STRUCT:
02220 case TYPE_STRING:
02221 oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
02222 d->prev_val[3]);
02223 oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
02224 break;
02225
02226 case TYPE_SCALAR:
02227 break;
02228
02229 default:
02230 gcc_unreachable ();
02231 }
02232 }
02233
02234
02235
02236
02237
02238
02239
02240 static void
02241 write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
02242 {
02243 const char *fn = s->u.s.line.file;
02244 int i;
02245 struct walk_type_data d;
02246
02247
02248 for (i = NUM_PARAM - 1; i >= 0; i--)
02249 if (param && param[i] && param[i]->kind == TYPE_POINTER
02250 && UNION_OR_STRUCT_P (param[i]->u.p))
02251 fn = param[i]->u.p->u.s.line.file;
02252
02253 memset (&d, 0, sizeof (d));
02254 d.of = get_output_file_with_visibility (fn);
02255
02256 d.process_field = write_types_local_process_field;
02257 d.opt = s->u.s.opt;
02258 d.line = &s->u.s.line;
02259 d.bitmap = s->u.s.bitmap;
02260 d.param = param;
02261 d.prev_val[0] = d.prev_val[2] = "*x";
02262 d.prev_val[1] = "not valid postage";
02263 d.prev_val[3] = "x";
02264 d.val = "(*x)";
02265 d.fn_wants_lvalue = true;
02266
02267 oprintf (d.of, "\n");
02268 oprintf (d.of, "void\n");
02269 oprintf (d.of, "gt_pch_p_");
02270 output_mangled_typename (d.of, orig_s);
02271 oprintf (d.of, " (ATTRIBUTE_UNUSED void *this_obj,\n"
02272 "\tvoid *x_p,\n"
02273 "\tATTRIBUTE_UNUSED gt_pointer_operator op,\n"
02274 "\tATTRIBUTE_UNUSED void *cookie)\n");
02275 oprintf (d.of, "{\n");
02276 oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
02277 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
02278 s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
02279 d.indent = 2;
02280 walk_type (s, &d);
02281 oprintf (d.of, "}\n");
02282 }
02283
02284
02285
02286 static void
02287 write_local (type_p structures, type_p param_structs)
02288 {
02289 type_p s;
02290
02291 oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
02292 for (s = structures; s; s = s->next)
02293 if (s->gc_used == GC_POINTED_TO
02294 || s->gc_used == GC_MAYBE_POINTED_TO)
02295 {
02296 options_p opt;
02297
02298 if (s->u.s.line.file == NULL)
02299 continue;
02300
02301 for (opt = s->u.s.opt; opt; opt = opt->next)
02302 if (strcmp (opt->name, "ptr_alias") == 0)
02303 {
02304 type_p t = (type_p) opt->info;
02305 if (t->kind == TYPE_STRUCT
02306 || t->kind == TYPE_UNION
02307 || t->kind == TYPE_LANG_STRUCT)
02308 {
02309 oprintf (header_file, "#define gt_pch_p_");
02310 output_mangled_typename (header_file, s);
02311 oprintf (header_file, " gt_pch_p_");
02312 output_mangled_typename (header_file, t);
02313 oprintf (header_file, "\n");
02314 }
02315 else
02316 error_at_line (&s->u.s.line,
02317 "structure alias is not a structure");
02318 break;
02319 }
02320 if (opt)
02321 continue;
02322
02323
02324 oprintf (header_file, "extern void gt_pch_p_");
02325 output_mangled_typename (header_file, s);
02326 oprintf (header_file,
02327 "\n (void *, void *, gt_pointer_operator, void *);\n");
02328
02329 if (s->kind == TYPE_LANG_STRUCT)
02330 {
02331 type_p ss;
02332 for (ss = s->u.s.lang_struct; ss; ss = ss->next)
02333 write_local_func_for_structure (s, ss, NULL);
02334 }
02335 else
02336 write_local_func_for_structure (s, s, NULL);
02337 }
02338
02339 for (s = param_structs; s; s = s->next)
02340 if (s->gc_used == GC_POINTED_TO)
02341 {
02342 type_p * param = s->u.param_struct.param;
02343 type_p stru = s->u.param_struct.stru;
02344
02345
02346 oprintf (header_file, "extern void gt_pch_p_");
02347 output_mangled_typename (header_file, s);
02348 oprintf (header_file,
02349 "\n (void *, void *, gt_pointer_operator, void *);\n");
02350
02351 if (stru->u.s.line.file == NULL)
02352 {
02353 fprintf (stderr, "warning: structure `%s' used but not defined\n",
02354 s->u.s.tag);
02355 continue;
02356 }
02357
02358 if (stru->kind == TYPE_LANG_STRUCT)
02359 {
02360 type_p ss;
02361 for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
02362 write_local_func_for_structure (s, ss, param);
02363 }
02364 else
02365 write_local_func_for_structure (s, stru, param);
02366 }
02367 }
02368
02369
02370
02371 static void
02372 write_enum_defn (type_p structures, type_p param_structs)
02373 {
02374 type_p s;
02375
02376 oprintf (header_file, "\n/* Enumeration of types known. */\n");
02377 oprintf (header_file, "enum gt_types_enum {\n");
02378 for (s = structures; s; s = s->next)
02379 if (s->gc_used == GC_POINTED_TO
02380 || s->gc_used == GC_MAYBE_POINTED_TO)
02381 {
02382 if (s->gc_used == GC_MAYBE_POINTED_TO
02383 && s->u.s.line.file == NULL)
02384 continue;
02385
02386 oprintf (header_file, " gt_ggc_e_");
02387 output_mangled_typename (header_file, s);
02388 oprintf (header_file, ", \n");
02389 }
02390 for (s = param_structs; s; s = s->next)
02391 if (s->gc_used == GC_POINTED_TO)
02392 {
02393 oprintf (header_file, " gt_e_");
02394 output_mangled_typename (header_file, s);
02395 oprintf (header_file, ", \n");
02396 }
02397 oprintf (header_file, " gt_types_enum_last\n");
02398 oprintf (header_file, "};\n");
02399 }
02400
02401
02402
02403 static int
02404 contains_scalar_p (type_p t)
02405 {
02406 switch (t->kind)
02407 {
02408 case TYPE_STRING:
02409 case TYPE_POINTER:
02410 return 0;
02411 case TYPE_ARRAY:
02412 return contains_scalar_p (t->u.a.p);
02413 default:
02414
02415
02416 return 1;
02417 }
02418 }
02419
02420
02421
02422 static void
02423 put_mangled_filename (outf_p f, const char *fn)
02424 {
02425 const char *name = get_output_file_name (fn);
02426 for (; *name != 0; name++)
02427 if (ISALNUM (*name))
02428 oprintf (f, "%c", *name);
02429 else
02430 oprintf (f, "%c", '_');
02431 }
02432
02433
02434
02435
02436
02437 static void
02438 finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
02439 const char *tname, const char *name)
02440 {
02441 struct flist *fli2;
02442
02443 for (fli2 = flp; fli2; fli2 = fli2->next)
02444 if (fli2->started_p)
02445 {
02446 oprintf (fli2->f, " %s\n", lastname);
02447 oprintf (fli2->f, "};\n\n");
02448 }
02449
02450 for (fli2 = flp; fli2; fli2 = fli2->next)
02451 if (fli2->started_p)
02452 {
02453 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
02454 int fnum;
02455
02456 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
02457 if (bitmap & 1)
02458 {
02459 oprintf (base_files[fnum],
02460 "extern const struct %s gt_%s_",
02461 tname, pfx);
02462 put_mangled_filename (base_files[fnum], fli2->name);
02463 oprintf (base_files[fnum], "[];\n");
02464 }
02465 }
02466
02467 {
02468 size_t fnum;
02469 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
02470 oprintf (base_files [fnum],
02471 "const struct %s * const %s[] = {\n",
02472 tname, name);
02473 }
02474
02475
02476 for (fli2 = flp; fli2; fli2 = fli2->next)
02477 if (fli2->started_p)
02478 {
02479 lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
02480 int fnum;
02481
02482 fli2->started_p = 0;
02483
02484 for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
02485 if (bitmap & 1)
02486 {
02487 oprintf (base_files[fnum], " gt_%s_", pfx);
02488 put_mangled_filename (base_files[fnum], fli2->name);
02489 oprintf (base_files[fnum], ",\n");
02490 }
02491 }
02492
02493 {
02494 size_t fnum;
02495 for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
02496 {
02497 oprintf (base_files[fnum], " NULL\n");
02498 oprintf (base_files[fnum], "};\n");
02499 }
02500 }
02501 }
02502
02503
02504
02505
02506
02507
02508 static void
02509 write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
02510 struct fileloc *line, const char *if_marked)
02511 {
02512 switch (type->kind)
02513 {
02514 case TYPE_STRUCT:
02515 {
02516 pair_p fld;
02517 for (fld = type->u.s.fields; fld; fld = fld->next)
02518 {
02519 int skip_p = 0;
02520 const char *desc = NULL;
02521 options_p o;
02522
02523 for (o = fld->opt; o; o = o->next)
02524 if (strcmp (o->name, "skip") == 0)
02525 skip_p = 1;
02526 else if (strcmp (o->name, "desc") == 0)
02527 desc = o->info;
02528 else
02529 error_at_line (line,
02530 "field `%s' of global `%s' has unknown option `%s'",
02531 fld->name, name, o->name);
02532
02533 if (skip_p)
02534 continue;
02535 else if (desc && fld->type->kind == TYPE_UNION)
02536 {
02537 pair_p validf = NULL;
02538 pair_p ufld;
02539
02540 for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
02541 {
02542 const char *tag = NULL;
02543 options_p oo;
02544
02545 for (oo = ufld->opt; oo; oo = oo->next)
02546 if (strcmp (oo->name, "tag") == 0)
02547 tag = oo->info;
02548 if (tag == NULL || strcmp (tag, desc) != 0)
02549 continue;
02550 if (validf != NULL)
02551 error_at_line (line,
02552 "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
02553 name, fld->name, validf->name,
02554 name, fld->name, ufld->name,
02555 tag);
02556 validf = ufld;
02557 }
02558 if (validf != NULL)
02559 {
02560 char *newname;
02561 newname = xasprintf ("%s.%s.%s",
02562 name, fld->name, validf->name);
02563 write_root (f, v, validf->type, newname, 0, line,
02564 if_marked);
02565 free (newname);
02566 }
02567 }
02568 else if (desc)
02569 error_at_line (line,
02570 "global `%s.%s' has `desc' option but is not union",
02571 name, fld->name);
02572 else
02573 {
02574 char *newname;
02575 newname = xasprintf ("%s.%s", name, fld->name);
02576 write_root (f, v, fld->type, newname, 0, line, if_marked);
02577 free (newname);
02578 }
02579 }
02580 }
02581 break;
02582
02583 case TYPE_ARRAY:
02584 {
02585 char *newname;
02586 newname = xasprintf ("%s[0]", name);
02587 write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
02588 free (newname);
02589 }
02590 break;
02591
02592 case TYPE_POINTER:
02593 {
02594 type_p ap, tp;
02595
02596 oprintf (f, " {\n");
02597 oprintf (f, " &%s,\n", name);
02598 oprintf (f, " 1");
02599
02600 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
02601 if (ap->u.a.len[0])
02602 oprintf (f, " * (%s)", ap->u.a.len);
02603 else if (ap == v->type)
02604 oprintf (f, " * ARRAY_SIZE (%s)", v->name);
02605 oprintf (f, ",\n");
02606 oprintf (f, " sizeof (%s", v->name);
02607 for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
02608 oprintf (f, "[0]");
02609 oprintf (f, "),\n");
02610
02611 tp = type->u.p;
02612
02613 if (! has_length && UNION_OR_STRUCT_P (tp))
02614 {
02615 oprintf (f, " >_ggc_mx_%s,\n", tp->u.s.tag);
02616 oprintf (f, " >_pch_nx_%s", tp->u.s.tag);
02617 }
02618 else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
02619 {
02620 oprintf (f, " >_ggc_m_");
02621 output_mangled_typename (f, tp);
02622 oprintf (f, ",\n >_pch_n_");
02623 output_mangled_typename (f, tp);
02624 }
02625 else if (has_length
02626 && (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
02627 {
02628 oprintf (f, " >_ggc_ma_%s,\n", name);
02629 oprintf (f, " >_pch_na_%s", name);
02630 }
02631 else
02632 {
02633 error_at_line (line,
02634 "global `%s' is pointer to unimplemented type",
02635 name);
02636 }
02637 if (if_marked)
02638 oprintf (f, ",\n &%s", if_marked);
02639 oprintf (f, "\n },\n");
02640 }
02641 break;
02642
02643 case TYPE_STRING:
02644 {
02645 oprintf (f, " {\n");
02646 oprintf (f, " &%s,\n", name);
02647 oprintf (f, " 1, \n");
02648 oprintf (f, " sizeof (%s),\n", v->name);
02649 oprintf (f, " >_ggc_m_S,\n");
02650 oprintf (f, " (gt_pointer_walker) >_pch_n_S\n");
02651 oprintf (f, " },\n");
02652 }
02653 break;
02654
02655 case TYPE_SCALAR:
02656 break;
02657
02658 default:
02659 error_at_line (line,
02660 "global `%s' is unimplemented type",
02661 name);
02662 }
02663 }
02664
02665
02666
02667 static void
02668 write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
02669 {
02670 struct walk_type_data d;
02671 char *prevval3;
02672
02673 memset (&d, 0, sizeof (d));
02674 d.of = f;
02675 d.cookie = wtd;
02676 d.indent = 2;
02677 d.line = &v->line;
02678 d.opt = v->opt;
02679 d.bitmap = get_base_file_bitmap (v->line.file);
02680 d.param = NULL;
02681
02682 d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
02683
02684 if (wtd->param_prefix)
02685 {
02686 oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
02687 oprintf (f,
02688 " (void *, void *, gt_pointer_operator, void *);\n");
02689 oprintf (f, "static void gt_%sa_%s (ATTRIBUTE_UNUSED void *this_obj,\n",
02690 wtd->param_prefix, v->name);
02691 oprintf (d.of,
02692 " ATTRIBUTE_UNUSED void *x_p,\n"
02693 " ATTRIBUTE_UNUSED gt_pointer_operator op,\n"
02694 " ATTRIBUTE_UNUSED void * cookie)\n");
02695 oprintf (d.of, "{\n");
02696 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
02697 d.process_field = write_types_local_process_field;
02698 walk_type (v->type, &d);
02699 oprintf (f, "}\n\n");
02700 }
02701
02702 d.opt = v->opt;
02703 oprintf (f, "static void gt_%sa_%s (void *);\n",
02704 wtd->prefix, v->name);
02705 oprintf (f, "static void\ngt_%sa_%s (ATTRIBUTE_UNUSED void *x_p)\n",
02706 wtd->prefix, v->name);
02707 oprintf (f, "{\n");
02708 d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
02709 d.process_field = write_types_process_field;
02710 walk_type (v->type, &d);
02711 free (prevval3);
02712 oprintf (f, "}\n\n");
02713 }
02714
02715
02716
02717 static void
02718 write_roots (pair_p variables)
02719 {
02720 pair_p v;
02721 struct flist *flp = NULL;
02722
02723 for (v = variables; v; v = v->next)
02724 {
02725 outf_p f = get_output_file_with_visibility (v->line.file);
02726 struct flist *fli;
02727 const char *length = NULL;
02728 int deletable_p = 0;
02729 options_p o;
02730
02731 for (o = v->opt; o; o = o->next)
02732 if (strcmp (o->name, "length") == 0)
02733 length = o->info;
02734 else if (strcmp (o->name, "deletable") == 0)
02735 deletable_p = 1;
02736 else if (strcmp (o->name, "param_is") == 0)
02737 ;
02738 else if (strncmp (o->name, "param", 5) == 0
02739 && ISDIGIT (o->name[5])
02740 && strcmp (o->name + 6, "_is") == 0)
02741 ;
02742 else if (strcmp (o->name, "if_marked") == 0)
02743 ;
02744 else
02745 error_at_line (&v->line,
02746 "global `%s' has unknown option `%s'",
02747 v->name, o->name);
02748
02749 for (fli = flp; fli; fli = fli->next)
02750 if (fli->f == f)
02751 break;
02752 if (fli == NULL)
02753 {
02754 fli = XNEW (struct flist);
02755 fli->f = f;
02756 fli->next = flp;
02757 fli->started_p = 0;
02758 fli->name = v->line.file;
02759 flp = fli;
02760
02761 oprintf (f, "\n/* GC roots. */\n\n");
02762 }
02763
02764 if (! deletable_p
02765 && length
02766 && v->type->kind == TYPE_POINTER
02767 && (v->type->u.p->kind == TYPE_POINTER
02768 || v->type->u.p->kind == TYPE_STRUCT))
02769 {
02770 write_array (f, v, &ggc_wtd);
02771 write_array (f, v, &pch_wtd);
02772 }
02773 }
02774
02775 for (v = variables; v; v = v->next)
02776 {
02777 outf_p f = get_output_file_with_visibility (v->line.file);
02778 struct flist *fli;
02779 int skip_p = 0;
02780 int length_p = 0;
02781 options_p o;
02782
02783 for (o = v->opt; o; o = o->next)
02784 if (strcmp (o->name, "length") == 0)
02785 length_p = 1;
02786 else if (strcmp (o->name, "deletable") == 0
02787 || strcmp (o->name, "if_marked") == 0)
02788 skip_p = 1;
02789
02790 if (skip_p)
02791 continue;
02792
02793 for (fli = flp; fli; fli = fli->next)
02794 if (fli->f == f)
02795 break;
02796 if (! fli->started_p)
02797 {
02798 fli->started_p = 1;
02799
02800 oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
02801 put_mangled_filename (f, v->line.file);
02802 oprintf (f, "[] = {\n");
02803 }
02804
02805 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
02806 }
02807
02808 finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
02809 "gt_ggc_rtab");
02810
02811 for (v = variables; v; v = v->next)
02812 {
02813 outf_p f = get_output_file_with_visibility (v->line.file);
02814 struct flist *fli;
02815 int skip_p = 1;
02816 options_p o;
02817
02818 for (o = v->opt; o; o = o->next)
02819 if (strcmp (o->name, "deletable") == 0)
02820 skip_p = 0;
02821 else if (strcmp (o->name, "if_marked") == 0)
02822 skip_p = 1;
02823
02824 if (skip_p)
02825 continue;
02826
02827 for (fli = flp; fli; fli = fli->next)
02828 if (fli->f == f)
02829 break;
02830 if (! fli->started_p)
02831 {
02832 fli->started_p = 1;
02833
02834 oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
02835 put_mangled_filename (f, v->line.file);
02836 oprintf (f, "[] = {\n");
02837 }
02838
02839 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
02840 v->name, v->name);
02841 }
02842
02843 finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
02844 "gt_ggc_deletable_rtab");
02845
02846 for (v = variables; v; v = v->next)
02847 {
02848 outf_p f = get_output_file_with_visibility (v->line.file);
02849 struct flist *fli;
02850 const char *if_marked = NULL;
02851 int length_p = 0;
02852 options_p o;
02853
02854 for (o = v->opt; o; o = o->next)
02855 if (strcmp (o->name, "length") == 0)
02856 length_p = 1;
02857 else if (strcmp (o->name, "if_marked") == 0)
02858 if_marked = o->info;
02859
02860 if (if_marked == NULL)
02861 continue;
02862
02863 if (v->type->kind != TYPE_POINTER
02864 || v->type->u.p->kind != TYPE_PARAM_STRUCT
02865 || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
02866 {
02867 error_at_line (&v->line, "if_marked option used but not hash table");
02868 continue;
02869 }
02870
02871 for (fli = flp; fli; fli = fli->next)
02872 if (fli->f == f)
02873 break;
02874 if (! fli->started_p)
02875 {
02876 fli->started_p = 1;
02877
02878 oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
02879 put_mangled_filename (f, v->line.file);
02880 oprintf (f, "[] = {\n");
02881 }
02882
02883 write_root (f, v, v->type->u.p->u.param_struct.param[0],
02884 v->name, length_p, &v->line, if_marked);
02885 }
02886
02887 finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
02888 "gt_ggc_cache_rtab");
02889
02890 for (v = variables; v; v = v->next)
02891 {
02892 outf_p f = get_output_file_with_visibility (v->line.file);
02893 struct flist *fli;
02894 int length_p = 0;
02895 int if_marked_p = 0;
02896 options_p o;
02897
02898 for (o = v->opt; o; o = o->next)
02899 if (strcmp (o->name, "length") == 0)
02900 length_p = 1;
02901 else if (strcmp (o->name, "if_marked") == 0)
02902 if_marked_p = 1;
02903
02904 if (! if_marked_p)
02905 continue;
02906
02907 for (fli = flp; fli; fli = fli->next)
02908 if (fli->f == f)
02909 break;
02910 if (! fli->started_p)
02911 {
02912 fli->started_p = 1;
02913
02914 oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
02915 put_mangled_filename (f, v->line.file);
02916 oprintf (f, "[] = {\n");
02917 }
02918
02919 write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
02920 }
02921
02922 finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
02923 "gt_pch_cache_rtab");
02924
02925 for (v = variables; v; v = v->next)
02926 {
02927 outf_p f = get_output_file_with_visibility (v->line.file);
02928 struct flist *fli;
02929 int skip_p = 0;
02930 options_p o;
02931
02932 for (o = v->opt; o; o = o->next)
02933 if (strcmp (o->name, "deletable") == 0
02934 || strcmp (o->name, "if_marked") == 0)
02935 skip_p = 1;
02936
02937 if (skip_p)
02938 continue;
02939
02940 if (! contains_scalar_p (v->type))
02941 continue;
02942
02943 for (fli = flp; fli; fli = fli->next)
02944 if (fli->f == f)
02945 break;
02946 if (! fli->started_p)
02947 {
02948 fli->started_p = 1;
02949
02950 oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
02951 put_mangled_filename (f, v->line.file);
02952 oprintf (f, "[] = {\n");
02953 }
02954
02955 oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
02956 v->name, v->name);
02957 }
02958
02959 finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
02960 "gt_pch_scalar_rtab");
02961 }
02962
02963
02964 extern int main (int argc, char **argv);
02965 int
02966 main(int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
02967 {
02968 unsigned i;
02969 static struct fileloc pos = { __FILE__, __LINE__ };
02970 unsigned j;
02971
02972 gen_rtx_next ();
02973
02974 srcdir_len = strlen (srcdir);
02975
02976 do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
02977 do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
02978 do_scalar_typedef ("uint8", &pos);
02979 do_scalar_typedef ("jword", &pos);
02980 do_scalar_typedef ("JCF_u2", &pos);
02981 #ifdef USE_MAPPED_LOCATION
02982 do_scalar_typedef ("location_t", &pos);
02983 do_scalar_typedef ("source_locus", &pos);
02984 #endif
02985 do_scalar_typedef ("void", &pos);
02986
02987 do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
02988
02989 do_typedef ("HARD_REG_SET", create_array (
02990 create_scalar_type ("unsigned long", strlen ("unsigned long")),
02991 "2"), &pos);
02992
02993 for (i = 0; i < NUM_GT_FILES; i++)
02994 {
02995 int dupflag = 0;
02996
02997 for (j = 0; j < i; j++)
02998 {
02999 if (!strcmp (all_files[i], all_files[j]))
03000 {
03001 dupflag = 1;
03002 break;
03003 }
03004 }
03005 if (!dupflag)
03006 parse_file (all_files[i]);
03007 #ifndef USE_MAPPED_LOCATION
03008
03009
03010 if (i == 0)
03011 do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
03012 #endif
03013 }
03014
03015 if (hit_error != 0)
03016 exit (1);
03017
03018 set_gc_used (variables);
03019
03020 open_base_files ();
03021 write_enum_defn (structures, param_structs);
03022 write_types (structures, param_structs, &ggc_wtd);
03023 write_types (structures, param_structs, &pch_wtd);
03024 write_local (structures, param_structs);
03025 write_roots (variables);
03026 write_rtx_next ();
03027 close_output_files ();
03028
03029 return (hit_error != 0);
03030 }