target.h (globalize_decl_name): New.
[gcc.git] / gcc / gengtype-lex.l
1 /* -*- indented-text -*- */
2 /* Process source files and output type information.
3 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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
10 version.
11
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
15 for more details.
16
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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22 %{
23 #include "bconfig.h"
24 #include "coretypes.h"
25 #include "system.h"
26
27 #define malloc xmalloc
28 #define realloc xrealloc
29
30 #include "gengtype.h"
31 #include "gengtype-yacc.h"
32
33 #define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE))
34
35 static unsigned macro_input (char *buffer, unsigned);
36 static const char *push_macro_expansion (const char *, unsigned,
37 const char *, unsigned);
38 static char *mangle_macro_name (const char *, unsigned,
39 const char *, unsigned);
40 static void update_lineno (const char *l, size_t len);
41
42 struct fileloc lexer_line;
43 int lexer_toplevel_done;
44
45 static void
46 update_lineno (const char *l, size_t len)
47 {
48 while (len-- > 0)
49 if (*l++ == '\n')
50 lexer_line.line++;
51 }
52
53 %}
54
55 ID [[:alpha:]_][[:alnum:]_]*
56 WS [[:space:]]+
57 IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD
58 ITYPE {IWORD}({WS}{IWORD})*
59
60 %x in_struct in_struct_comment in_comment in_yacc_escape
61 %option warn noyywrap nounput nodefault perf-report
62 %option 8bit never-interactive
63 %%
64
65 [^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" {
66 char *tagstart;
67 size_t taglen;
68 char *namestart;
69 size_t namelen;
70 int is_pointer = 0;
71 struct type *t;
72 int union_p;
73
74 tagstart = yytext + strlen (" typedef ");
75 while (ISSPACE (*tagstart))
76 tagstart++;
77 union_p = tagstart[0] == 'u';
78 tagstart += strlen ("union ");
79 while (ISSPACE (*tagstart))
80 tagstart++;
81 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
82 ;
83 for (namestart = tagstart + taglen;
84 ! ISIDNUM (*namestart);
85 namestart++)
86 if (*namestart == '*')
87 is_pointer = 1;
88 for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++)
89 ;
90 t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1),
91 union_p);
92 if (is_pointer)
93 t = create_pointer (t);
94 namestart = (char *) xmemdup (namestart, namelen, namelen+1);
95 #ifdef USE_MAPPED_LOCATION
96 /* temporary kludge - gentype doesn't handle cpp conditionals */
97 if (strcmp (namestart, "location_t") != 0
98 && strcmp (namestart, "expanded_location") != 0)
99 #endif
100 do_typedef (namestart, t, &lexer_line);
101 update_lineno (yytext, yyleng);
102 }
103
104 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
105
106 char *namestart;
107 size_t namelen;
108 struct type *t;
109 char *typestart;
110 size_t typelen;
111
112 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
113 ;
114 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
115 ;
116 namestart -= namelen - 1;
117 for (typestart = yytext + strlen (" typedef ");
118 ISSPACE(*typestart);
119 typestart++)
120 ;
121 for (typelen = namestart - typestart;
122 ISSPACE (typestart[typelen-1]);
123 typelen--)
124 ;
125
126 t = create_scalar_type (typestart, typelen);
127 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
128 &lexer_line);
129 update_lineno (yytext, yyleng);
130 }
131
132 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
133 char *namestart;
134 size_t namelen;
135 struct type *t;
136
137 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
138 ;
139 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
140 ;
141 namestart -= namelen - 1;
142
143 t = create_scalar_type ("function type", sizeof ("function type")-1);
144 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
145 &lexer_line);
146 update_lineno (yytext, yyleng);
147 }
148
149 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
150 char *namestart;
151 size_t namelen;
152 struct type *t;
153
154 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
155 ;
156 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
157 ;
158 namestart -= namelen - 1;
159
160 t = create_scalar_type ("function type", sizeof ("function type")-1);
161 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
162 &lexer_line);
163 update_lineno (yytext, yyleng);
164 }
165
166 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
167 char *namestart;
168 size_t namelen;
169 struct type *t;
170
171 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
172 ;
173 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
174 ;
175 namestart -= namelen - 1;
176
177 t = create_scalar_type ("function type", sizeof ("function type")-1);
178 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
179 &lexer_line);
180 update_lineno (yytext, yyleng);
181 }
182
183 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
184 char *namestart;
185 size_t namelen;
186 struct type *t;
187
188 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
189 ;
190 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
191 ;
192 namestart -= namelen - 1;
193
194 t = create_scalar_type ("function type", sizeof ("function type")-1);
195 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
196 &lexer_line);
197 update_lineno (yytext, yyleng);
198 }
199
200 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
201 char *tagstart;
202 size_t taglen;
203 int typedef_p;
204 int union_p;
205
206 typedef_p = yytext[1] == 't';
207 if (typedef_p)
208 for (tagstart = yytext + strlen (" typedef ");
209 ISSPACE(*tagstart);
210 tagstart++)
211 ;
212 else
213 tagstart = yytext + 1;
214
215 union_p = tagstart[0] == 'u';
216 tagstart += strlen ("union ");
217 while (ISSPACE (*tagstart))
218 tagstart++;
219 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
220 ;
221
222 yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen,
223 taglen + 1),
224 union_p);
225 BEGIN(in_struct);
226 update_lineno (yytext, yyleng);
227 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
228 }
229
230 [^[:alnum:]_](extern|static){WS}/"GTY" {
231 BEGIN(in_struct);
232 update_lineno (yytext, yyleng);
233 return ENT_EXTERNSTATIC;
234 }
235
236 ^"%union"{WS}"{"{WS}/"GTY" {
237 BEGIN(in_struct);
238 update_lineno (yytext, yyleng);
239 return ENT_YACCUNION;
240 }
241
242 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
243 char *macro, *arg;
244 unsigned macro_len, arg_len;
245 char *ptr = yytext;
246 const char *additional;
247 type_p t;
248
249 /* Find the macro name. */
250 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
251 continue;
252 for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++)
253 continue;
254
255 /* Find the argument(s). */
256 for (arg = ptr; *ptr != ')'; ptr++)
257 continue;
258 arg_len = ptr - arg;
259
260 /* Create the struct and typedef. */
261 ptr = mangle_macro_name ("VEC", 3, arg, arg_len);
262
263 t = find_structure (ptr, 0);
264 do_typedef (ptr, t, &lexer_line);
265
266 /* Push the macro for later expansion. */
267 additional = push_macro_expansion (macro, macro_len, arg, arg_len);
268
269 if (additional)
270 {
271 ptr = mangle_macro_name (ptr, strlen (ptr),
272 additional, strlen (additional));
273 t = find_structure (ptr, 0);
274 do_typedef (ptr, t, &lexer_line);
275 }
276 }
277
278 <in_struct>{
279
280 "/*" { BEGIN(in_struct_comment); }
281
282 ^"%{" { BEGIN(in_yacc_escape); } /* } */
283
284 {WS} { update_lineno (yytext, yyleng); }
285
286 "const"/[^[:alnum:]_] /* don't care */
287 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
288 "union"/[^[:alnum:]_] { return UNION; }
289 "struct"/[^[:alnum:]_] { return STRUCT; }
290 "enum"/[^[:alnum:]_] { return ENUM; }
291 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
292 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
293 [0-9]+ { return NUM; }
294 "param"[0-9]*"_is"/[^[:alnum:]_] {
295 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
296 return PARAM_IS;
297 }
298
299 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
300 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
301 size_t len;
302
303 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
304 ;
305
306 yylval.t = create_scalar_type (yytext, len);
307 update_lineno (yytext, yyleng);
308 return SCALAR;
309 }
310
311 "VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
312 char *macro, *arg;
313 unsigned macro_len, arg_len;
314 char *ptr = yytext;
315
316 /* Find the macro name */
317 for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
318 continue;
319 for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++)
320 continue;
321
322 /* Find the arguments. */
323 for (arg = ptr; *ptr != ')'; ptr++)
324 continue;
325 arg_len = ptr - arg;
326
327 ptr = mangle_macro_name (macro, macro_len, arg, arg_len);
328 yylval.s = ptr;
329 return ID;
330 }
331
332 {ID}/[^[:alnum:]_] {
333 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
334 return ID;
335 }
336
337 \"([^"\\]|\\.)*\" {
338 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
339 return STRING;
340 }
341 "["[^\[\]]*"]" {
342 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
343 return ARRAY;
344 }
345 ^"%"{ID} {
346 yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
347 return PERCENT_ID;
348 }
349 "'"("\\".|[^\\])"'" {
350 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
351 return CHAR;
352 }
353
354 [(){},*:<>] { return yytext[0]; }
355
356 [;=] {
357 if (lexer_toplevel_done)
358 {
359 BEGIN(INITIAL);
360 lexer_toplevel_done = 0;
361 }
362 return yytext[0];
363 }
364
365 ^"%%" {
366 BEGIN(INITIAL);
367 return PERCENTPERCENT;
368 }
369
370 "#define"[^\n]*\n {lexer_line.line++;}
371
372 . {
373 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
374 }
375 }
376
377 "/*" { BEGIN(in_comment); }
378 \n { lexer_line.line++; }
379 {ID} |
380 "'"("\\".|[^\\])"'" |
381 [^"/\n] /* do nothing */
382 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
383 "/"/[^*] /* do nothing */
384
385 <in_comment,in_struct_comment>{
386 \n { lexer_line.line++; }
387 [^*\n]{16} |
388 [^*\n] /* do nothing */
389 "*"/[^/] /* do nothing */
390 }
391 <in_comment>"*/" { BEGIN(INITIAL); }
392 <in_struct_comment>"*/" { BEGIN(in_struct); }
393
394 <in_yacc_escape>{
395 \n { lexer_line.line++; }
396 [^%]{16} |
397 [^%] /* do nothing */
398 "%"/[^}] /* do nothing */
399 "%}" { BEGIN(in_struct); }
400 "%" {
401 error_at_line (&lexer_line,
402 "unterminated %%{; unexpected EOF");
403 }
404 }
405
406
407 ["/] |
408 <in_struct_comment,in_comment>"*" {
409 error_at_line (&lexer_line,
410 "unterminated comment or string; unexpected EOF");
411 }
412
413 ^"#define"{WS}"GTY(" /* do nothing */
414 {WS}"GTY"{WS}?"(" {
415 error_at_line (&lexer_line, "stray GTY marker");
416 }
417
418 %%
419
420 /* Deal with the expansion caused by the DEF_VEC_x macros. */
421
422 /* Mangle a macro and argument list as done by cpp concatenation in
423 the compiler proper. */
424 static char *
425 mangle_macro_name (const char *macro, unsigned macro_len,
426 const char *arg, unsigned arg_len)
427 {
428 char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
429
430 /* Now copy and concatenate each argument */
431 while (arg_len)
432 {
433 ptr[macro_len++] = '_';
434 for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--)
435 ptr[macro_len++] = *arg++;
436 for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--)
437 arg++;
438 }
439 ptr[macro_len] = 0;
440
441 return ptr;
442 }
443
444 typedef struct macro_def
445 {
446 const char *name;
447 const char *expansion;
448 const char *additional;
449 } macro_def_t;
450
451 typedef struct macro
452 {
453 const macro_def_t *def;
454 struct macro *next;
455 const char *args[10];
456 } macro_t;
457
458 static const macro_def_t macro_defs[] =
459 {
460 #define IN_GENGTYPE 1
461 #include "vec.h"
462 {NULL, NULL, NULL}
463 };
464
465 /* Chain of macro expansions to do at end of scanning. */
466 static macro_t *macro_expns;
467 static macro_t *macro_expns_end;
468
469 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
470 expansion queue. We ensure NAME is known at this point. */
471
472 static const char *
473 push_macro_expansion (const char *name, unsigned name_len,
474 const char *arg, unsigned arg_len)
475 {
476 unsigned ix;
477
478 for (ix = 0; macro_defs[ix].name; ix++)
479 if (strlen (macro_defs[ix].name) == name_len
480 && !memcmp (name, macro_defs[ix].name, name_len))
481 {
482 macro_t *expansion = XNEW (macro_t);
483 char *args;
484 unsigned argno, last_arg;
485
486 expansion->def = &macro_defs[ix];
487 expansion->next = NULL;
488 args = (char *) xmemdup (arg, arg_len, arg_len+1);
489 args[arg_len] = 0;
490 for (argno = 0; *args;)
491 {
492 expansion->args[argno++] = args;
493 while (*args && (ISALNUM (*args) || *args == '_'))
494 args++;
495 if (argno == 1)
496 expansion->args[argno++] = "base";
497 if (!*args)
498 break;
499 *args++ = 0;
500 while (*args && !(ISALNUM (*args) || *args == '_'))
501 args++;
502 }
503 last_arg = argno;
504 for (; argno != 10; argno++)
505 expansion->args[argno] = NULL;
506 if (macro_expns_end)
507 macro_expns_end->next = expansion;
508 else
509 macro_expns = expansion;
510 macro_expns_end = expansion;
511 if (macro_defs[ix].additional)
512 {
513 macro_t *expn2 = XNEW (macro_t);
514 memcpy (expn2, expansion, sizeof (*expn2));
515 expansion = expn2;
516 expansion->def += 1;
517 expansion->args[last_arg++] = macro_defs[ix].additional;
518 macro_expns_end->next = expansion;
519 macro_expns_end = expansion;
520 }
521 if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap"))
522 expansion->args[last_arg++] = "GTY (())";
523 return macro_defs[ix].additional;
524 }
525 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
526 name_len, name, arg_len, arg);
527 return NULL;
528 }
529
530 /* Attempt to read some input. Use fread until we're at the end of
531 file. At end of file expand the next queued macro. We presume the
532 buffer is large enough for the entire expansion. */
533
534 static unsigned
535 macro_input (char *buffer, unsigned size)
536 {
537 unsigned result;
538
539 result = fread (buffer, 1, size, yyin);
540 if (result)
541 /*NOP*/;
542 else if (ferror (yyin))
543 YY_FATAL_ERROR ("read of source file failed");
544 else if (macro_expns)
545 {
546 const char *expn;
547 unsigned len;
548
549 for (expn = macro_expns->def->expansion; *expn; expn++)
550 {
551 if (*expn == '#')
552 {
553 int argno;
554
555 argno = expn[1] - '0';
556 expn += 1;
557
558 /* Remove inserted space? */
559 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
560 result--;
561
562 /* Insert the argument value */
563 if (macro_expns->args[argno])
564 {
565 len = strlen (macro_expns->args[argno]);
566 memcpy (&buffer[result], macro_expns->args[argno], len);
567 result += len;
568 }
569
570 /* Skip next space? */
571 if (expn[1] == ' ' && expn[2] == '_')
572 expn++;
573 }
574 else
575 {
576 buffer[result++] = *expn;
577 if (*expn == ';' || *expn == '{')
578 buffer[result++] = '\n';
579 }
580 }
581 if (result > size)
582 YY_FATAL_ERROR ("buffer too small to expand macro");
583 macro_expns = macro_expns->next;
584 if (!macro_expns)
585 macro_expns_end = NULL;
586 }
587 return result;
588 }
589
590 void
591 yyerror (const char *s)
592 {
593 error_at_line (&lexer_line, s);
594 }
595
596 void
597 parse_file (const char *fname)
598 {
599 yyin = fopen (fname, "r");
600 lexer_line.file = fname;
601 lexer_line.line = 1;
602 if (yyin == NULL)
603 {
604 perror (fname);
605 exit (1);
606 }
607 if (yyparse() != 0)
608 exit (1);
609 fclose (yyin);
610 }