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