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