1 /* -*- indented-text -*- */
2 /* Process source files and output type information.
3 Copyright (C) 2002, 2003, 2004 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 (xmemdup (tagstart, taglen, taglen+1), union_p);
90 t = create_pointer (t);
91 namestart = xmemdup (namestart, namelen, namelen+1);
92 #ifdef USE_MAPPED_LOCATION
93 /* temporary kludge - gentype doesn't handle cpp conditionals */
94 if (strcmp (namestart, "location_t") != 0)
96 do_typedef (namestart, t, &lexer_line);
97 update_lineno (yytext, yyleng);
100 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
108 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
110 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
112 namestart -= namelen - 1;
113 for (typestart = yytext + strlen (" typedef ");
117 for (typelen = namestart - typestart;
118 ISSPACE(typestart[typelen-1]);
122 t = create_scalar_type (typestart, typelen);
123 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
124 update_lineno (yytext, yyleng);
127 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
132 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
134 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
136 namestart -= namelen - 1;
138 t = create_scalar_type ("function type", sizeof ("function type")-1);
139 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
140 update_lineno (yytext, yyleng);
143 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
148 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
150 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
152 namestart -= namelen - 1;
154 t = create_scalar_type ("function type", sizeof ("function type")-1);
155 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
156 update_lineno (yytext, yyleng);
159 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
164 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
166 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
168 namestart -= namelen - 1;
170 t = create_scalar_type ("function type", sizeof ("function type")-1);
171 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
172 update_lineno (yytext, yyleng);
175 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
180 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
182 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
184 namestart -= namelen - 1;
186 t = create_scalar_type ("function type", sizeof ("function type")-1);
187 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
188 update_lineno (yytext, yyleng);
191 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
197 typedef_p = yytext[1] == 't';
199 for (tagstart = yytext + strlen (" typedef ");
204 tagstart = yytext + 1;
206 union_p = tagstart[0] == 'u';
207 tagstart += strlen ("union ");
208 while (ISSPACE (*tagstart))
210 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
213 yylval.t = find_structure (xmemdup (tagstart, taglen, taglen + 1), union_p);
215 update_lineno (yytext, yyleng);
216 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
219 [^[:alnum:]_](extern|static){WS}/"GTY" {
221 update_lineno (yytext, yyleng);
222 return ENT_EXTERNSTATIC;
225 ^"%union"{WS}"{"{WS}/"GTY" {
227 update_lineno (yytext, yyleng);
228 return ENT_YACCUNION;
231 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
233 unsigned macro_len, arg_len;
237 /* Locate the macro and argument strings. */
239 while (*ptr != '(' && !ISSPACE (*ptr))
241 macro_len = ptr - macro;
242 while (*ptr == '(' || ISSPACE (*ptr))
245 while (*ptr != ')' && !ISSPACE (*ptr))
249 /* Push the macro for later expansion. */
250 push_macro_expansion (macro, macro_len, arg, arg_len);
252 /* Create the struct and typedef. */
253 ptr = xmemdup ("VEC_", 4, 4 + arg_len + 1);
254 memcpy (&ptr[4], arg, arg_len);
255 ptr[4 + arg_len] = 0;
256 t = find_structure (ptr, 0);
257 do_typedef (ptr, t, &lexer_line);
262 "/*" { BEGIN(in_struct_comment); }
264 ^"%{" { BEGIN(in_yacc_escape); }
266 ^"@@".* /* Used for c-parse.in C/ObjC demarcation. */
268 {WS} { update_lineno (yytext, yyleng); }
270 "const"/[^[:alnum:]_] /* don't care */
271 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
272 "union"/[^[:alnum:]_] { return UNION; }
273 "struct"/[^[:alnum:]_] { return STRUCT; }
274 "enum"/[^[:alnum:]_] { return ENUM; }
275 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
276 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
277 [0-9]+ { return NUM; }
278 "param"[0-9]*"_is"/[^[:alnum:]_] {
279 yylval.s = xmemdup (yytext, yyleng, yyleng+1);
283 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
284 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
287 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
290 yylval.t = create_scalar_type (yytext, len);
291 update_lineno (yytext, yyleng);
295 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
297 unsigned macro_len, arg_len;
301 while (*ptr != '(' && !ISSPACE (*ptr))
303 macro_len = ptr - macro;
304 while (*ptr == '(' || ISSPACE (*ptr))
307 while (*ptr != ')' && !ISSPACE (*ptr))
310 ptr = xmemdup (macro, macro_len, macro_len + arg_len + 2);
311 ptr[macro_len] = '_';
312 memcpy (&ptr[macro_len+1], arg, arg_len);
318 yylval.s = xmemdup (yytext, yyleng, yyleng+1);
323 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
327 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
331 yylval.s = xmemdup (yytext+1, yyleng-1, yyleng);
334 "'"("\\".|[^\\])"'" {
335 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng);
339 [(){},*:<>] { return yytext[0]; }
342 if (lexer_toplevel_done)
345 lexer_toplevel_done = 0;
352 return PERCENTPERCENT;
356 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
360 "/*" { BEGIN(in_comment); }
361 \n { lexer_line.line++; }
363 "'"("\\".|[^\\])"'" |
364 [^"/\n] /* do nothing */
365 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
366 "/"/[^*] /* do nothing */
368 <in_comment,in_struct_comment>{
369 \n { lexer_line.line++; }
371 [^*\n] /* do nothing */
372 "*"/[^/] /* do nothing */
374 <in_comment>"*/" { BEGIN(INITIAL); }
375 <in_struct_comment>"*/" { BEGIN(in_struct); }
378 \n { lexer_line.line++; }
380 [^%] /* do nothing */
381 "%"/[^}] /* do nothing */
382 "%}" { BEGIN(in_struct); }
384 error_at_line (&lexer_line,
385 "unterminated %%{; unexpected EOF");
391 <in_struct_comment,in_comment>"*" {
392 error_at_line (&lexer_line,
393 "unterminated comment or string; unexpected EOF");
396 ^"#define"{WS}"GTY(" /* do nothing */
398 error_at_line (&lexer_line, "stray GTY marker");
403 /* Deal with the expansion caused by the DEF_VEC_x macros. */
408 const char *expansion;
412 static const macro_t macro_defs[] =
414 #define IN_GENGTYPE 1
419 /* Chain of macro expansions to do at end of scanning. */
420 static macro_t *macro_expns;
422 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
423 expansion queue. We ensure NAME is known at this point. */
426 push_macro_expansion (const char *name, unsigned name_len,
427 const char *arg, unsigned arg_len)
431 for (ix = 0; macro_defs[ix].name; ix++)
432 if (strlen (macro_defs[ix].name) == name_len
433 && !memcmp (name, macro_defs[ix].name, name_len))
435 macro_t *expansion = xmalloc (sizeof (*expansion));
437 expansion->next = macro_expns;
438 expansion->name = xmemdup (arg, arg_len, arg_len+1);
439 expansion->expansion = macro_defs[ix].expansion;
440 macro_expns = expansion;
443 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
444 name_len, name, arg_len, arg);
447 /* Attempt to read some input. Use fread until we're at the end of
448 file. At end of file expand the next queued macro. We presume the
449 buffer is large enough for the entire expansion. */
452 macro_input (char *buffer, unsigned size)
456 result = fread (buffer, 1, size, yyin);
459 else if (ferror (yyin))
460 YY_FATAL_ERROR ("read of source file failed");
461 else if (macro_expns)
466 for (expn = macro_expns->expansion; *expn; expn++)
470 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
472 len = strlen (macro_expns->name);
473 memcpy (&buffer[result], macro_expns->name, len);
478 buffer[result++] = *expn;
479 if (*expn == ';' || *expn == '{')
480 buffer[result++] = '\n';
484 YY_FATAL_ERROR ("buffer too small to expand macro");
485 macro_expns = macro_expns->next;
491 yyerror (const char *s)
493 error_at_line (&lexer_line, s);
497 parse_file (const char *fname)
499 yyin = fopen (fname, "r");
500 lexer_line.file = fname;