1 /* -*- indented-text -*- */
2 /* Process source files and output type information.
3 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "coretypes.h"
27 #define malloc xmalloc
28 #define realloc xrealloc
31 #include "gengtype-yacc.h"
33 #define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE))
35 static unsigned macro_input (char *buffer, unsigned);
36 static const char *push_macro_expansion (const char *, unsigned,
37 const char *, unsigned);
38 static char *mangle_macro_name (const char *, unsigned,
39 const char *, unsigned);
40 static void update_lineno (const char *l, size_t len);
42 struct fileloc lexer_line;
43 int lexer_toplevel_done;
46 update_lineno (const char *l, size_t len)
55 ID [[:alpha:]_][[:alnum:]_]*
57 IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD
58 ITYPE {IWORD}({WS}{IWORD})*
60 %x in_struct in_struct_comment in_comment in_yacc_escape
61 %option warn noyywrap nounput nodefault perf-report
62 %option 8bit never-interactive
65 [^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" {
74 tagstart = yytext + strlen (" typedef ");
75 while (ISSPACE (*tagstart))
77 union_p = tagstart[0] == 'u';
78 tagstart += strlen ("union ");
79 while (ISSPACE (*tagstart))
81 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
83 for (namestart = tagstart + taglen;
84 ! ISIDNUM (*namestart);
86 if (*namestart == '*')
88 for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++)
90 t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1),
93 t = create_pointer (t);
94 namestart = (char *) xmemdup (namestart, namelen, namelen+1);
95 #ifdef USE_MAPPED_LOCATION
96 /* temporary kludge - gentype doesn't handle cpp conditionals */
97 if (strcmp (namestart, "location_t") != 0
98 && strcmp (namestart, "expanded_location") != 0)
100 do_typedef (namestart, t, &lexer_line);
101 update_lineno (yytext, yyleng);
104 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
112 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
114 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
116 namestart -= namelen - 1;
117 for (typestart = yytext + strlen (" typedef ");
121 for (typelen = namestart - typestart;
122 ISSPACE (typestart[typelen-1]);
126 t = create_scalar_type (typestart, typelen);
127 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
129 update_lineno (yytext, yyleng);
132 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
137 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
139 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
141 namestart -= namelen - 1;
143 t = create_scalar_type ("function type", sizeof ("function type")-1);
144 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
146 update_lineno (yytext, yyleng);
149 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
154 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
156 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
158 namestart -= namelen - 1;
160 t = create_scalar_type ("function type", sizeof ("function type")-1);
161 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
163 update_lineno (yytext, yyleng);
166 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
171 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
173 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
175 namestart -= namelen - 1;
177 t = create_scalar_type ("function type", sizeof ("function type")-1);
178 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
180 update_lineno (yytext, yyleng);
183 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
188 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
190 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
192 namestart -= namelen - 1;
194 t = create_scalar_type ("function type", sizeof ("function type")-1);
195 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
197 update_lineno (yytext, yyleng);
200 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
206 typedef_p = yytext[1] == 't';
208 for (tagstart = yytext + strlen (" typedef ");
213 tagstart = yytext + 1;
215 union_p = tagstart[0] == 'u';
216 tagstart += strlen ("union ");
217 while (ISSPACE (*tagstart))
219 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
222 yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen,
226 update_lineno (yytext, yyleng);
227 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
230 [^[:alnum:]_](extern|static){WS}/"GTY" {
232 update_lineno (yytext, yyleng);
233 return ENT_EXTERNSTATIC;
236 ^"%union"{WS}"{"{WS}/"GTY" {
238 update_lineno (yytext, yyleng);
239 return ENT_YACCUNION;
242 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
244 unsigned macro_len, arg_len;
246 const char *additional;
249 /* Find the macro name. */
250 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
252 for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++)
255 /* Find the argument(s). */
256 for (arg = ptr; *ptr != ')'; ptr++)
260 /* Create the struct and typedef. */
261 ptr = mangle_macro_name ("VEC", 3, arg, arg_len);
263 t = find_structure (ptr, 0);
264 do_typedef (ptr, t, &lexer_line);
266 /* Push the macro for later expansion. */
267 additional = push_macro_expansion (macro, macro_len, arg, arg_len);
271 ptr = mangle_macro_name (ptr, strlen (ptr),
272 additional, strlen (additional));
273 t = find_structure (ptr, 0);
274 do_typedef (ptr, t, &lexer_line);
280 "/*" { BEGIN(in_struct_comment); }
282 ^"%{" { BEGIN(in_yacc_escape); } /* } */
284 {WS} { update_lineno (yytext, yyleng); }
286 "const"/[^[:alnum:]_] /* don't care */
287 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
288 "union"/[^[:alnum:]_] { return UNION; }
289 "struct"/[^[:alnum:]_] { return STRUCT; }
290 "enum"/[^[:alnum:]_] { return ENUM; }
291 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
292 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
293 [0-9]+ { return NUM; }
294 "param"[0-9]*"_is"/[^[:alnum:]_] {
295 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
299 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
300 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
303 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
306 yylval.t = create_scalar_type (yytext, len);
307 update_lineno (yytext, yyleng);
311 "VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
313 unsigned macro_len, arg_len;
316 /* Find the macro name */
317 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
319 for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++)
322 /* Find the arguments. */
323 for (arg = ptr; *ptr != ')'; ptr++)
327 ptr = mangle_macro_name (macro, macro_len, arg, arg_len);
333 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
338 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
342 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
346 yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
349 "'"("\\".|[^\\])"'" {
350 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
354 [(){},*:<>] { return yytext[0]; }
357 if (lexer_toplevel_done)
360 lexer_toplevel_done = 0;
367 return PERCENTPERCENT;
370 "#define"[^\n]*\n {lexer_line.line++;}
373 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
377 "/*" { BEGIN(in_comment); }
378 \n { lexer_line.line++; }
380 "'"("\\".|[^\\])"'" |
381 [^"/\n] /* do nothing */
382 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
383 "/"/[^*] /* do nothing */
385 <in_comment,in_struct_comment>{
386 \n { lexer_line.line++; }
388 [^*\n] /* do nothing */
389 "*"/[^/] /* do nothing */
391 <in_comment>"*/" { BEGIN(INITIAL); }
392 <in_struct_comment>"*/" { BEGIN(in_struct); }
395 \n { lexer_line.line++; }
397 [^%] /* do nothing */
398 "%"/[^}] /* do nothing */
399 "%}" { BEGIN(in_struct); }
401 error_at_line (&lexer_line,
402 "unterminated %%{; unexpected EOF");
408 <in_struct_comment,in_comment>"*" {
409 error_at_line (&lexer_line,
410 "unterminated comment or string; unexpected EOF");
413 ^"#define"{WS}"GTY(" /* do nothing */
415 error_at_line (&lexer_line, "stray GTY marker");
420 /* Deal with the expansion caused by the DEF_VEC_x macros. */
422 /* Mangle a macro and argument list as done by cpp concatenation in
423 the compiler proper. */
425 mangle_macro_name (const char *macro, unsigned macro_len,
426 const char *arg, unsigned arg_len)
428 char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
430 /* Now copy and concatenate each argument */
433 ptr[macro_len++] = '_';
434 for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--)
435 ptr[macro_len++] = *arg++;
436 for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--)
444 typedef struct macro_def
447 const char *expansion;
448 const char *additional;
453 const macro_def_t *def;
455 const char *args[10];
458 static const macro_def_t macro_defs[] =
460 #define IN_GENGTYPE 1
465 /* Chain of macro expansions to do at end of scanning. */
466 static macro_t *macro_expns;
467 static macro_t *macro_expns_end;
469 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
470 expansion queue. We ensure NAME is known at this point. */
473 push_macro_expansion (const char *name, unsigned name_len,
474 const char *arg, unsigned arg_len)
478 for (ix = 0; macro_defs[ix].name; ix++)
479 if (strlen (macro_defs[ix].name) == name_len
480 && !memcmp (name, macro_defs[ix].name, name_len))
482 macro_t *expansion = XNEW (macro_t);
484 unsigned argno, last_arg;
486 expansion->def = ¯o_defs[ix];
487 expansion->next = NULL;
488 args = (char *) xmemdup (arg, arg_len, arg_len+1);
490 for (argno = 0; *args;)
492 expansion->args[argno++] = args;
493 while (*args && (ISALNUM (*args) || *args == '_'))
496 expansion->args[argno++] = "base";
500 while (*args && !(ISALNUM (*args) || *args == '_'))
504 for (; argno != 10; argno++)
505 expansion->args[argno] = NULL;
507 macro_expns_end->next = expansion;
509 macro_expns = expansion;
510 macro_expns_end = expansion;
511 if (macro_defs[ix].additional)
513 macro_t *expn2 = XNEW (macro_t);
514 memcpy (expn2, expansion, sizeof (*expn2));
517 expansion->args[last_arg++] = macro_defs[ix].additional;
518 macro_expns_end->next = expansion;
519 macro_expns_end = expansion;
521 if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap"))
522 expansion->args[last_arg++] = "GTY (())";
523 return macro_defs[ix].additional;
525 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
526 name_len, name, arg_len, arg);
530 /* Attempt to read some input. Use fread until we're at the end of
531 file. At end of file expand the next queued macro. We presume the
532 buffer is large enough for the entire expansion. */
535 macro_input (char *buffer, unsigned size)
539 result = fread (buffer, 1, size, yyin);
542 else if (ferror (yyin))
543 YY_FATAL_ERROR ("read of source file failed");
544 else if (macro_expns)
549 for (expn = macro_expns->def->expansion; *expn; expn++)
555 argno = expn[1] - '0';
558 /* Remove inserted space? */
559 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
562 /* Insert the argument value */
563 if (macro_expns->args[argno])
565 len = strlen (macro_expns->args[argno]);
566 memcpy (&buffer[result], macro_expns->args[argno], len);
570 /* Skip next space? */
571 if (expn[1] == ' ' && expn[2] == '_')
576 buffer[result++] = *expn;
577 if (*expn == ';' || *expn == '{')
578 buffer[result++] = '\n';
582 YY_FATAL_ERROR ("buffer too small to expand macro");
583 macro_expns = macro_expns->next;
585 macro_expns_end = NULL;
591 yyerror (const char *s)
593 error_at_line (&lexer_line, s);
597 parse_file (const char *fname)
599 yyin = fopen (fname, "r");
600 lexer_line.file = fname;