OSDN Git Service

Fix 4 execute/va-arg-26.c gcc testsuite failures.
[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 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, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, 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 void push_macro_expansion (const char *, unsigned,
37                                   const char *, unsigned);
38 static void update_lineno (const char *l, size_t len);
39
40 struct fileloc lexer_line;
41 int lexer_toplevel_done;
42
43 static void 
44 update_lineno (const char *l, size_t len)
45 {
46   while (len-- > 0)
47     if (*l++ == '\n')
48       lexer_line.line++;
49 }
50
51 %}
52
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})*
57
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
61 %%
62
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;
71
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 ((const char *) xmemdup (tagstart, taglen, taglen+1),
89                       union_p);
90   if (is_pointer)
91     t = create_pointer (t);
92   namestart = (char *) xmemdup (namestart, namelen, namelen+1);
93 #ifdef USE_MAPPED_LOCATION
94   /* temporary kludge - gentype doesn't handle cpp conditionals */
95   if (strcmp (namestart, "location_t") != 0
96       && strcmp (namestart, "expanded_location") != 0)
97 #endif
98   do_typedef (namestart, t, &lexer_line);
99   update_lineno (yytext, yyleng);
100 }
101
102 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
103
104   char *namestart;
105   size_t namelen;
106   struct type *t;
107   char *typestart;
108   size_t typelen;
109
110   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
111     ;
112   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
113     ;
114   namestart -= namelen - 1;
115   for (typestart = yytext + strlen (" typedef "); 
116        ISSPACE(*typestart);
117        typestart++)
118     ;
119   for (typelen = namestart - typestart;
120        ISSPACE (typestart[typelen-1]);
121        typelen--)
122     ;
123
124   t = create_scalar_type (typestart, typelen);
125   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
126               &lexer_line);
127   update_lineno (yytext, yyleng);
128 }
129
130 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
131   char *namestart;
132   size_t namelen;
133   struct type *t;
134
135   for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
136     ;
137   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
138     ;
139   namestart -= namelen - 1;
140
141   t = create_scalar_type ("function type", sizeof ("function type")-1);
142   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
143               &lexer_line);
144   update_lineno (yytext, yyleng);
145 }
146
147 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
148   char *namestart;
149   size_t namelen;
150   struct type *t;
151
152   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
153     ;
154   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
155     ;
156   namestart -= namelen - 1;
157
158   t = create_scalar_type ("function type", sizeof ("function type")-1);
159   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
160               &lexer_line);
161   update_lineno (yytext, yyleng);
162 }
163
164 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
165   char *namestart;
166   size_t namelen;
167   struct type *t;
168
169   for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
170     ;
171   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
172     ;
173   namestart -= namelen - 1;
174
175   t = create_scalar_type ("function type", sizeof ("function type")-1);
176   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
177               &lexer_line);
178   update_lineno (yytext, yyleng);
179 }
180
181 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
182   char *namestart;
183   size_t namelen;
184   struct type *t;
185
186   for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
187     ;
188   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
189     ;
190   namestart -= namelen - 1;
191
192   t = create_scalar_type ("function type", sizeof ("function type")-1);
193   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
194               &lexer_line);
195   update_lineno (yytext, yyleng);
196 }
197
198 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
199   char *tagstart;
200   size_t taglen;
201   int typedef_p;
202   int union_p;
203
204   typedef_p = yytext[1] == 't';
205   if (typedef_p)
206     for (tagstart = yytext + strlen (" typedef "); 
207          ISSPACE(*tagstart);
208          tagstart++)
209       ;
210   else
211     tagstart = yytext + 1;
212
213   union_p = tagstart[0] == 'u';
214   tagstart += strlen ("union ");
215   while (ISSPACE (*tagstart))
216     tagstart++;
217   for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
218     ;
219
220   yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen,
221                                                      taglen + 1),
222                              union_p);
223   BEGIN(in_struct);
224   update_lineno (yytext, yyleng);
225   return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
226 }
227
228 [^[:alnum:]_](extern|static){WS}/"GTY" {
229   BEGIN(in_struct);
230   update_lineno (yytext, yyleng);
231   return ENT_EXTERNSTATIC;
232 }
233
234 ^"%union"{WS}"{"{WS}/"GTY" {
235   BEGIN(in_struct);
236   update_lineno (yytext, yyleng);
237   return ENT_YACCUNION;
238 }
239
240 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
241   char *macro, *arg;
242   unsigned macro_len, arg_len;
243   char *ptr = yytext;
244   type_p t;
245
246   /* Locate the macro and argument strings.  */
247   macro = ptr;
248   while (*ptr != '(' && !ISSPACE (*ptr))
249     ptr++;
250   macro_len = ptr - macro;
251   while (*ptr == '(' || ISSPACE (*ptr))
252     ptr++;
253   arg = ptr;
254   while (*ptr != ')' && !ISSPACE (*ptr))
255     ptr++;
256   arg_len = ptr - arg;
257
258   /* Push the macro for later expansion.  */
259   push_macro_expansion (macro, macro_len, arg, arg_len);
260
261   /* Create the struct and typedef.  */
262   ptr = (char *) xmemdup ("VEC_", 4, 4 + arg_len + 1);
263   memcpy (&ptr[4], arg, arg_len);
264   ptr[4 + arg_len] = 0;
265   t = find_structure (ptr, 0);
266   do_typedef (ptr, t, &lexer_line);
267 }
268
269 <in_struct>{
270
271 "/*"                            { BEGIN(in_struct_comment); }
272
273 ^"%{"                           { BEGIN(in_yacc_escape); } /* } */
274
275 ^"@@".*                         /* Used for c-parse.in C/ObjC demarcation.  */
276
277 {WS}                            { update_lineno (yytext, yyleng); }
278
279 "const"/[^[:alnum:]_]           /* don't care */
280 "GTY"/[^[:alnum:]_]             { return GTY_TOKEN; }
281 "union"/[^[:alnum:]_]           { return UNION; }
282 "struct"/[^[:alnum:]_]          { return STRUCT; }
283 "enum"/[^[:alnum:]_]            { return ENUM; }
284 "ptr_alias"/[^[:alnum:]_]       { return ALIAS; }
285 "nested_ptr"/[^[:alnum:]_]      { return NESTED_PTR; }
286 [0-9]+                          { return NUM; }
287 "param"[0-9]*"_is"/[^[:alnum:]_]                {
288   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
289   return PARAM_IS;
290 }
291
292 {IWORD}({WS}{IWORD})*/[^[:alnum:]_]             |
293 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")"        {
294   size_t len;
295
296   for (len = yyleng; ISSPACE (yytext[len-1]); len--)
297     ;
298
299   yylval.t = create_scalar_type (yytext, len);
300   update_lineno (yytext, yyleng);
301   return SCALAR;
302 }
303
304 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
305   char *macro, *arg;
306   unsigned macro_len, arg_len;
307   char *ptr = yytext;
308
309   macro = ptr;
310   while (*ptr != '(' && !ISSPACE (*ptr)) /* )*/
311     ptr++;
312   macro_len = ptr - macro;
313   while (*ptr == '(' || ISSPACE (*ptr))
314     ptr++;
315   arg = ptr;
316   while (*ptr != ')' && !ISSPACE (*ptr))
317     ptr++;
318   arg_len = ptr - arg;
319   ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
320   ptr[macro_len] = '_';
321   memcpy (&ptr[macro_len+1], arg, arg_len);
322   yylval.s = ptr;
323   return ID;
324 }
325
326 {ID}/[^[:alnum:]_]              {
327   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
328   return ID;
329 }
330
331 \"([^"\\]|\\.)*\"               {
332   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
333   return STRING;
334 }
335 "["[^\[\]]*"]"                  {
336   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
337   return ARRAY;
338 }
339 ^"%"{ID}                        {
340   yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
341   return PERCENT_ID;
342 }
343 "'"("\\".|[^\\])"'"             {
344   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
345   return CHAR;
346 }
347
348 [(){},*:<>]                     { return yytext[0]; }
349
350 [;=]                            {
351   if (lexer_toplevel_done)
352     {
353       BEGIN(INITIAL);
354       lexer_toplevel_done = 0;
355     }
356   return yytext[0];
357 }
358
359 ^"%%"                           {
360   BEGIN(INITIAL);
361   return PERCENTPERCENT;
362 }
363
364 "#define"[^\n]*\n               {lexer_line.line++;}
365
366 .                               {
367   error_at_line (&lexer_line, "unexpected character `%s'", yytext);
368 }
369 }
370
371 "/*"                    { BEGIN(in_comment); }
372 \n                      { lexer_line.line++; }
373 {ID}                    |
374 "'"("\\".|[^\\])"'"     |
375 [^"/\n]                 /* do nothing */
376 \"([^"\\]|\\.|\\\n)*\"  { update_lineno (yytext, yyleng); }
377 "/"/[^*]                /* do nothing */
378
379 <in_comment,in_struct_comment>{
380 \n              { lexer_line.line++; }
381 [^*\n]{16}      |
382 [^*\n]          /* do nothing */
383 "*"/[^/]        /* do nothing */
384 }
385 <in_comment>"*/"        { BEGIN(INITIAL); } 
386 <in_struct_comment>"*/" { BEGIN(in_struct); }
387
388 <in_yacc_escape>{
389 \n              { lexer_line.line++; }
390 [^%]{16}        |
391 [^%]            /* do nothing */
392 "%"/[^}]        /* do nothing */
393 "%}"            { BEGIN(in_struct); }
394 "%"             {
395   error_at_line (&lexer_line, 
396                  "unterminated %%{; unexpected EOF");
397 }
398 }
399
400
401 ["/]                    |
402 <in_struct_comment,in_comment>"*"       {
403   error_at_line (&lexer_line, 
404                  "unterminated comment or string; unexpected EOF");
405 }
406
407 ^"#define"{WS}"GTY(" /* do nothing */
408 {WS}"GTY"{WS}?"("       {
409   error_at_line (&lexer_line, "stray GTY marker");
410 }
411
412 %%
413
414 /* Deal with the expansion caused by the DEF_VEC_x macros.  */
415
416 typedef struct macro
417 {
418   const char *name;
419   const char *expansion;
420   struct macro *next;
421 } macro_t;
422
423 static const macro_t macro_defs[] = 
424 {
425 #define IN_GENGTYPE 1
426 #include "vec.h"
427   {NULL, NULL, NULL}
428 };
429
430 /* Chain of macro expansions to do at end of scanning.  */
431 static macro_t *macro_expns;
432
433 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
434    expansion queue.  We ensure NAME is known at this point.  */
435
436 static void
437 push_macro_expansion (const char *name, unsigned name_len,
438                       const char *arg, unsigned arg_len)
439 {
440   unsigned ix;
441
442   for (ix = 0; macro_defs[ix].name; ix++)
443     if (strlen (macro_defs[ix].name) == name_len
444         && !memcmp (name, macro_defs[ix].name, name_len))
445       {
446         macro_t *expansion = XNEW (macro_t);
447
448         expansion->next = macro_expns;
449         expansion->name = (char *) xmemdup (arg, arg_len, arg_len+1);
450         expansion->expansion = macro_defs[ix].expansion;
451         macro_expns = expansion;
452         return;
453       }
454   error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
455                  name_len, name, arg_len, arg);
456 }
457
458 /* Attempt to read some input.  Use fread until we're at the end of
459    file.  At end of file expand the next queued macro.  We presume the
460    buffer is large enough for the entire expansion.  */
461
462 static unsigned
463 macro_input (char *buffer, unsigned size)
464 {
465   unsigned result;
466
467   result = fread (buffer, 1, size, yyin);
468   if (result)
469     /*NOP*/;
470   else if (ferror (yyin))
471     YY_FATAL_ERROR ("read of source file failed");
472   else if (macro_expns)
473     {
474       const char *expn;
475       unsigned len;
476
477       for (expn = macro_expns->expansion; *expn; expn++)
478         {
479           if (*expn == '#')
480             {
481               if (buffer[result-1] == ' ' && buffer[result-2] == '_')
482                 result--;
483               len = strlen (macro_expns->name);
484               memcpy (&buffer[result], macro_expns->name, len);
485               result += len;
486             }
487           else
488             {
489               buffer[result++] = *expn;
490               if (*expn == ';' || *expn == '{')
491                 buffer[result++] = '\n';
492             }
493         }
494       if (result > size)
495         YY_FATAL_ERROR ("buffer too small to expand macro");
496       macro_expns = macro_expns->next;
497     }
498   return result;
499 }
500
501 void
502 yyerror (const char *s)
503 {
504   error_at_line (&lexer_line, s);
505 }
506
507 void
508 parse_file (const char *fname)
509 {
510   yyin = fopen (fname, "r");
511   lexer_line.file = fname;
512   lexer_line.line = 1;
513   if (yyin == NULL)
514     {
515       perror (fname);
516       exit (1);
517     }
518   if (yyparse() != 0)
519     exit (1);
520   fclose (yyin);
521 }