1/* -*- indented-text -*- */
2/* Process source files and output type information.
3   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301, USA.  */
21
22%{
23#include "bconfig.h"
24#include "system.h"
25#include "coretypes.h"
26#include "tm.h"
27#include "gengtype.h"
28#define YYERROR_VERBOSE
29%}
30
31%union {
32  type_p t;
33  pair_p p;
34  options_p o;
35  const char *s;
36}
37
38%token <t>ENT_TYPEDEF_STRUCT
39%token <t>ENT_STRUCT
40%token ENT_EXTERNSTATIC
41%token ENT_YACCUNION
42%token GTY_TOKEN
43%token UNION
44%token STRUCT
45%token ENUM
46%token ALIAS
47%token NESTED_PTR
48%token <s>PARAM_IS
49%token NUM
50%token PERCENTPERCENT "%%"
51%token <t>SCALAR
52%token <s>ID
53%token <s>STRING
54%token <s>ARRAY
55%token <s>PERCENT_ID
56%token <s>CHAR
57
58%type <p> struct_fields yacc_ids yacc_typematch
59%type <t> type lasttype
60%type <o> optionsopt options option optionseq optionseqopt
61%type <s> type_option stringseq
62
63%%
64
65start: /* empty */
66       | typedef_struct start
67       | externstatic start
68       | yacc_union start
69       ;
70
71typedef_struct: ENT_TYPEDEF_STRUCT options '{' struct_fields '}' ID
72		   {
73		     new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
74				    $4, $2);
75		     do_typedef ($6, $1, &lexer_line);
76		     lexer_toplevel_done = 1;
77		   }
78		 ';'
79		   {}
80		| ENT_STRUCT options '{' struct_fields '}'
81		   {
82		     new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
83				    $4, $2);
84		     lexer_toplevel_done = 1;
85		   }
86		 ';'
87		   {}
88		;
89
90externstatic: ENT_EXTERNSTATIC options lasttype ID semiequal
91	         {
92	           note_variable ($4, adjust_field_type ($3, $2), $2,
93				  &lexer_line);
94	         }
95	      | ENT_EXTERNSTATIC options lasttype ID ARRAY semiequal
96	         {
97	           note_variable ($4, create_array ($3, $5),
98	      		    $2, &lexer_line);
99	         }
100	      | ENT_EXTERNSTATIC options lasttype ID ARRAY ARRAY semiequal
101	         {
102	           note_variable ($4, create_array (create_array ($3, $6),
103	      				      $5),
104	      		    $2, &lexer_line);
105	         }
106	      ;
107
108lasttype: type
109	    {
110	      lexer_toplevel_done = 1;
111	      $$ = $1;
112	    }
113	    ;
114
115semiequal: ';'
116	   | '='
117	   ;
118
119yacc_union: ENT_YACCUNION options struct_fields '}' yacc_typematch
120	    PERCENTPERCENT
121	      {
122	        note_yacc_type ($2, $3, $5, &lexer_line);
123	      }
124	    ;
125
126yacc_typematch: /* empty */
127		   { $$ = NULL; }
128		| yacc_typematch PERCENT_ID yacc_ids
129		   {
130		     pair_p p;
131		     for (p = $3; p->next != NULL; p = p->next)
132		       {
133		         p->name = NULL;
134			 p->type = NULL;
135		       }
136		     p->name = NULL;
137		     p->type = NULL;
138		     p->next = $1;
139		     $$ = $3;
140		   }
141		| yacc_typematch PERCENT_ID '<' ID '>' yacc_ids
142		   {
143		     pair_p p;
144		     type_p newtype = NULL;
145		     if (strcmp ($2, "type") == 0)
146		       newtype = (type_p) 1;
147		     for (p = $6; p->next != NULL; p = p->next)
148		       {
149		         p->name = $4;
150		         p->type = newtype;
151		       }
152		     p->name = $4;
153		     p->next = $1;
154		     p->type = newtype;
155		     $$ = $6;
156		   }
157		;
158
159yacc_ids: /* empty */
160	{ $$ = NULL; }
161     | yacc_ids ID
162        {
163	  pair_p p = XCNEW (struct pair);
164	  p->next = $1;
165	  p->line = lexer_line;
166	  p->opt = XNEW (struct options);
167	  p->opt->name = "tag";
168	  p->opt->next = NULL;
169	  p->opt->info = (char *)$2;
170	  $$ = p;
171	}
172     | yacc_ids CHAR
173        {
174	  pair_p p = XCNEW (struct pair);
175	  p->next = $1;
176	  p->line = lexer_line;
177	  p->opt = XNEW (struct options);
178	  p->opt->name = "tag";
179	  p->opt->next = NULL;
180	  p->opt->info = xasprintf ("'%s'", $2);
181	  $$ = p;
182	}
183     ;
184
185struct_fields: { $$ = NULL; }
186	       | type optionsopt ID bitfieldopt ';' struct_fields
187	          {
188	            pair_p p = XNEW (struct pair);
189		    p->type = adjust_field_type ($1, $2);
190		    p->opt = $2;
191		    p->name = $3;
192		    p->next = $6;
193		    p->line = lexer_line;
194		    $$ = p;
195		  }
196	       | type optionsopt ID ARRAY ';' struct_fields
197	          {
198	            pair_p p = XNEW (struct pair);
199		    p->type = adjust_field_type (create_array ($1, $4), $2);
200		    p->opt = $2;
201		    p->name = $3;
202		    p->next = $6;
203		    p->line = lexer_line;
204		    $$ = p;
205		  }
206	       | type optionsopt ID ARRAY ARRAY ';' struct_fields
207	          {
208	            pair_p p = XNEW (struct pair);
209		    p->type = create_array (create_array ($1, $5), $4);
210		    p->opt = $2;
211		    p->name = $3;
212		    p->next = $7;
213		    p->line = lexer_line;
214		    $$ = p;
215		  }
216	       | type ':' bitfieldlen ';' struct_fields
217		  { $$ = $5; }
218	       ;
219
220bitfieldopt: /* empty */
221	     | ':' bitfieldlen
222	     ;
223
224bitfieldlen: NUM | ID
225		{ }
226	     ;
227
228type: SCALAR
229         { $$ = $1; }
230      | ID
231         { $$ = resolve_typedef ($1, &lexer_line); }
232      | type '*'
233         { $$ = create_pointer ($1); }
234      | STRUCT ID '{' struct_fields '}'
235         { $$ = new_structure ($2, 0, &lexer_line, $4, NULL); }
236      | STRUCT ID
237         { $$ = find_structure ($2, 0); }
238      | UNION ID '{' struct_fields '}'
239         { $$ = new_structure ($2, 1, &lexer_line, $4, NULL); }
240      | UNION ID
241         { $$ = find_structure ($2, 1); }
242      | ENUM ID
243         { $$ = create_scalar_type ($2, strlen ($2)); }
244      | ENUM ID '{' enum_items '}'
245         { $$ = create_scalar_type ($2, strlen ($2)); }
246      ;
247
248enum_items: /* empty */
249	    | ID '=' NUM ',' enum_items
250	      { }
251	    | ID ',' enum_items
252	      { }
253	    | ID enum_items
254	      { }
255	    ;
256
257optionsopt: { $$ = NULL; }
258	    | options { $$ = $1; }
259	    ;
260
261options: GTY_TOKEN '(' '(' optionseqopt ')' ')'
262	   { $$ = $4; }
263	 ;
264
265type_option : ALIAS
266	        { $$ = "ptr_alias"; }
267	      | PARAM_IS
268	        { $$ = $1; }
269	      ;
270
271option:   ID
272	    { $$ = create_option (NULL, $1, (void *)""); }
273        | ID '(' stringseq ')'
274            { $$ = create_option (NULL, $1, (void *)$3); }
275	| type_option '(' type ')'
276	    { $$ = create_option (NULL, $1, adjust_field_type ($3, NULL)); }
277	| NESTED_PTR '(' type ',' stringseq ',' stringseq ')'
278	    {
279	      struct nested_ptr_data d;
280
281	      d.type = adjust_field_type ($3, NULL);
282	      d.convert_to = $5;
283	      d.convert_from = $7;
284	      $$ = create_option (NULL, "nested_ptr",
285				  xmemdup (&d, sizeof (d), sizeof (d)));
286	    }
287	;
288
289optionseq: option
290	      {
291	        $1->next = NULL;
292		$$ = $1;
293	      }
294	    | optionseq ',' option
295	      {
296	        $3->next = $1;
297		$$ = $3;
298	      }
299	    ;
300
301optionseqopt: { $$ = NULL; }
302	      | optionseq { $$ = $1; }
303	      ;
304
305stringseq: STRING
306	     { $$ = $1; }
307	   | stringseq STRING
308	     {
309	       size_t l1 = strlen ($1);
310	       size_t l2 = strlen ($2);
311	       char *s = XRESIZEVEC (char, $1, l1 + l2 + 1);
312	       memcpy (s + l1, $2, l2 + 1);
313	       XDELETE ($2);
314	       $$ = s;
315	     }
316	   ;
317%%
318