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 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
92 update_lineno (yytext, yyleng);
95 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
103 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
105 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
107 namestart -= namelen - 1;
108 for (typestart = yytext + strlen (" typedef ");
112 for (typelen = namestart - typestart;
113 ISSPACE(typestart[typelen-1]);
117 t = create_scalar_type (typestart, typelen);
118 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
119 update_lineno (yytext, yyleng);
122 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
127 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
129 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
131 namestart -= namelen - 1;
133 t = create_scalar_type ("function type", sizeof ("function type")-1);
134 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
135 update_lineno (yytext, yyleng);
138 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
143 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
145 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
147 namestart -= namelen - 1;
149 t = create_scalar_type ("function type", sizeof ("function type")-1);
150 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
151 update_lineno (yytext, yyleng);
154 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
159 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
161 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
163 namestart -= namelen - 1;
165 t = create_scalar_type ("function type", sizeof ("function type")-1);
166 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
167 update_lineno (yytext, yyleng);
170 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
175 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
177 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
179 namestart -= namelen - 1;
181 t = create_scalar_type ("function type", sizeof ("function type")-1);
182 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
183 update_lineno (yytext, yyleng);
186 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
192 typedef_p = yytext[1] == 't';
194 for (tagstart = yytext + strlen (" typedef ");
199 tagstart = yytext + 1;
201 union_p = tagstart[0] == 'u';
202 tagstart += strlen ("union ");
203 while (ISSPACE (*tagstart))
205 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
208 yylval.t = find_structure (xmemdup (tagstart, taglen, taglen + 1), union_p);
210 update_lineno (yytext, yyleng);
211 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
214 [^[:alnum:]_](extern|static){WS}/"GTY" {
216 update_lineno (yytext, yyleng);
217 return ENT_EXTERNSTATIC;
220 ^"%union"{WS}"{"{WS}/"GTY" {
222 update_lineno (yytext, yyleng);
223 return ENT_YACCUNION;
226 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
228 unsigned macro_len, arg_len;
232 /* Locate the macro and argument strings. */
234 while (*ptr != '(' && !ISSPACE (*ptr))
236 macro_len = ptr - macro;
237 while (*ptr == '(' || ISSPACE (*ptr))
240 while (*ptr != ')' && !ISSPACE (*ptr))
244 /* Push the macro for later expansion. */
245 push_macro_expansion (macro, macro_len, arg, arg_len);
247 /* Create the struct and typedef. */
248 ptr = xmemdup ("VEC_", 4, 4 + arg_len + 1);
249 memcpy (&ptr[4], arg, arg_len);
250 ptr[4 + arg_len] = 0;
251 t = find_structure (ptr, 0);
252 do_typedef (ptr, t, &lexer_line);
257 "/*" { BEGIN(in_struct_comment); }
259 ^"%{" { BEGIN(in_yacc_escape); }
261 ^"@@".* /* Used for c-parse.in C/ObjC demarcation. */
263 {WS} { update_lineno (yytext, yyleng); }
265 "const"/[^[:alnum:]_] /* don't care */
266 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
267 "union"/[^[:alnum:]_] { return UNION; }
268 "struct"/[^[:alnum:]_] { return STRUCT; }
269 "enum"/[^[:alnum:]_] { return ENUM; }
270 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
271 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
272 [0-9]+ { return NUM; }
273 "param"[0-9]*"_is"/[^[:alnum:]_] {
274 yylval.s = xmemdup (yytext, yyleng, yyleng+1);
278 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
279 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
282 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
285 yylval.t = create_scalar_type (yytext, len);
286 update_lineno (yytext, yyleng);
290 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
292 unsigned macro_len, arg_len;
296 while (*ptr != '(' && !ISSPACE (*ptr))
298 macro_len = ptr - macro;
299 while (*ptr == '(' || ISSPACE (*ptr))
302 while (*ptr != ')' && !ISSPACE (*ptr))
305 ptr = xmemdup (macro, macro_len, macro_len + arg_len + 2);
306 ptr[macro_len] = '_';
307 memcpy (&ptr[macro_len+1], arg, arg_len);
313 yylval.s = xmemdup (yytext, yyleng, yyleng+1);
318 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
322 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
326 yylval.s = xmemdup (yytext+1, yyleng-1, yyleng);
329 "'"("\\".|[^\\])"'" {
330 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng);
334 [(){},*:<>] { return yytext[0]; }
337 if (lexer_toplevel_done)
340 lexer_toplevel_done = 0;
347 return PERCENTPERCENT;
351 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
355 "/*" { BEGIN(in_comment); }
356 \n { lexer_line.line++; }
358 "'"("\\".|[^\\])"'" |
359 [^"/\n] /* do nothing */
360 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
361 "/"/[^*] /* do nothing */
363 <in_comment,in_struct_comment>{
364 \n { lexer_line.line++; }
366 [^*\n] /* do nothing */
367 "*"/[^/] /* do nothing */
369 <in_comment>"*/" { BEGIN(INITIAL); }
370 <in_struct_comment>"*/" { BEGIN(in_struct); }
373 \n { lexer_line.line++; }
375 [^%] /* do nothing */
376 "%"/[^}] /* do nothing */
377 "%}" { BEGIN(in_struct); }
379 error_at_line (&lexer_line,
380 "unterminated %%{; unexpected EOF");
386 <in_struct_comment,in_comment>"*" {
387 error_at_line (&lexer_line,
388 "unterminated comment or string; unexpected EOF");
391 ^"#define"{WS}"GTY(" /* do nothing */
393 error_at_line (&lexer_line, "stray GTY marker");
398 /* Deal with the expansion caused by the DEF_VEC_x macros. */
403 const char *expansion;
407 static const macro_t macro_defs[] =
409 #define IN_GENGTYPE 1
414 /* Chain of macro expansions to do at end of scanning. */
415 static macro_t *macro_expns;
417 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
418 expansion queue. We ensure NAME is known at this point. */
421 push_macro_expansion (const char *name, unsigned name_len,
422 const char *arg, unsigned arg_len)
426 for (ix = 0; macro_defs[ix].name; ix++)
427 if (strlen (macro_defs[ix].name) == name_len
428 && !memcmp (name, macro_defs[ix].name, name_len))
430 macro_t *expansion = xmalloc (sizeof (*expansion));
432 expansion->next = macro_expns;
433 expansion->name = xmemdup (arg, arg_len, arg_len+1);
434 expansion->expansion = macro_defs[ix].expansion;
435 macro_expns = expansion;
438 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
439 name_len, name, arg_len, arg);
442 /* Attempt to read some input. Use fread until we're at the end of
443 file. At end of file expand the next queued macro. We presume the
444 buffer is large enough for the entire expansion. */
447 macro_input (char *buffer, unsigned size)
451 result = fread (buffer, 1, size, yyin);
454 else if (ferror (yyin))
455 YY_FATAL_ERROR ("read of source file failed");
456 else if (macro_expns)
461 for (expn = macro_expns->expansion; *expn; expn++)
465 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
467 len = strlen (macro_expns->name);
468 memcpy (&buffer[result], macro_expns->name, len);
473 buffer[result++] = *expn;
474 if (*expn == ';' || *expn == '{')
475 buffer[result++] = '\n';
479 YY_FATAL_ERROR ("buffer too small to expand macro");
480 macro_expns = macro_expns->next;
486 yyerror (const char *s)
488 error_at_line (&lexer_line, s);
492 parse_file (const char *fname)
494 yyin = fopen (fname, "r");
495 lexer_line.file = fname;