PR c++/16115
[official-gcc.git] / gcc / gengtype-lex.l
blob60b738eadce98df8bd2b2ee987d39229bf3fdba8
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
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 COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
23 #include "bconfig.h"
24 #include "coretypes.h"
25 #include "system.h"
27 #define malloc xmalloc
28 #define realloc xrealloc
30 #include "gengtype.h"
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;
43 static void 
44 update_lineno (const char *l, size_t len)
46   while (len-- > 0)
47     if (*l++ == '\n')
48       lexer_line.line++;
53 ID      [[:alpha:]_][[:alnum:]_]*
54 WS      [[:space:]]+
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}?";" {
64   char *tagstart;
65   size_t taglen;
66   char *namestart;
67   size_t namelen;
68   int is_pointer = 0;
69   struct type *t;
70   int union_p;
72   tagstart = yytext + strlen (" typedef ");
73   while (ISSPACE (*tagstart))
74     tagstart++;
75   union_p = tagstart[0] == 'u';
76   tagstart += strlen ("union ");
77   while (ISSPACE (*tagstart))
78     tagstart++;
79   for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
80     ;
81   for (namestart = tagstart + taglen; 
82        ! ISIDNUM (*namestart);
83        namestart++)
84     if (*namestart == '*')
85       is_pointer = 1;
86   for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++)
87     ;
88   t = find_structure (xmemdup (tagstart, taglen, taglen+1), union_p);
89   if (is_pointer)
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)
96 #endif
97   do_typedef (namestart, t, &lexer_line);
98   update_lineno (yytext, yyleng);
101 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
103   char *namestart;
104   size_t namelen;
105   struct type *t;
106   char *typestart;
107   size_t typelen;
109   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
110     ;
111   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
112     ;
113   namestart -= namelen - 1;
114   for (typestart = yytext + strlen (" typedef "); 
115        ISSPACE(*typestart);
116        typestart++)
117     ;
118   for (typelen = namestart - typestart; 
119        ISSPACE(typestart[typelen-1]); 
120        typelen--)
121     ;
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 {
129   char *namestart;
130   size_t namelen;
131   struct type *t;
133   for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
134     ;
135   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
136     ;
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}"(" {
145   char *namestart;
146   size_t namelen;
147   struct type *t;
149   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
150     ;
151   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
152     ;
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 {
161   char *namestart;
162   size_t namelen;
163   struct type *t;
165   for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
166     ;
167   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
168     ;
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}?"(" {
177   char *namestart;
178   size_t namelen;
179   struct type *t;
181   for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
182     ;
183   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
184     ;
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" {
193   char *tagstart;
194   size_t taglen;
195   int typedef_p;
196   int union_p;
198   typedef_p = yytext[1] == 't';
199   if (typedef_p)
200     for (tagstart = yytext + strlen (" typedef "); 
201          ISSPACE(*tagstart);
202          tagstart++)
203       ;
204   else
205     tagstart = yytext + 1;
207   union_p = tagstart[0] == 'u';
208   tagstart += strlen ("union ");
209   while (ISSPACE (*tagstart))
210     tagstart++;
211   for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
212     ;
214   yylval.t = find_structure (xmemdup (tagstart, taglen, taglen + 1), union_p);
215   BEGIN(in_struct);
216   update_lineno (yytext, yyleng);
217   return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
220 [^[:alnum:]_](extern|static){WS}/"GTY" {
221   BEGIN(in_struct);
222   update_lineno (yytext, yyleng);
223   return ENT_EXTERNSTATIC;
226 ^"%union"{WS}"{"{WS}/"GTY" {
227   BEGIN(in_struct);
228   update_lineno (yytext, yyleng);
229   return ENT_YACCUNION;
232 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
233   char *macro, *arg;
234   unsigned macro_len, arg_len;
235   char *ptr = yytext;
236   type_p t;
238   /* Locate the macro and argument strings.  */
239   macro = ptr;
240   while (*ptr != '(' && !ISSPACE (*ptr))
241     ptr++;
242   macro_len = ptr - macro;
243   while (*ptr == '(' || ISSPACE (*ptr))
244     ptr++;
245   arg = ptr;
246   while (*ptr != ')' && !ISSPACE (*ptr))
247     ptr++;
248   arg_len = ptr - arg;
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);
261 <in_struct>{
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);
281   return PARAM_IS;
284 {IWORD}({WS}{IWORD})*/[^[:alnum:]_]             |
285 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")"        {
286   size_t len;
288   for (len = yyleng; ISSPACE (yytext[len-1]); len--)
289     ;
291   yylval.t = create_scalar_type (yytext, len);
292   update_lineno (yytext, yyleng);
293   return SCALAR;
296 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
297   char *macro, *arg;
298   unsigned macro_len, arg_len;
299   char *ptr = yytext;
301   macro = ptr;
302   while (*ptr != '(' && !ISSPACE (*ptr))
303     ptr++;
304   macro_len = ptr - macro;
305   while (*ptr == '(' || ISSPACE (*ptr))
306     ptr++;
307   arg = ptr;
308   while (*ptr != ')' && !ISSPACE (*ptr))
309     ptr++;
310   arg_len = ptr - arg;
311   ptr = xmemdup (macro, macro_len, macro_len + arg_len + 2);
312   ptr[macro_len] = '_';
313   memcpy (&ptr[macro_len+1], arg, arg_len);
314   yylval.s = ptr;
315   return ID;
318 {ID}/[^[:alnum:]_]              {
319   yylval.s = xmemdup (yytext, yyleng, yyleng+1);
320   return ID;
323 \"([^"\\]|\\.)*\"               {
324   yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
325   return STRING;
327 "["[^\[\]]*"]"                  {
328   yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
329   return ARRAY;
331 ^"%"{ID}                        {
332   yylval.s = xmemdup (yytext+1, yyleng-1, yyleng);
333   return PERCENT_ID;
335 "'"("\\".|[^\\])"'"             {
336   yylval.s = xmemdup (yytext+1, yyleng-2, yyleng);
337   return CHAR;
340 [(){},*:<>]                     { return yytext[0]; }
342 [;=]                            {
343   if (lexer_toplevel_done)
344     {
345       BEGIN(INITIAL);
346       lexer_toplevel_done = 0;
347     }
348   return yytext[0];
351 ^"%%"                           {
352   BEGIN(INITIAL);
353   return PERCENTPERCENT;
356 .                               {
357   error_at_line (&lexer_line, "unexpected character `%s'", yytext);
361 "/*"                    { BEGIN(in_comment); }
362 \n                      { lexer_line.line++; }
363 {ID}                    |
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++; }
371 [^*\n]{16}      |
372 [^*\n]          /* do nothing */
373 "*"/[^/]        /* do nothing */
375 <in_comment>"*/"        { BEGIN(INITIAL); } 
376 <in_struct_comment>"*/" { BEGIN(in_struct); }
378 <in_yacc_escape>{
379 \n              { lexer_line.line++; }
380 [^%]{16}        |
381 [^%]            /* do nothing */
382 "%"/[^}]        /* do nothing */
383 "%}"            { BEGIN(in_struct); }
384 "%"             {
385   error_at_line (&lexer_line, 
386                  "unterminated %%{; unexpected EOF");
391 ["/]                    |
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 */
398 {WS}"GTY"{WS}?"("       {
399   error_at_line (&lexer_line, "stray GTY marker");
404 /* Deal with the expansion caused by the DEF_VEC_x macros.  */
406 typedef struct macro
408   const char *name;
409   const char *expansion;
410   struct macro *next;
411 } macro_t;
413 static const macro_t macro_defs[] = 
415 #define IN_GENGTYPE 1
416 #include "vec.h"
417   {NULL, NULL, NULL}
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.  */
426 static void
427 push_macro_expansion (const char *name, unsigned name_len,
428                       const char *arg, unsigned arg_len)
430   unsigned ix;
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))
435       {
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;
442         return;
443       }
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.  */
452 static unsigned
453 macro_input (char *buffer, unsigned size)
455   unsigned result;
457   result = fread (buffer, 1, size, yyin);
458   if (result)
459     /*NOP*/;
460   else if (ferror (yyin))
461     YY_FATAL_ERROR ("read of source file failed");
462   else if (macro_expns)
463     {
464       const char *expn;
465       unsigned len;
467       for (expn = macro_expns->expansion; *expn; expn++)
468         {
469           if (*expn == '#')
470             {
471               if (buffer[result-1] == ' ' && buffer[result-2] == '_')
472                 result--;
473               len = strlen (macro_expns->name);
474               memcpy (&buffer[result], macro_expns->name, len);
475               result += len;
476             }
477           else
478             {
479               buffer[result++] = *expn;
480               if (*expn == ';' || *expn == '{')
481                 buffer[result++] = '\n';
482             }
483         }
484       if (result > size)
485         YY_FATAL_ERROR ("buffer too small to expand macro");
486       macro_expns = macro_expns->next;
487     }
488   return result;
491 void
492 yyerror (const char *s)
494   error_at_line (&lexer_line, s);
497 void
498 parse_file (const char *fname)
500   yyin = fopen (fname, "r");
501   lexer_line.file = fname;
502   lexer_line.line = 1;
503   if (yyin == NULL)
504     {
505       perror (fname);
506       exit (1);
507     }
508   if (yyparse() != 0)
509     exit (1);
510   fclose (yyin);