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