]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/read-md.cc
[PATCH v1 1/1] RISC-V: Nan-box the result of movbf on soft-bf16
[thirdparty/gcc.git] / gcc / read-md.cc
CommitLineData
10692477 1/* MD reader for GCC.
a945c346 2 Copyright (C) 1987-2024 Free Software Foundation, Inc.
10692477
RS
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
51b86113
DM
20/* This file is compiled twice: once for the generator programs
21 once for the compiler. */
22#ifdef GENERATOR_FILE
10692477 23#include "bconfig.h"
51b86113
DM
24#else
25#include "config.h"
26#endif
10692477
RS
27#include "system.h"
28#include "coretypes.h"
51b86113 29#ifdef GENERATOR_FILE
bb933490 30#include "errors.h"
51b86113 31#endif /* #ifdef GENERATOR_FILE */
b78027d1
DM
32#include "statistics.h"
33#include "vec.h"
10692477
RS
34#include "read-md.h"
35
51b86113
DM
36#ifndef GENERATOR_FILE
37
e53b6e56 38/* Minimal reimplementation of errors.cc for use by RTL frontend
51b86113
DM
39 within cc1. */
40
41int have_error = 0;
42
43#endif /* #ifndef GENERATOR_FILE */
44
45
600ab3fc
RS
46/* This callback will be invoked whenever an md include directive is
47 processed. To be used for creation of the dependency file. */
48void (*include_callback) (const char *);
49
812b1403
DM
50/* Global singleton. */
51
a96d1f1d 52md_reader *md_reader_ptr;
600ab3fc 53
9f418533
RS
54/* Given an object that starts with a char * name field, return a hash
55 code for its name. */
56
57hashval_t
58leading_string_hash (const void *def)
59{
60 return htab_hash_string (*(const char *const *) def);
61}
62
63/* Given two objects that start with char * name fields, return true if
64 they have the same name. */
65
66int
67leading_string_eq_p (const void *def1, const void *def2)
68{
69 return strcmp (*(const char *const *) def1,
70 *(const char *const *) def2) == 0;
71}
72
10692477
RS
73/* Return a hash value for the pointer pointed to by DEF. */
74
75static hashval_t
76leading_ptr_hash (const void *def)
77{
78 return htab_hash_pointer (*(const void *const *) def);
79}
80
81/* Return true if DEF1 and DEF2 are pointers to the same pointer. */
82
83static int
84leading_ptr_eq_p (const void *def1, const void *def2)
85{
86 return *(const void *const *) def1 == *(const void *const *) def2;
87}
88
737eb767 89/* Associate PTR with the file position given by FILE_LOC. */
10692477 90
b78027d1 91void
737eb767 92md_reader::set_md_ptr_loc (const void *ptr, file_location file_loc)
10692477
RS
93{
94 struct ptr_loc *loc;
95
b78027d1 96 loc = (struct ptr_loc *) obstack_alloc (&m_ptr_loc_obstack,
10692477
RS
97 sizeof (struct ptr_loc));
98 loc->ptr = ptr;
737eb767 99 loc->loc = file_loc;
b78027d1 100 *htab_find_slot (m_ptr_locs, loc, INSERT) = loc;
10692477
RS
101}
102
103/* Return the position associated with pointer PTR. Return null if no
104 position was set. */
105
737eb767 106const md_reader::ptr_loc *
a96d1f1d 107md_reader::get_md_ptr_loc (const void *ptr)
10692477 108{
b78027d1 109 return (const struct ptr_loc *) htab_find (m_ptr_locs, &ptr);
10692477
RS
110}
111
112/* Associate NEW_PTR with the same file position as OLD_PTR. */
113
114void
a96d1f1d 115md_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
10692477 116{
d2a3ce4e 117 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
10692477 118 if (loc != 0)
737eb767 119 set_md_ptr_loc (new_ptr, loc->loc);
10692477
RS
120}
121
122/* If PTR is associated with a known file position, print a #line
41723253 123 directive for it to OUTF. */
10692477
RS
124
125void
a96d1f1d 126md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
10692477 127{
d2a3ce4e 128 const struct ptr_loc *loc = get_md_ptr_loc (ptr);
10692477 129 if (loc != 0)
737eb767 130 fprintf (outf, "#line %d \"%s\"\n", loc->loc.lineno, loc->loc.filename);
41723253
SB
131}
132
133/* Special fprint_md_ptr_loc for writing to STDOUT. */
134void
18437802 135md_reader::print_md_ptr_loc (const void *ptr, FILE *file)
41723253 136{
18437802 137 fprint_md_ptr_loc (file, ptr);
10692477
RS
138}
139
140/* Return a condition that satisfies both COND1 and COND2. Either string
141 may be null or empty. */
142
143const char *
a96d1f1d 144md_reader::join_c_conditions (const char *cond1, const char *cond2)
10692477
RS
145{
146 char *result;
147 const void **entry;
148
149 if (cond1 == 0 || cond1[0] == 0)
150 return cond2;
151
152 if (cond2 == 0 || cond2[0] == 0)
153 return cond1;
154
155 if (strcmp (cond1, cond2) == 0)
156 return cond1;
157
158 result = concat ("(", cond1, ") && (", cond2, ")", NULL);
b78027d1
DM
159 obstack_ptr_grow (&m_joined_conditions_obstack, result);
160 obstack_ptr_grow (&m_joined_conditions_obstack, cond1);
161 obstack_ptr_grow (&m_joined_conditions_obstack, cond2);
162 entry = XOBFINISH (&m_joined_conditions_obstack, const void **);
163 *htab_find_slot (m_joined_conditions, entry, INSERT) = entry;
10692477
RS
164 return result;
165}
166
41723253
SB
167/* Print condition COND to OUTF, wrapped in brackets. If COND was created
168 by join_c_conditions, recursively invoke this function for the original
10692477
RS
169 conditions and join the result with "&&". Otherwise print a #line
170 directive for COND if its original file position is known. */
171
172void
a96d1f1d 173md_reader::fprint_c_condition (FILE *outf, const char *cond)
10692477 174{
b78027d1 175 const char **halves = (const char **) htab_find (m_joined_conditions, &cond);
10692477
RS
176 if (halves != 0)
177 {
41723253
SB
178 fprintf (outf, "(");
179 fprint_c_condition (outf, halves[1]);
180 fprintf (outf, " && ");
181 fprint_c_condition (outf, halves[2]);
182 fprintf (outf, ")");
10692477
RS
183 }
184 else
185 {
41723253
SB
186 fputc ('\n', outf);
187 fprint_md_ptr_loc (outf, cond);
188 fprintf (outf, "(%s)", cond);
10692477
RS
189 }
190}
191
41723253
SB
192/* Special fprint_c_condition for writing to STDOUT. */
193
194void
a96d1f1d 195md_reader::print_c_condition (const char *cond)
41723253
SB
196{
197 fprint_c_condition (stdout, cond);
198}
199
bb933490
RS
200/* A vfprintf-like function for reporting an error against line LINENO
201 of the current MD file. */
202
203static void ATTRIBUTE_PRINTF(2,0)
cc472607 204message_at_1 (file_location loc, const char *msg, va_list ap)
bb933490 205{
3814e880 206 fprintf (stderr, "%s:%d:%d: ", loc.filename, loc.lineno, loc.colno);
bb933490
RS
207 vfprintf (stderr, msg, ap);
208 fputc ('\n', stderr);
209}
210
cc472607
RS
211/* A printf-like function for reporting a message against location LOC. */
212
213void
214message_at (file_location loc, const char *msg, ...)
215{
216 va_list ap;
217
218 va_start (ap, msg);
219 message_at_1 (loc, msg, ap);
220 va_end (ap);
221}
222
223/* Like message_at, but treat the condition as an error. */
224
225void
226error_at (file_location loc, const char *msg, ...)
227{
228 va_list ap;
229
230 va_start (ap, msg);
231 message_at_1 (loc, msg, ap);
232 va_end (ap);
233 have_error = 1;
234}
235
8f246310
RS
236/* Like message_at, but treat the condition as a fatal error. */
237
238void
239fatal_at (file_location loc, const char *msg, ...)
240{
241 va_list ap;
242
243 va_start (ap, msg);
244 message_at_1 (loc, msg, ap);
245 va_end (ap);
246 exit (1);
247}
248
10692477 249/* A printf-like function for reporting an error against the current
c5e88b39 250 position in the MD file. */
10692477
RS
251
252void
c5e88b39 253fatal_with_file_and_line (const char *msg, ...)
10692477
RS
254{
255 char context[64];
256 size_t i;
257 int c;
258 va_list ap;
259
260 va_start (ap, msg);
261
a96d1f1d
DM
262 fprintf (stderr, "%s:%d:%d: error: ", md_reader_ptr->get_filename (),
263 md_reader_ptr->get_lineno (),
264 md_reader_ptr->get_colno ());
10692477
RS
265 vfprintf (stderr, msg, ap);
266 putc ('\n', stderr);
267
268 /* Gather some following context. */
269 for (i = 0; i < sizeof (context)-1; ++i)
270 {
c5e88b39 271 c = read_char ();
10692477
RS
272 if (c == EOF)
273 break;
274 if (c == '\r' || c == '\n')
7f7c467f
RS
275 {
276 unread_char (c);
277 break;
278 }
10692477
RS
279 context[i] = c;
280 }
281 context[i] = '\0';
282
3814e880 283 fprintf (stderr, "%s:%d:%d: note: following context is `%s'\n",
a96d1f1d
DM
284 md_reader_ptr->get_filename (),
285 md_reader_ptr->get_lineno (),
286 md_reader_ptr->get_colno (), context);
10692477
RS
287
288 va_end (ap);
289 exit (1);
290}
291
292/* Report that we found character ACTUAL when we expected to find
c5e88b39 293 character EXPECTED. */
10692477
RS
294
295void
c5e88b39 296fatal_expected_char (int expected, int actual)
10692477
RS
297{
298 if (actual == EOF)
c5e88b39 299 fatal_with_file_and_line ("expected character `%c', found EOF",
10692477
RS
300 expected);
301 else
c5e88b39 302 fatal_with_file_and_line ("expected character `%c', found `%c'",
10692477
RS
303 expected, actual);
304}
305
c5e88b39 306/* Read chars from the MD file until a non-whitespace char and return that.
10692477
RS
307 Comments, both Lisp style and C style, are treated as whitespace. */
308
309int
c5e88b39 310read_skip_spaces (void)
10692477
RS
311{
312 int c;
313
314 while (1)
315 {
c5e88b39 316 c = read_char ();
10692477
RS
317 switch (c)
318 {
7f7c467f 319 case ' ': case '\t': case '\f': case '\r': case '\n':
10692477
RS
320 break;
321
322 case ';':
323 do
c5e88b39 324 c = read_char ();
10692477 325 while (c != '\n' && c != EOF);
10692477
RS
326 break;
327
328 case '/':
329 {
330 int prevc;
c5e88b39 331 c = read_char ();
10692477 332 if (c != '*')
7f7c467f
RS
333 {
334 unread_char (c);
335 fatal_with_file_and_line ("stray '/' in file");
336 }
10692477
RS
337
338 prevc = 0;
c5e88b39 339 while ((c = read_char ()) && c != EOF)
10692477 340 {
7f7c467f 341 if (prevc == '*' && c == '/')
10692477
RS
342 break;
343 prevc = c;
344 }
345 }
346 break;
347
348 default:
349 return c;
350 }
351 }
352}
353
9c4e96eb
DM
354/* Consume the next character, issuing a fatal error if it is not
355 EXPECTED. */
356
357void
a96d1f1d 358md_reader::require_char (char expected)
9c4e96eb
DM
359{
360 int ch = read_char ();
361 if (ch != expected)
362 fatal_expected_char (expected, ch);
363}
364
601070fc
DM
365/* Consume any whitespace, then consume the next non-whitespace
366 character, issuing a fatal error if it is not EXPECTED. */
367
368void
a96d1f1d 369md_reader::require_char_ws (char expected)
601070fc
DM
370{
371 int ch = read_skip_spaces ();
372 if (ch != expected)
373 fatal_expected_char (expected, ch);
374}
375
9c4e96eb
DM
376/* Consume any whitespace, then consume the next word (as per read_name),
377 issuing a fatal error if it is not EXPECTED. */
378
379void
a96d1f1d 380md_reader::require_word_ws (const char *expected)
9c4e96eb
DM
381{
382 struct md_name name;
383 read_name (&name);
384 if (strcmp (name.string, expected))
385 fatal_with_file_and_line ("missing '%s'", expected);
386}
387
812b1403
DM
388/* Read the next character from the file. */
389
390int
a96d1f1d 391md_reader::read_char (void)
812b1403
DM
392{
393 int ch;
394
395 ch = getc (m_read_md_file);
396 if (ch == '\n')
3814e880
DM
397 {
398 m_read_md_lineno++;
399 m_last_line_colno = m_read_md_colno;
400 m_read_md_colno = 0;
401 }
402 else
403 m_read_md_colno++;
812b1403 404
c2e84327
DM
405 /* If we're filtering lines, treat everything before the range of
406 interest as a space, and as EOF for everything after. */
407 if (m_first_line && m_last_line)
408 {
409 if (m_read_md_lineno < m_first_line)
410 return ' ';
411 if (m_read_md_lineno > m_last_line)
412 return EOF;
413 }
414
812b1403
DM
415 return ch;
416}
417
418/* Put back CH, which was the last character read from the file. */
419
420void
a96d1f1d 421md_reader::unread_char (int ch)
812b1403
DM
422{
423 if (ch == '\n')
3814e880
DM
424 {
425 m_read_md_lineno--;
426 m_read_md_colno = m_last_line_colno;
427 }
428 else
429 m_read_md_colno--;
812b1403
DM
430 ungetc (ch, m_read_md_file);
431}
432
9c4e96eb
DM
433/* Peek at the next character from the file without consuming it. */
434
435int
a96d1f1d 436md_reader::peek_char (void)
9c4e96eb
DM
437{
438 int ch = read_char ();
439 unread_char (ch);
440 return ch;
441}
442
9f418533
RS
443/* Read an rtx code name into NAME. It is terminated by any of the
444 punctuation chars of rtx printed syntax. */
445
51b86113
DM
446bool
447md_reader::read_name_1 (struct md_name *name, file_location *out_loc)
9f418533
RS
448{
449 int c;
450 size_t i;
4fe017f6 451 int angle_bracket_depth;
9f418533
RS
452
453 c = read_skip_spaces ();
454
51b86113
DM
455 *out_loc = get_current_location ();
456
9f418533 457 i = 0;
4fe017f6 458 angle_bracket_depth = 0;
9f418533
RS
459 while (1)
460 {
4fe017f6
MC
461 if (c == '<')
462 angle_bracket_depth++;
463
464 if ((c == '>') && (angle_bracket_depth > 0))
465 angle_bracket_depth--;
466
9f418533
RS
467 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
468 || c == EOF)
469 break;
4fe017f6 470 if (angle_bracket_depth == 0)
9f418533 471 {
4fe017f6
MC
472 if (c == ':' || c == ')' || c == ']'
473 || c == '"' || c == '/' || c == '(' || c == '[')
474 {
475 unread_char (c);
476 break;
477 }
9f418533
RS
478 }
479
480 if (i == sizeof (name->buffer) - 1)
481 fatal_with_file_and_line ("name too long");
482 name->buffer[i++] = c;
483
484 c = read_char ();
485 }
486
487 if (i == 0)
51b86113 488 return false;
9f418533
RS
489
490 name->buffer[i] = 0;
491 name->string = name->buffer;
492
b78027d1 493 if (m_md_constants)
9f418533
RS
494 {
495 /* Do constant expansion. */
496 struct md_constant *def;
497
498 do
499 {
500 struct md_constant tmp_def;
501
502 tmp_def.name = name->string;
b78027d1 503 def = (struct md_constant *) htab_find (m_md_constants, &tmp_def);
9f418533
RS
504 if (def)
505 name->string = def->value;
506 }
507 while (def);
508 }
51b86113
DM
509
510 return true;
511}
512
513/* Read an rtx code name into NAME. It is terminated by any of the
514 punctuation chars of rtx printed syntax. */
515
516file_location
517md_reader::read_name (struct md_name *name)
518{
519 file_location loc;
520 if (!read_name_1 (name, &loc))
521 fatal_with_file_and_line ("missing name or number");
522 return loc;
523}
524
525file_location
526md_reader::read_name_or_nil (struct md_name *name)
527{
528 file_location loc;
529 if (!read_name_1 (name, &loc))
530 {
531 file_location loc = get_current_location ();
532 read_skip_construct (0, loc);
533 /* Skip the ')'. */
534 read_char ();
535 name->buffer[0] = 0;
536 name->string = name->buffer;
537 }
538 return loc;
9f418533
RS
539}
540
10692477
RS
541/* Subroutine of the string readers. Handles backslash escapes.
542 Caller has read the backslash, but not placed it into the obstack. */
543
b78027d1 544void
a96d1f1d 545md_reader::read_escape ()
10692477 546{
c5e88b39 547 int c = read_char ();
10692477
RS
548
549 switch (c)
550 {
551 /* Backslash-newline is replaced by nothing, as in C. */
552 case '\n':
10692477
RS
553 return;
554
555 /* \" \' \\ are replaced by the second character. */
556 case '\\':
557 case '"':
558 case '\'':
559 break;
560
561 /* Standard C string escapes:
562 \a \b \f \n \r \t \v
563 \[0-7] \x
564 all are passed through to the output string unmolested.
565 In normal use these wind up in a string constant processed
566 by the C compiler, which will translate them appropriately.
567 We do not bother checking that \[0-7] are followed by up to
568 two octal digits, or that \x is followed by N hex digits.
569 \? \u \U are left out because they are not in traditional C. */
570 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
571 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
572 case '7': case 'x':
b78027d1 573 obstack_1grow (&m_string_obstack, '\\');
10692477
RS
574 break;
575
576 /* \; makes stuff for a C string constant containing
577 newline and tab. */
578 case ';':
b78027d1 579 obstack_grow (&m_string_obstack, "\\n\\t", 4);
10692477
RS
580 return;
581
582 /* pass anything else through, but issue a warning. */
583 default:
584 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
b78027d1 585 get_filename (), get_lineno (),
812b1403 586 c);
b78027d1 587 obstack_1grow (&m_string_obstack, '\\');
10692477
RS
588 break;
589 }
590
b78027d1 591 obstack_1grow (&m_string_obstack, c);
10692477
RS
592}
593
594/* Read a double-quoted string onto the obstack. Caller has scanned
595 the leading quote. */
596
597char *
a96d1f1d 598md_reader::read_quoted_string ()
10692477
RS
599{
600 int c;
601
602 while (1)
603 {
c5e88b39 604 c = read_char (); /* Read the string */
7f7c467f 605 if (c == '\\')
10692477 606 {
c5e88b39 607 read_escape ();
10692477
RS
608 continue;
609 }
610 else if (c == '"' || c == EOF)
611 break;
612
b78027d1 613 obstack_1grow (&m_string_obstack, c);
10692477
RS
614 }
615
b78027d1
DM
616 obstack_1grow (&m_string_obstack, 0);
617 return XOBFINISH (&m_string_obstack, char *);
10692477
RS
618}
619
620/* Read a braced string (a la Tcl) onto the string obstack. Caller
621 has scanned the leading brace. Note that unlike quoted strings,
622 the outermost braces _are_ included in the string constant. */
623
b78027d1 624char *
a96d1f1d 625md_reader::read_braced_string ()
10692477
RS
626{
627 int c;
628 int brace_depth = 1; /* caller-processed */
b78027d1 629 unsigned long starting_read_md_lineno = get_lineno ();
10692477 630
b78027d1 631 obstack_1grow (&m_string_obstack, '{');
10692477
RS
632 while (brace_depth)
633 {
c5e88b39 634 c = read_char (); /* Read the string */
10692477 635
7f7c467f 636 if (c == '{')
10692477
RS
637 brace_depth++;
638 else if (c == '}')
639 brace_depth--;
640 else if (c == '\\')
641 {
c5e88b39 642 read_escape ();
10692477
RS
643 continue;
644 }
645 else if (c == EOF)
646 fatal_with_file_and_line
c5e88b39 647 ("missing closing } for opening brace on line %lu",
d2a3ce4e 648 starting_read_md_lineno);
10692477 649
b78027d1 650 obstack_1grow (&m_string_obstack, c);
10692477
RS
651 }
652
b78027d1
DM
653 obstack_1grow (&m_string_obstack, 0);
654 return XOBFINISH (&m_string_obstack, char *);
10692477
RS
655}
656
657/* Read some kind of string constant. This is the high-level routine
658 used by read_rtx. It handles surrounding parentheses, leading star,
659 and dispatch to the appropriate string constant reader. */
660
661char *
a96d1f1d 662md_reader::read_string (int star_if_braced)
10692477
RS
663{
664 char *stringbuf;
665 int saw_paren = 0;
737eb767 666 int c;
10692477 667
c5e88b39 668 c = read_skip_spaces ();
10692477
RS
669 if (c == '(')
670 {
671 saw_paren = 1;
c5e88b39 672 c = read_skip_spaces ();
10692477
RS
673 }
674
737eb767 675 file_location loc = get_current_location ();
10692477 676 if (c == '"')
c5e88b39 677 stringbuf = read_quoted_string ();
10692477
RS
678 else if (c == '{')
679 {
680 if (star_if_braced)
b78027d1 681 obstack_1grow (&m_string_obstack, '*');
c5e88b39 682 stringbuf = read_braced_string ();
10692477 683 }
51b86113
DM
684 else if (saw_paren && c == 'n')
685 {
686 /* Handle (nil) by returning NULL. */
687 require_char ('i');
688 require_char ('l');
689 require_char_ws (')');
690 return NULL;
691 }
10692477 692 else
c5e88b39 693 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
10692477
RS
694
695 if (saw_paren)
601070fc 696 require_char_ws (')');
10692477 697
737eb767 698 set_md_ptr_loc (stringbuf, loc);
10692477
RS
699 return stringbuf;
700}
701
9b68b6ea
RS
702/* Skip the rest of a construct that started at line LINENO and that
703 is currently nested by DEPTH levels of parentheses. */
704
b78027d1 705void
a96d1f1d 706md_reader::read_skip_construct (int depth, file_location loc)
9b68b6ea
RS
707{
708 struct md_name name;
709 int c;
710
711 do
712 {
713 c = read_skip_spaces ();
714 if (c == EOF)
715 {
cc472607 716 error_at (loc, "unterminated construct");
9b68b6ea
RS
717 exit (1);
718 }
719 switch (c)
720 {
721 case '(':
722 depth++;
723 break;
724
725 case ')':
726 depth--;
727 break;
728
729 case ':':
730 case '[':
731 case ']':
732 case '/':
733 break;
734
735 case '\"':
736 case '{':
737 unread_char (c);
738 read_string (false);
739 break;
740
741 default:
742 unread_char (c);
743 read_name (&name);
744 break;
745 }
746 }
747 while (depth > 0);
748 unread_char (c);
749}
750
10692477
RS
751/* Given a string, return the number of comma-separated elements in it.
752 Return 0 for the null string. */
753
754int
755n_comma_elts (const char *s)
756{
757 int n;
758
759 if (*s == '\0')
760 return 0;
761
762 for (n = 1; *s; s++)
763 if (*s == ',')
764 n++;
765
766 return n;
767}
768
769/* Given a pointer to a (char *), return a pointer to the beginning of the
770 next comma-separated element in the string. Advance the pointer given
771 to the end of that element. Return NULL if at end of string. Caller
772 is responsible for copying the string if necessary. White space between
773 a comma and an element is ignored. */
774
775const char *
776scan_comma_elt (const char **pstr)
777{
778 const char *start;
779 const char *p = *pstr;
780
781 if (*p == ',')
782 p++;
c3284718 783 while (ISSPACE (*p))
10692477
RS
784 p++;
785
786 if (*p == '\0')
787 return NULL;
788
789 start = p;
790
791 while (*p != ',' && *p != '\0')
792 p++;
793
794 *pstr = p;
795 return start;
796}
797
24609606
RS
798/* Convert STRING to uppercase. */
799
800void
801upcase_string (char *string)
802{
803 int i;
804
805 for (i = 0; string[i]; i++)
806 string[i] = TOUPPER (string[i]);
807}
808
809/* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
810 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
811 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
812
813static struct md_constant *
814add_constant (htab_t defs, char *name, char *value,
815 struct enum_type *parent_enum)
816{
817 struct md_constant *def, tmp_def;
818 void **entry_ptr;
819
820 tmp_def.name = name;
821 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
822 if (*entry_ptr)
823 {
824 def = (struct md_constant *) *entry_ptr;
825 if (strcmp (def->value, value) != 0)
826 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
827 def->name, def->value, value);
828 else if (parent_enum || def->parent_enum)
829 fatal_with_file_and_line ("redefinition of `%s'", def->name);
830 free (name);
831 free (value);
832 }
833 else
834 {
835 def = XNEW (struct md_constant);
836 def->name = name;
837 def->value = value;
838 def->parent_enum = parent_enum;
839 *entry_ptr = def;
840 }
841 return def;
842}
843
9f418533
RS
844/* Process a define_constants directive, starting with the optional space
845 after the "define_constants". */
846
b78027d1 847void
a96d1f1d 848md_reader::handle_constants ()
9f418533
RS
849{
850 int c;
851 htab_t defs;
852
601070fc 853 require_char_ws ('[');
9f418533
RS
854
855 /* Disable constant expansion during definition processing. */
b78027d1
DM
856 defs = m_md_constants;
857 m_md_constants = 0;
9f418533
RS
858 while ( (c = read_skip_spaces ()) != ']')
859 {
860 struct md_name name, value;
9f418533
RS
861
862 if (c != '(')
863 fatal_expected_char ('(', c);
864
865 read_name (&name);
866 read_name (&value);
24609606 867 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
9f418533 868
601070fc 869 require_char_ws (')');
9f418533 870 }
b78027d1 871 m_md_constants = defs;
9f418533
RS
872}
873
874/* For every constant definition, call CALLBACK with two arguments:
875 a pointer a pointer to the constant definition and INFO.
876 Stop when CALLBACK returns zero. */
877
878void
a96d1f1d 879md_reader::traverse_md_constants (htab_trav callback, void *info)
9f418533 880{
b78027d1 881 htab_traverse (get_md_constants (), callback, info);
24609606
RS
882}
883
884/* Return a malloc()ed decimal string that represents number NUMBER. */
885
886static char *
09e9c1e0 887md_decimal_string (int number)
24609606
RS
888{
889 /* A safe overestimate. +1 for sign, +1 for null terminator. */
890 char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
891
892 sprintf (buffer, "%d", number);
893 return xstrdup (buffer);
894}
895
896/* Process a define_enum or define_c_enum directive, starting with
897 the optional space after the "define_enum". LINENO is the line
898 number on which the directive started and MD_P is true if the
899 directive is a define_enum rather than a define_c_enum. */
900
b78027d1 901void
a96d1f1d 902md_reader::handle_enum (file_location loc, bool md_p)
24609606
RS
903{
904 char *enum_name, *value_name;
7c922606
YS
905 unsigned int cur_value;
906 struct md_name name, value;
24609606
RS
907 struct enum_type *def;
908 struct enum_value *ev;
909 void **slot;
910 int c;
911
912 enum_name = read_string (false);
b78027d1 913 slot = htab_find_slot (m_enum_types, &enum_name, INSERT);
24609606
RS
914 if (*slot)
915 {
916 def = (struct enum_type *) *slot;
917 if (def->md_p != md_p)
cc472607
RS
918 error_at (loc, "redefining `%s' as a different type of enum",
919 enum_name);
24609606
RS
920 }
921 else
922 {
923 def = XNEW (struct enum_type);
924 def->name = enum_name;
925 def->md_p = md_p;
926 def->values = 0;
927 def->tail_ptr = &def->values;
928 def->num_values = 0;
929 *slot = def;
930 }
931
7c922606 932 cur_value = def->num_values;
601070fc 933 require_char_ws ('[');
24609606
RS
934
935 while ((c = read_skip_spaces ()) != ']')
936 {
937 if (c == EOF)
938 {
cc472607 939 error_at (loc, "unterminated construct");
24609606
RS
940 exit (1);
941 }
7c922606
YS
942 if (c == '(')
943 {
944 read_name (&name);
945 read_name (&value);
946 require_char_ws (')');
947 cur_value = atoi (value.string);
948 }
949 else
950 {
951 unread_char (c);
952 read_name (&name);
953 }
24609606
RS
954
955 ev = XNEW (struct enum_value);
956 ev->next = 0;
957 if (md_p)
958 {
959 value_name = concat (def->name, "_", name.string, NULL);
960 upcase_string (value_name);
961 ev->name = xstrdup (name.string);
962 }
963 else
964 {
965 value_name = xstrdup (name.string);
966 ev->name = value_name;
967 }
b78027d1 968 ev->def = add_constant (get_md_constants (), value_name,
7c922606 969 md_decimal_string (cur_value), def);
24609606
RS
970
971 *def->tail_ptr = ev;
972 def->tail_ptr = &ev->next;
973 def->num_values++;
7c922606 974 cur_value++;
24609606
RS
975 }
976}
977
8f4fe86c
RS
978/* Try to find the definition of the given enum. Return null on failure. */
979
980struct enum_type *
a96d1f1d 981md_reader::lookup_enum_type (const char *name)
8f4fe86c 982{
b78027d1 983 return (struct enum_type *) htab_find (m_enum_types, &name);
8f4fe86c
RS
984}
985
24609606
RS
986/* For every enum definition, call CALLBACK with two arguments:
987 a pointer to the constant definition and INFO. Stop when CALLBACK
988 returns zero. */
989
990void
a96d1f1d 991md_reader::traverse_enum_types (htab_trav callback, void *info)
24609606 992{
b78027d1 993 htab_traverse (m_enum_types, callback, info);
9f418533
RS
994}
995
812b1403 996
a96d1f1d 997/* Constructor for md_reader. */
812b1403 998
51b86113
DM
999md_reader::md_reader (bool compact)
1000: m_compact (compact),
1001 m_toplevel_fname (NULL),
812b1403
DM
1002 m_base_dir (NULL),
1003 m_read_md_file (NULL),
1004 m_read_md_filename (NULL),
1005 m_read_md_lineno (0),
3814e880 1006 m_read_md_colno (0),
812b1403 1007 m_first_dir_md_include (NULL),
c2e84327
DM
1008 m_last_dir_md_include_ptr (&m_first_dir_md_include),
1009 m_first_line (0),
0016d8d9
RS
1010 m_last_line (0),
1011 m_first_overload (NULL),
1012 m_next_overload_ptr (&m_first_overload),
1013 m_overloads_htab (NULL)
812b1403
DM
1014{
1015 /* Set the global singleton pointer. */
a96d1f1d 1016 md_reader_ptr = this;
b78027d1
DM
1017
1018 obstack_init (&m_string_obstack);
1019
1020 m_ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1021 obstack_init (&m_ptr_loc_obstack);
1022
1023 m_joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1024 obstack_init (&m_joined_conditions_obstack);
1025
1026 m_md_constants = htab_create (31, leading_string_hash,
1027 leading_string_eq_p, (htab_del) 0);
1028
1029 m_enum_types = htab_create (31, leading_string_hash,
1030 leading_string_eq_p, (htab_del) 0);
1031
1032 /* Unlock the stdio streams. */
1033 unlock_std_streams ();
812b1403
DM
1034}
1035
a96d1f1d 1036/* md_reader's destructor. */
812b1403 1037
a96d1f1d 1038md_reader::~md_reader ()
812b1403 1039{
b78027d1
DM
1040 free (m_base_dir);
1041
1042 htab_delete (m_enum_types);
1043
1044 htab_delete (m_md_constants);
1045
1046 obstack_free (&m_joined_conditions_obstack, NULL);
1047 htab_delete (m_joined_conditions);
1048
1049 obstack_free (&m_ptr_loc_obstack, NULL);
1050 htab_delete (m_ptr_locs);
1051
1052 obstack_free (&m_string_obstack, NULL);
1053
812b1403 1054 /* Clear the global singleton pointer. */
a96d1f1d 1055 md_reader_ptr = NULL;
812b1403
DM
1056}
1057
600ab3fc
RS
1058/* Process an "include" directive, starting with the optional space
1059 after the "include". Read in the file and use HANDLE_DIRECTIVE
1060 to process each unknown directive. LINENO is the line number on
1aa95df7 1061 which the "include" occurred. */
10692477 1062
812b1403 1063void
a96d1f1d 1064md_reader::handle_include (file_location loc)
10692477 1065{
600ab3fc
RS
1066 const char *filename;
1067 const char *old_filename;
3814e880 1068 int old_lineno, old_colno;
600ab3fc
RS
1069 char *pathname;
1070 FILE *input_file, *old_file;
1071
1072 filename = read_string (false);
1073 input_file = NULL;
1074
1075 /* If the specified file name is absolute, skip the include stack. */
1076 if (!IS_ABSOLUTE_PATH (filename))
1077 {
1078 struct file_name_list *stackp;
1079
1080 /* Search the directory path, trying to open the file. */
812b1403 1081 for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next)
600ab3fc
RS
1082 {
1083 static const char sep[2] = { DIR_SEPARATOR, '\0' };
1084
1085 pathname = concat (stackp->fname, sep, filename, NULL);
1086 input_file = fopen (pathname, "r");
1087 if (input_file != NULL)
1088 break;
1089 free (pathname);
1090 }
1091 }
1092
1093 /* If we haven't managed to open the file yet, try combining the
1094 filename with BASE_DIR. */
1095 if (input_file == NULL)
1096 {
812b1403
DM
1097 if (m_base_dir)
1098 pathname = concat (m_base_dir, filename, NULL);
600ab3fc
RS
1099 else
1100 pathname = xstrdup (filename);
1101 input_file = fopen (pathname, "r");
1102 }
1103
1104 if (input_file == NULL)
1105 {
1106 free (pathname);
cc472607 1107 error_at (loc, "include file `%s' not found", filename);
600ab3fc
RS
1108 return;
1109 }
1110
1111 /* Save the old cursor. Note that the LINENO argument to this
1112 function is the beginning of the include statement, while
1113 read_md_lineno has already been advanced. */
812b1403
DM
1114 old_file = m_read_md_file;
1115 old_filename = m_read_md_filename;
1116 old_lineno = m_read_md_lineno;
3814e880 1117 old_colno = m_read_md_colno;
600ab3fc
RS
1118
1119 if (include_callback)
1120 include_callback (pathname);
1121
812b1403
DM
1122 m_read_md_file = input_file;
1123 m_read_md_filename = pathname;
1124
1125 handle_file ();
600ab3fc
RS
1126
1127 /* Restore the old cursor. */
812b1403
DM
1128 m_read_md_file = old_file;
1129 m_read_md_filename = old_filename;
1130 m_read_md_lineno = old_lineno;
3814e880 1131 m_read_md_colno = old_colno;
600ab3fc
RS
1132
1133 /* Do not free the pathname. It is attached to the various rtx
1134 queue elements. */
1135}
1136
1137/* Process the current file, assuming that read_md_file and
1138 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
1139 unknown directives. */
1140
812b1403 1141void
a96d1f1d 1142md_reader::handle_file ()
600ab3fc
RS
1143{
1144 struct md_name directive;
cc472607 1145 int c;
600ab3fc 1146
812b1403 1147 m_read_md_lineno = 1;
3814e880 1148 m_read_md_colno = 0;
600ab3fc
RS
1149 while ((c = read_skip_spaces ()) != EOF)
1150 {
812b1403 1151 file_location loc = get_current_location ();
600ab3fc
RS
1152 if (c != '(')
1153 fatal_expected_char ('(', c);
1154
1155 read_name (&directive);
1156 if (strcmp (directive.string, "define_constants") == 0)
1157 handle_constants ();
24609606 1158 else if (strcmp (directive.string, "define_enum") == 0)
cc472607 1159 handle_enum (loc, true);
24609606 1160 else if (strcmp (directive.string, "define_c_enum") == 0)
cc472607 1161 handle_enum (loc, false);
600ab3fc 1162 else if (strcmp (directive.string, "include") == 0)
812b1403 1163 handle_include (loc);
9b68b6ea 1164 else
812b1403 1165 handle_unknown_directive (loc, directive.string);
600ab3fc 1166
601070fc 1167 require_char_ws (')');
600ab3fc 1168 }
812b1403 1169 fclose (m_read_md_file);
600ab3fc
RS
1170}
1171
812b1403
DM
1172/* Like handle_file, but for top-level files. Set up m_toplevel_fname
1173 and m_base_dir accordingly. */
600ab3fc 1174
812b1403 1175void
a96d1f1d 1176md_reader::handle_toplevel_file ()
600ab3fc 1177{
ba78087b 1178 const char *base;
600ab3fc 1179
812b1403
DM
1180 m_toplevel_fname = m_read_md_filename;
1181 base = lbasename (m_toplevel_fname);
1182 if (base == m_toplevel_fname)
1183 m_base_dir = NULL;
ba78087b 1184 else
812b1403
DM
1185 m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname);
1186
1187 handle_file ();
1188}
600ab3fc 1189
812b1403 1190file_location
a96d1f1d 1191md_reader::get_current_location () const
812b1403 1192{
3814e880 1193 return file_location (m_read_md_filename, m_read_md_lineno, m_read_md_colno);
600ab3fc
RS
1194}
1195
1196/* Parse a -I option with argument ARG. */
1197
812b1403 1198void
a96d1f1d 1199md_reader::add_include_path (const char *arg)
600ab3fc
RS
1200{
1201 struct file_name_list *dirtmp;
1202
1203 dirtmp = XNEW (struct file_name_list);
1204 dirtmp->next = 0;
1205 dirtmp->fname = arg;
812b1403
DM
1206 *m_last_dir_md_include_ptr = dirtmp;
1207 m_last_dir_md_include_ptr = &dirtmp->next;
600ab3fc
RS
1208}
1209
51b86113
DM
1210#ifdef GENERATOR_FILE
1211
600ab3fc 1212/* The main routine for reading .md files. Try to process all the .md
1aa95df7 1213 files specified on the command line and return true if no error occurred.
600ab3fc
RS
1214
1215 ARGC and ARGV are the arguments to main.
1216
1217 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1218 It should return true if it recognizes the argument or false if a
812b1403 1219 generic error should be reported. */
600ab3fc
RS
1220
1221bool
a96d1f1d
DM
1222md_reader::read_md_files (int argc, const char **argv,
1223 bool (*parse_opt) (const char *))
600ab3fc
RS
1224{
1225 int i;
1226 bool no_more_options;
1227 bool already_read_stdin;
1228 int num_files;
1229
600ab3fc
RS
1230 /* First we loop over all the options. */
1231 for (i = 1; i < argc; i++)
1232 if (argv[i][0] == '-')
1233 {
1234 /* An argument consisting of exactly one dash is a request to
1235 read stdin. This will be handled in the second loop. */
1236 if (argv[i][1] == '\0')
1237 continue;
1238
1239 /* An argument consisting of just two dashes causes option
1240 parsing to cease. */
1241 if (argv[i][1] == '-' && argv[i][2] == '\0')
1242 break;
1243
1244 if (argv[i][1] == 'I')
1245 {
1246 if (argv[i][2] != '\0')
812b1403 1247 add_include_path (argv[i] + 2);
600ab3fc 1248 else if (++i < argc)
812b1403 1249 add_include_path (argv[i]);
600ab3fc
RS
1250 else
1251 fatal ("directory name missing after -I option");
1252 continue;
1253 }
1254
1255 /* The program may have provided a callback so it can
1256 accept its own options. */
1257 if (parse_opt && parse_opt (argv[i]))
1258 continue;
1259
1260 fatal ("invalid option `%s'", argv[i]);
1261 }
1262
1263 /* Now loop over all input files. */
1264 num_files = 0;
1265 no_more_options = false;
1266 already_read_stdin = false;
1267 for (i = 1; i < argc; i++)
1268 {
1269 if (argv[i][0] == '-')
1270 {
1271 if (argv[i][1] == '\0')
1272 {
1273 /* Read stdin. */
1274 if (already_read_stdin)
1275 fatal ("cannot read standard input twice");
1276
812b1403
DM
1277 m_read_md_file = stdin;
1278 m_read_md_filename = "<stdin>";
1279 handle_toplevel_file ();
600ab3fc
RS
1280 already_read_stdin = true;
1281 continue;
1282 }
1283 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1284 {
1285 /* No further arguments are to be treated as options. */
1286 no_more_options = true;
1287 continue;
1288 }
1289 else if (!no_more_options)
1290 continue;
1291 }
1292
1293 /* If we get here we are looking at a non-option argument, i.e.
1294 a file to be processed. */
812b1403
DM
1295 m_read_md_filename = argv[i];
1296 m_read_md_file = fopen (m_read_md_filename, "r");
1297 if (m_read_md_file == 0)
600ab3fc 1298 {
812b1403 1299 perror (m_read_md_filename);
600ab3fc
RS
1300 return false;
1301 }
812b1403 1302 handle_toplevel_file ();
600ab3fc
RS
1303 num_files++;
1304 }
1305
1306 /* If we get to this point without having seen any files to process,
1307 read the standard input now. */
1308 if (num_files == 0 && !already_read_stdin)
1309 {
812b1403
DM
1310 m_read_md_file = stdin;
1311 m_read_md_filename = "<stdin>";
1312 handle_toplevel_file ();
600ab3fc
RS
1313 }
1314
1315 return !have_error;
10692477 1316}
812b1403 1317
51b86113
DM
1318#endif /* #ifdef GENERATOR_FILE */
1319
1320/* Read FILENAME. */
1321
1322bool
1323md_reader::read_file (const char *filename)
1324{
1325 m_read_md_filename = filename;
1326 m_read_md_file = fopen (m_read_md_filename, "r");
1327 if (m_read_md_file == 0)
1328 {
1329 perror (m_read_md_filename);
1330 return false;
1331 }
1332 handle_toplevel_file ();
1333 return !have_error;
1334}
1335
c2e84327
DM
1336/* Read FILENAME, filtering to just the given lines. */
1337
1338bool
1339md_reader::read_file_fragment (const char *filename,
1340 int first_line,
1341 int last_line)
1342{
1343 m_read_md_filename = filename;
1344 m_read_md_file = fopen (m_read_md_filename, "r");
1345 if (m_read_md_file == 0)
1346 {
1347 perror (m_read_md_filename);
1348 return false;
1349 }
1350 m_first_line = first_line;
1351 m_last_line = last_line;
1352 handle_toplevel_file ();
1353 return !have_error;
1354}
1355
a96d1f1d 1356/* class noop_reader : public md_reader */
812b1403
DM
1357
1358/* A dummy implementation which skips unknown directives. */
1359void
1360noop_reader::handle_unknown_directive (file_location loc, const char *)
1361{
1362 read_skip_construct (1, loc);
1363}