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
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}"(" {
137 for (namestart = yytext + yyleng - 2; 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}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
154 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
156 for (namelen = 1; ISIDNUM (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})?(struct|union){WS}{ID}{WS}/"GTY" {
172 typedef_p = yytext[1] == 't';
174 for (tagstart = yytext + strlen (" typedef ");
179 tagstart = yytext + 1;
181 union_p = tagstart[0] == 'u';
182 tagstart += strlen ("union ");
183 while (ISSPACE (*tagstart))
185 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
188 yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen,
192 update_lineno (yytext, yyleng);
193 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
196 [^[:alnum:]_](extern|static){WS}/"GTY" {
198 update_lineno (yytext, yyleng);
199 return ENT_EXTERNSTATIC;
202 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
204 unsigned macro_len, arg_len;
206 const char *additional;
209 /* Find the macro name. */
210 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
212 for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++)
215 /* Find the argument(s). */
216 for (arg = ptr; *ptr != ')'; ptr++)
220 /* Create the struct and typedef. */
221 ptr = mangle_macro_name ("VEC", 3, arg, arg_len);
223 t = find_structure (ptr, 0);
224 do_typedef (ptr, t, &lexer_line);
226 /* Push the macro for later expansion. */
227 additional = push_macro_expansion (macro, macro_len, arg, arg_len);
231 ptr = mangle_macro_name (ptr, strlen (ptr),
232 additional, strlen (additional));
233 t = find_structure (ptr, 0);
234 do_typedef (ptr, t, &lexer_line);
240 "/*" { BEGIN(in_struct_comment); }
242 {WS} { update_lineno (yytext, yyleng); }
244 "const"/[^[:alnum:]_] /* don't care */
245 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
246 "union"/[^[:alnum:]_] { return UNION; }
247 "struct"/[^[:alnum:]_] { return STRUCT; }
248 "enum"/[^[:alnum:]_] { return ENUM; }
249 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
250 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
251 [0-9]+ { return NUM; }
252 "param"[0-9]*"_is"/[^[:alnum:]_] {
253 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
257 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
258 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
261 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
264 yylval.t = create_scalar_type (yytext, len);
265 update_lineno (yytext, yyleng);
269 "VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
271 unsigned macro_len, arg_len;
274 /* Find the macro name */
275 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
277 for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++)
280 /* Find the arguments. */
281 for (arg = ptr; *ptr != ')'; ptr++)
285 ptr = mangle_macro_name (macro, macro_len, arg, arg_len);
291 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
296 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
300 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
303 "'"("\\".|[^\\])"'" {
304 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
308 [(){},*:<>] { return yytext[0]; }
311 if (lexer_toplevel_done)
314 lexer_toplevel_done = 0;
319 "#define"[^\n]*\n {lexer_line.line++;}
322 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
326 "/*" { BEGIN(in_comment); }
327 \n { lexer_line.line++; }
329 "'"("\\".|[^\\])"'" |
330 [^"/\n] /* do nothing */
331 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
332 "/"/[^*] /* do nothing */
334 <in_comment,in_struct_comment>{
335 \n { lexer_line.line++; }
337 [^*\n] /* do nothing */
338 "*"/[^/] /* do nothing */
340 <in_comment>"*/" { BEGIN(INITIAL); }
341 <in_struct_comment>"*/" { BEGIN(in_struct); }
344 <in_struct_comment,in_comment>"*" {
345 error_at_line (&lexer_line,
346 "unterminated comment or string; unexpected EOF");
349 ^"#define"{WS}"GTY(" /* do nothing */
351 error_at_line (&lexer_line, "stray GTY marker");
356 /* Deal with the expansion caused by the DEF_VEC_x macros. */
358 /* Mangle a macro and argument list as done by cpp concatenation in
359 the compiler proper. */
361 mangle_macro_name (const char *macro, unsigned macro_len,
362 const char *arg, unsigned arg_len)
364 char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
366 /* Now copy and concatenate each argument */
369 ptr[macro_len++] = '_';
370 for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--)
371 ptr[macro_len++] = *arg++;
372 for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--)
380 typedef struct macro_def
383 const char *expansion;
384 const char *additional;
389 const macro_def_t *def;
391 const char *args[10];
394 static const macro_def_t macro_defs[] =
396 #define IN_GENGTYPE 1
401 /* Chain of macro expansions to do at end of scanning. */
402 static macro_t *macro_expns;
403 static macro_t *macro_expns_end;
405 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
406 expansion queue. We ensure NAME is known at this point. */
409 push_macro_expansion (const char *name, unsigned name_len,
410 const char *arg, unsigned arg_len)
414 for (ix = 0; macro_defs[ix].name; ix++)
415 if (strlen (macro_defs[ix].name) == name_len
416 && !memcmp (name, macro_defs[ix].name, name_len))
418 macro_t *expansion = XNEW (macro_t);
420 unsigned argno, last_arg;
422 expansion->def = ¯o_defs[ix];
423 expansion->next = NULL;
424 args = (char *) xmemdup (arg, arg_len, arg_len+1);
426 for (argno = 0; *args;)
428 expansion->args[argno++] = args;
429 while (*args && (ISALNUM (*args) || *args == '_'))
432 expansion->args[argno++] = "base";
436 while (*args && !(ISALNUM (*args) || *args == '_'))
440 for (; argno != 10; argno++)
441 expansion->args[argno] = NULL;
443 macro_expns_end->next = expansion;
445 macro_expns = expansion;
446 macro_expns_end = expansion;
447 if (macro_defs[ix].additional)
449 macro_t *expn2 = XNEW (macro_t);
450 memcpy (expn2, expansion, sizeof (*expn2));
453 expansion->args[last_arg++] = macro_defs[ix].additional;
454 macro_expns_end->next = expansion;
455 macro_expns_end = expansion;
457 if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap"))
458 expansion->args[last_arg++] = "GTY (())";
459 return macro_defs[ix].additional;
461 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
462 name_len, name, arg_len, arg);
466 /* Attempt to read some input. Use fread until we're at the end of
467 file. At end of file expand the next queued macro. We presume the
468 buffer is large enough for the entire expansion. */
471 macro_input (char *buffer, unsigned size)
475 result = fread (buffer, 1, size, yyin);
478 else if (ferror (yyin))
479 YY_FATAL_ERROR ("read of source file failed");
480 else if (macro_expns)
485 for (expn = macro_expns->def->expansion; *expn; expn++)
491 argno = expn[1] - '0';
494 /* Remove inserted space? */
495 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
498 /* Insert the argument value */
499 if (macro_expns->args[argno])
501 len = strlen (macro_expns->args[argno]);
502 memcpy (&buffer[result], macro_expns->args[argno], len);
506 /* Skip next space? */
507 if (expn[1] == ' ' && expn[2] == '_')
512 buffer[result++] = *expn;
513 if (*expn == ';' || *expn == '{')
514 buffer[result++] = '\n';
518 YY_FATAL_ERROR ("buffer too small to expand macro");
519 macro_expns = macro_expns->next;
521 macro_expns_end = NULL;
527 yyerror (const char *s)
529 error_at_line (&lexer_line, s);
533 parse_file (const char *fname)
535 yyin = fopen (fname, "r");
536 lexer_line.file = fname;