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, 59 Temple Place - Suite 330, 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 void push_macro_expansion (const char *, unsigned,
37 const char *, unsigned);
38 static void update_lineno (const char *l, size_t len);
40 struct fileloc lexer_line;
41 int lexer_toplevel_done;
44 update_lineno (const char *l, size_t len)
53 ID [[:alpha:]_][[:alnum:]_]*
55 IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD
56 ITYPE {IWORD}({WS}{IWORD})*
58 %x in_struct in_struct_comment in_comment in_yacc_escape
59 %option warn noyywrap nounput nodefault perf-report
60 %option 8bit never-interactive
63 [^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" {
72 tagstart = yytext + strlen (" typedef ");
73 while (ISSPACE (*tagstart))
75 union_p = tagstart[0] == 'u';
76 tagstart += strlen ("union ");
77 while (ISSPACE (*tagstart))
79 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
81 for (namestart = tagstart + taglen;
82 ! ISIDNUM (*namestart);
84 if (*namestart == '*')
86 for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++)
88 t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1),
91 t = create_pointer (t);
92 namestart = (char *) xmemdup (namestart, namelen, namelen+1);
93 #ifdef USE_MAPPED_LOCATION
94 /* temporary kludge - gentype doesn't handle cpp conditionals */
95 if (strcmp (namestart, "location_t") != 0
96 && strcmp (namestart, "expanded_location") != 0)
98 do_typedef (namestart, t, &lexer_line);
99 update_lineno (yytext, yyleng);
102 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
110 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
112 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
114 namestart -= namelen - 1;
115 for (typestart = yytext + strlen (" typedef ");
119 for (typelen = namestart - typestart;
120 ISSPACE (typestart[typelen-1]);
124 t = create_scalar_type (typestart, typelen);
125 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
127 update_lineno (yytext, yyleng);
130 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
135 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
137 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
139 namestart -= namelen - 1;
141 t = create_scalar_type ("function type", sizeof ("function type")-1);
142 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
144 update_lineno (yytext, yyleng);
147 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
152 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
154 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
156 namestart -= namelen - 1;
158 t = create_scalar_type ("function type", sizeof ("function type")-1);
159 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
161 update_lineno (yytext, yyleng);
164 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
169 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
171 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
173 namestart -= namelen - 1;
175 t = create_scalar_type ("function type", sizeof ("function type")-1);
176 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
178 update_lineno (yytext, yyleng);
181 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
186 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
188 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
190 namestart -= namelen - 1;
192 t = create_scalar_type ("function type", sizeof ("function type")-1);
193 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
195 update_lineno (yytext, yyleng);
198 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
204 typedef_p = yytext[1] == 't';
206 for (tagstart = yytext + strlen (" typedef ");
211 tagstart = yytext + 1;
213 union_p = tagstart[0] == 'u';
214 tagstart += strlen ("union ");
215 while (ISSPACE (*tagstart))
217 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
220 yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen,
224 update_lineno (yytext, yyleng);
225 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
228 [^[:alnum:]_](extern|static){WS}/"GTY" {
230 update_lineno (yytext, yyleng);
231 return ENT_EXTERNSTATIC;
234 ^"%union"{WS}"{"{WS}/"GTY" {
236 update_lineno (yytext, yyleng);
237 return ENT_YACCUNION;
240 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
242 unsigned macro_len, arg_len;
246 /* Locate the macro and argument strings. */
248 while (*ptr != '(' && !ISSPACE (*ptr))
250 macro_len = ptr - macro;
251 while (*ptr == '(' || ISSPACE (*ptr))
254 while (*ptr != ')' && !ISSPACE (*ptr))
258 /* Push the macro for later expansion. */
259 push_macro_expansion (macro, macro_len, arg, arg_len);
261 /* Create the struct and typedef. */
262 ptr = (char *) xmemdup ("VEC_", 4, 4 + arg_len + 1);
263 memcpy (&ptr[4], arg, arg_len);
264 ptr[4 + arg_len] = 0;
265 t = find_structure (ptr, 0);
266 do_typedef (ptr, t, &lexer_line);
271 "/*" { BEGIN(in_struct_comment); }
273 ^"%{" { BEGIN(in_yacc_escape); } /* } */
275 {WS} { update_lineno (yytext, yyleng); }
277 "const"/[^[:alnum:]_] /* don't care */
278 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
279 "union"/[^[:alnum:]_] { return UNION; }
280 "struct"/[^[:alnum:]_] { return STRUCT; }
281 "enum"/[^[:alnum:]_] { return ENUM; }
282 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
283 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
284 [0-9]+ { return NUM; }
285 "param"[0-9]*"_is"/[^[:alnum:]_] {
286 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
290 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
291 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
294 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
297 yylval.t = create_scalar_type (yytext, len);
298 update_lineno (yytext, yyleng);
302 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
304 unsigned macro_len, arg_len;
308 while (*ptr != '(' && !ISSPACE (*ptr)) /* )*/
310 macro_len = ptr - macro;
311 while (*ptr == '(' || ISSPACE (*ptr))
314 while (*ptr != ')' && !ISSPACE (*ptr))
317 ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
318 ptr[macro_len] = '_';
319 memcpy (&ptr[macro_len+1], arg, arg_len);
325 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
330 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
334 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
338 yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
341 "'"("\\".|[^\\])"'" {
342 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
346 [(){},*:<>] { return yytext[0]; }
349 if (lexer_toplevel_done)
352 lexer_toplevel_done = 0;
359 return PERCENTPERCENT;
362 "#define"[^\n]*\n {lexer_line.line++;}
365 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
369 "/*" { BEGIN(in_comment); }
370 \n { lexer_line.line++; }
372 "'"("\\".|[^\\])"'" |
373 [^"/\n] /* do nothing */
374 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
375 "/"/[^*] /* do nothing */
377 <in_comment,in_struct_comment>{
378 \n { lexer_line.line++; }
380 [^*\n] /* do nothing */
381 "*"/[^/] /* do nothing */
383 <in_comment>"*/" { BEGIN(INITIAL); }
384 <in_struct_comment>"*/" { BEGIN(in_struct); }
387 \n { lexer_line.line++; }
389 [^%] /* do nothing */
390 "%"/[^}] /* do nothing */
391 "%}" { BEGIN(in_struct); }
393 error_at_line (&lexer_line,
394 "unterminated %%{; unexpected EOF");
400 <in_struct_comment,in_comment>"*" {
401 error_at_line (&lexer_line,
402 "unterminated comment or string; unexpected EOF");
405 ^"#define"{WS}"GTY(" /* do nothing */
407 error_at_line (&lexer_line, "stray GTY marker");
412 /* Deal with the expansion caused by the DEF_VEC_x macros. */
417 const char *expansion;
421 static const macro_t macro_defs[] =
423 #define IN_GENGTYPE 1
428 /* Chain of macro expansions to do at end of scanning. */
429 static macro_t *macro_expns;
431 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
432 expansion queue. We ensure NAME is known at this point. */
435 push_macro_expansion (const char *name, unsigned name_len,
436 const char *arg, unsigned arg_len)
440 for (ix = 0; macro_defs[ix].name; ix++)
441 if (strlen (macro_defs[ix].name) == name_len
442 && !memcmp (name, macro_defs[ix].name, name_len))
444 macro_t *expansion = XNEW (macro_t);
446 expansion->next = macro_expns;
447 expansion->name = (char *) xmemdup (arg, arg_len, arg_len+1);
448 expansion->expansion = macro_defs[ix].expansion;
449 macro_expns = expansion;
452 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
453 name_len, name, arg_len, arg);
456 /* Attempt to read some input. Use fread until we're at the end of
457 file. At end of file expand the next queued macro. We presume the
458 buffer is large enough for the entire expansion. */
461 macro_input (char *buffer, unsigned size)
465 result = fread (buffer, 1, size, yyin);
468 else if (ferror (yyin))
469 YY_FATAL_ERROR ("read of source file failed");
470 else if (macro_expns)
475 for (expn = macro_expns->expansion; *expn; expn++)
479 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
481 len = strlen (macro_expns->name);
482 memcpy (&buffer[result], macro_expns->name, len);
487 buffer[result++] = *expn;
488 if (*expn == ';' || *expn == '{')
489 buffer[result++] = '\n';
493 YY_FATAL_ERROR ("buffer too small to expand macro");
494 macro_expns = macro_expns->next;
500 yyerror (const char *s)
502 error_at_line (&lexer_line, s);
506 parse_file (const char *fname)
508 yyin = fopen (fname, "r");
509 lexer_line.file = fname;