OSDN Git Service

Fixed erroneous ChangeLog and gcc/ChangeLog entries.
[pf3gnuchains/gcc-fork.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 }