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 ((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 ^"@@".* /* Used for c-parse.in C/ObjC demarcation. */
277 {WS} { update_lineno (yytext, yyleng); }
279 "const"/[^[:alnum:]_] /* don't care */
280 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
281 "union"/[^[:alnum:]_] { return UNION; }
282 "struct"/[^[:alnum:]_] { return STRUCT; }
283 "enum"/[^[:alnum:]_] { return ENUM; }
284 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
285 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
286 [0-9]+ { return NUM; }
287 "param"[0-9]*"_is"/[^[:alnum:]_] {
288 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
292 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
293 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
296 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
299 yylval.t = create_scalar_type (yytext, len);
300 update_lineno (yytext, yyleng);
304 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
306 unsigned macro_len, arg_len;
310 while (*ptr != '(' && !ISSPACE (*ptr)) /* )*/
312 macro_len = ptr - macro;
313 while (*ptr == '(' || ISSPACE (*ptr))
316 while (*ptr != ')' && !ISSPACE (*ptr))
319 ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
320 ptr[macro_len] = '_';
321 memcpy (&ptr[macro_len+1], arg, arg_len);
327 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
332 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
336 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
340 yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
343 "'"("\\".|[^\\])"'" {
344 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
348 [(){},*:<>] { return yytext[0]; }
351 if (lexer_toplevel_done)
354 lexer_toplevel_done = 0;
361 return PERCENTPERCENT;
364 "#define"[^\n]*\n {lexer_line.line++;}
367 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
371 "/*" { BEGIN(in_comment); }
372 \n { lexer_line.line++; }
374 "'"("\\".|[^\\])"'" |
375 [^"/\n] /* do nothing */
376 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
377 "/"/[^*] /* do nothing */
379 <in_comment,in_struct_comment>{
380 \n { lexer_line.line++; }
382 [^*\n] /* do nothing */
383 "*"/[^/] /* do nothing */
385 <in_comment>"*/" { BEGIN(INITIAL); }
386 <in_struct_comment>"*/" { BEGIN(in_struct); }
389 \n { lexer_line.line++; }
391 [^%] /* do nothing */
392 "%"/[^}] /* do nothing */
393 "%}" { BEGIN(in_struct); }
395 error_at_line (&lexer_line,
396 "unterminated %%{; unexpected EOF");
402 <in_struct_comment,in_comment>"*" {
403 error_at_line (&lexer_line,
404 "unterminated comment or string; unexpected EOF");
407 ^"#define"{WS}"GTY(" /* do nothing */
409 error_at_line (&lexer_line, "stray GTY marker");
414 /* Deal with the expansion caused by the DEF_VEC_x macros. */
419 const char *expansion;
423 static const macro_t macro_defs[] =
425 #define IN_GENGTYPE 1
430 /* Chain of macro expansions to do at end of scanning. */
431 static macro_t *macro_expns;
433 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
434 expansion queue. We ensure NAME is known at this point. */
437 push_macro_expansion (const char *name, unsigned name_len,
438 const char *arg, unsigned arg_len)
442 for (ix = 0; macro_defs[ix].name; ix++)
443 if (strlen (macro_defs[ix].name) == name_len
444 && !memcmp (name, macro_defs[ix].name, name_len))
446 macro_t *expansion = XNEW (macro_t);
448 expansion->next = macro_expns;
449 expansion->name = (char *) xmemdup (arg, arg_len, arg_len+1);
450 expansion->expansion = macro_defs[ix].expansion;
451 macro_expns = expansion;
454 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
455 name_len, name, arg_len, arg);
458 /* Attempt to read some input. Use fread until we're at the end of
459 file. At end of file expand the next queued macro. We presume the
460 buffer is large enough for the entire expansion. */
463 macro_input (char *buffer, unsigned size)
467 result = fread (buffer, 1, size, yyin);
470 else if (ferror (yyin))
471 YY_FATAL_ERROR ("read of source file failed");
472 else if (macro_expns)
477 for (expn = macro_expns->expansion; *expn; expn++)
481 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
483 len = strlen (macro_expns->name);
484 memcpy (&buffer[result], macro_expns->name, len);
489 buffer[result++] = *expn;
490 if (*expn == ';' || *expn == '{')
491 buffer[result++] = '\n';
495 YY_FATAL_ERROR ("buffer too small to expand macro");
496 macro_expns = macro_expns->next;
502 yyerror (const char *s)
504 error_at_line (&lexer_line, s);
508 parse_file (const char *fname)
510 yyin = fopen (fname, "r");
511 lexer_line.file = fname;