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
95 && strcmp (namestart, "expanded_location") != 0)
97 do_typedef (namestart, t, &lexer_line);
98 update_lineno (yytext, yyleng);
101 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
109 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
111 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
113 namestart -= namelen - 1;
114 for (typestart = yytext + strlen (" typedef ");
118 for (typelen = namestart - typestart;
119 ISSPACE(typestart[typelen-1]);
123 t = create_scalar_type (typestart, typelen);
124 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
125 update_lineno (yytext, yyleng);
128 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
133 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
135 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
137 namestart -= namelen - 1;
139 t = create_scalar_type ("function type", sizeof ("function type")-1);
140 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
141 update_lineno (yytext, yyleng);
144 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
149 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
151 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
153 namestart -= namelen - 1;
155 t = create_scalar_type ("function type", sizeof ("function type")-1);
156 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
157 update_lineno (yytext, yyleng);
160 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
165 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
167 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
169 namestart -= namelen - 1;
171 t = create_scalar_type ("function type", sizeof ("function type")-1);
172 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
173 update_lineno (yytext, yyleng);
176 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
181 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
183 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
185 namestart -= namelen - 1;
187 t = create_scalar_type ("function type", sizeof ("function type")-1);
188 do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
189 update_lineno (yytext, yyleng);
192 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
198 typedef_p = yytext[1] == 't';
200 for (tagstart = yytext + strlen (" typedef ");
205 tagstart = yytext + 1;
207 union_p = tagstart[0] == 'u';
208 tagstart += strlen ("union ");
209 while (ISSPACE (*tagstart))
211 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
214 yylval.t = find_structure (xmemdup (tagstart, taglen, taglen + 1), union_p);
216 update_lineno (yytext, yyleng);
217 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
220 [^[:alnum:]_](extern|static){WS}/"GTY" {
222 update_lineno (yytext, yyleng);
223 return ENT_EXTERNSTATIC;
226 ^"%union"{WS}"{"{WS}/"GTY" {
228 update_lineno (yytext, yyleng);
229 return ENT_YACCUNION;
232 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
234 unsigned macro_len, arg_len;
238 /* Locate the macro and argument strings. */
240 while (*ptr != '(' && !ISSPACE (*ptr))
242 macro_len = ptr - macro;
243 while (*ptr == '(' || ISSPACE (*ptr))
246 while (*ptr != ')' && !ISSPACE (*ptr))
250 /* Push the macro for later expansion. */
251 push_macro_expansion (macro, macro_len, arg, arg_len);
253 /* Create the struct and typedef. */
254 ptr = xmemdup ("VEC_", 4, 4 + arg_len + 1);
255 memcpy (&ptr[4], arg, arg_len);
256 ptr[4 + arg_len] = 0;
257 t = find_structure (ptr, 0);
258 do_typedef (ptr, t, &lexer_line);
263 "/*" { BEGIN(in_struct_comment); }
265 ^"%{" { BEGIN(in_yacc_escape); }
267 ^"@@".* /* Used for c-parse.in C/ObjC demarcation. */
269 {WS} { update_lineno (yytext, yyleng); }
271 "const"/[^[:alnum:]_] /* don't care */
272 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
273 "union"/[^[:alnum:]_] { return UNION; }
274 "struct"/[^[:alnum:]_] { return STRUCT; }
275 "enum"/[^[:alnum:]_] { return ENUM; }
276 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
277 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
278 [0-9]+ { return NUM; }
279 "param"[0-9]*"_is"/[^[:alnum:]_] {
280 yylval.s = xmemdup (yytext, yyleng, yyleng+1);
284 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
285 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
288 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
291 yylval.t = create_scalar_type (yytext, len);
292 update_lineno (yytext, yyleng);
296 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
298 unsigned macro_len, arg_len;
302 while (*ptr != '(' && !ISSPACE (*ptr))
304 macro_len = ptr - macro;
305 while (*ptr == '(' || ISSPACE (*ptr))
308 while (*ptr != ')' && !ISSPACE (*ptr))
311 ptr = xmemdup (macro, macro_len, macro_len + arg_len + 2);
312 ptr[macro_len] = '_';
313 memcpy (&ptr[macro_len+1], arg, arg_len);
319 yylval.s = xmemdup (yytext, yyleng, yyleng+1);
324 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
328 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
332 yylval.s = xmemdup (yytext+1, yyleng-1, yyleng);
335 "'"("\\".|[^\\])"'" {
336 yylval.s = xmemdup (yytext+1, yyleng-2, yyleng);
340 [(){},*:<>] { return yytext[0]; }
343 if (lexer_toplevel_done)
346 lexer_toplevel_done = 0;
353 return PERCENTPERCENT;
357 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
361 "/*" { BEGIN(in_comment); }
362 \n { lexer_line.line++; }
364 "'"("\\".|[^\\])"'" |
365 [^"/\n] /* do nothing */
366 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
367 "/"/[^*] /* do nothing */
369 <in_comment,in_struct_comment>{
370 \n { lexer_line.line++; }
372 [^*\n] /* do nothing */
373 "*"/[^/] /* do nothing */
375 <in_comment>"*/" { BEGIN(INITIAL); }
376 <in_struct_comment>"*/" { BEGIN(in_struct); }
379 \n { lexer_line.line++; }
381 [^%] /* do nothing */
382 "%"/[^}] /* do nothing */
383 "%}" { BEGIN(in_struct); }
385 error_at_line (&lexer_line,
386 "unterminated %%{; unexpected EOF");
392 <in_struct_comment,in_comment>"*" {
393 error_at_line (&lexer_line,
394 "unterminated comment or string; unexpected EOF");
397 ^"#define"{WS}"GTY(" /* do nothing */
399 error_at_line (&lexer_line, "stray GTY marker");
404 /* Deal with the expansion caused by the DEF_VEC_x macros. */
409 const char *expansion;
413 static const macro_t macro_defs[] =
415 #define IN_GENGTYPE 1
420 /* Chain of macro expansions to do at end of scanning. */
421 static macro_t *macro_expns;
423 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
424 expansion queue. We ensure NAME is known at this point. */
427 push_macro_expansion (const char *name, unsigned name_len,
428 const char *arg, unsigned arg_len)
432 for (ix = 0; macro_defs[ix].name; ix++)
433 if (strlen (macro_defs[ix].name) == name_len
434 && !memcmp (name, macro_defs[ix].name, name_len))
436 macro_t *expansion = xmalloc (sizeof (*expansion));
438 expansion->next = macro_expns;
439 expansion->name = xmemdup (arg, arg_len, arg_len+1);
440 expansion->expansion = macro_defs[ix].expansion;
441 macro_expns = expansion;
444 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
445 name_len, name, arg_len, arg);
448 /* Attempt to read some input. Use fread until we're at the end of
449 file. At end of file expand the next queued macro. We presume the
450 buffer is large enough for the entire expansion. */
453 macro_input (char *buffer, unsigned size)
457 result = fread (buffer, 1, size, yyin);
460 else if (ferror (yyin))
461 YY_FATAL_ERROR ("read of source file failed");
462 else if (macro_expns)
467 for (expn = macro_expns->expansion; *expn; expn++)
471 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
473 len = strlen (macro_expns->name);
474 memcpy (&buffer[result], macro_expns->name, len);
479 buffer[result++] = *expn;
480 if (*expn == ';' || *expn == '{')
481 buffer[result++] = '\n';
485 YY_FATAL_ERROR ("buffer too small to expand macro");
486 macro_expns = macro_expns->next;
492 yyerror (const char *s)
494 error_at_line (&lexer_line, s);
498 parse_file (const char *fname)
500 yyin = fopen (fname, "r");
501 lexer_line.file = fname;