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;
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;