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