1117395Skan/* -*- indented-text -*- */
2117395Skan/* Process source files and output type information.
3169689Skan   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4117395Skan
5117395SkanThis file is part of GCC.
6117395Skan
7117395SkanGCC is free software; you can redistribute it and/or modify it under
8117395Skanthe terms of the GNU General Public License as published by the Free
9117395SkanSoftware Foundation; either version 2, or (at your option) any later
10117395Skanversion.
11117395Skan
12117395SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13117395SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
14117395SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15117395Skanfor more details.
16117395Skan
17117395SkanYou should have received a copy of the GNU General Public License
18117395Skanalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
21117395Skan
22117395Skan%{
23132718Skan#include "bconfig.h"
24117395Skan#include "system.h"
25132718Skan#include "coretypes.h"
26132718Skan#include "tm.h"
27117395Skan#include "gengtype.h"
28117395Skan#define YYERROR_VERBOSE
29117395Skan%}
30117395Skan
31117395Skan%union {
32117395Skan  type_p t;
33117395Skan  pair_p p;
34117395Skan  options_p o;
35117395Skan  const char *s;
36117395Skan}
37117395Skan
38117395Skan%token <t>ENT_TYPEDEF_STRUCT
39117395Skan%token <t>ENT_STRUCT
40117395Skan%token ENT_EXTERNSTATIC
41117395Skan%token ENT_YACCUNION
42117395Skan%token GTY_TOKEN
43117395Skan%token UNION
44117395Skan%token STRUCT
45117395Skan%token ENUM
46117395Skan%token ALIAS
47169689Skan%token NESTED_PTR
48117395Skan%token <s>PARAM_IS
49117395Skan%token NUM
50117395Skan%token PERCENTPERCENT "%%"
51117395Skan%token <t>SCALAR
52117395Skan%token <s>ID
53117395Skan%token <s>STRING
54117395Skan%token <s>ARRAY
55117395Skan%token <s>PERCENT_ID
56117395Skan%token <s>CHAR
57117395Skan
58117395Skan%type <p> struct_fields yacc_ids yacc_typematch
59117395Skan%type <t> type lasttype
60117395Skan%type <o> optionsopt options option optionseq optionseqopt
61169689Skan%type <s> type_option stringseq
62117395Skan
63117395Skan%%
64117395Skan
65117395Skanstart: /* empty */
66117395Skan       | typedef_struct start
67117395Skan       | externstatic start
68117395Skan       | yacc_union start
69117395Skan       ;
70117395Skan
71117395Skantypedef_struct: ENT_TYPEDEF_STRUCT options '{' struct_fields '}' ID
72117395Skan		   {
73117395Skan		     new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
74117395Skan				    $4, $2);
75117395Skan		     do_typedef ($6, $1, &lexer_line);
76117395Skan		     lexer_toplevel_done = 1;
77117395Skan		   }
78117395Skan		 ';'
79117395Skan		   {}
80117395Skan		| ENT_STRUCT options '{' struct_fields '}'
81117395Skan		   {
82117395Skan		     new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
83117395Skan				    $4, $2);
84117395Skan		     lexer_toplevel_done = 1;
85117395Skan		   }
86117395Skan		 ';'
87117395Skan		   {}
88117395Skan		;
89117395Skan
90117395Skanexternstatic: ENT_EXTERNSTATIC options lasttype ID semiequal
91117395Skan	         {
92117395Skan	           note_variable ($4, adjust_field_type ($3, $2), $2,
93117395Skan				  &lexer_line);
94117395Skan	         }
95117395Skan	      | ENT_EXTERNSTATIC options lasttype ID ARRAY semiequal
96117395Skan	         {
97117395Skan	           note_variable ($4, create_array ($3, $5),
98117395Skan	      		    $2, &lexer_line);
99117395Skan	         }
100117395Skan	      | ENT_EXTERNSTATIC options lasttype ID ARRAY ARRAY semiequal
101117395Skan	         {
102117395Skan	           note_variable ($4, create_array (create_array ($3, $6),
103117395Skan	      				      $5),
104117395Skan	      		    $2, &lexer_line);
105117395Skan	         }
106117395Skan	      ;
107117395Skan
108117395Skanlasttype: type
109117395Skan	    {
110117395Skan	      lexer_toplevel_done = 1;
111117395Skan	      $$ = $1;
112117395Skan	    }
113117395Skan	    ;
114117395Skan
115117395Skansemiequal: ';'
116117395Skan	   | '='
117117395Skan	   ;
118117395Skan
119117395Skanyacc_union: ENT_YACCUNION options struct_fields '}' yacc_typematch
120117395Skan	    PERCENTPERCENT
121117395Skan	      {
122117395Skan	        note_yacc_type ($2, $3, $5, &lexer_line);
123117395Skan	      }
124117395Skan	    ;
125117395Skan
126117395Skanyacc_typematch: /* empty */
127117395Skan		   { $$ = NULL; }
128117395Skan		| yacc_typematch PERCENT_ID yacc_ids
129117395Skan		   {
130117395Skan		     pair_p p;
131117395Skan		     for (p = $3; p->next != NULL; p = p->next)
132117395Skan		       {
133117395Skan		         p->name = NULL;
134117395Skan			 p->type = NULL;
135117395Skan		       }
136117395Skan		     p->name = NULL;
137117395Skan		     p->type = NULL;
138117395Skan		     p->next = $1;
139117395Skan		     $$ = $3;
140117395Skan		   }
141117395Skan		| yacc_typematch PERCENT_ID '<' ID '>' yacc_ids
142117395Skan		   {
143117395Skan		     pair_p p;
144117395Skan		     type_p newtype = NULL;
145117395Skan		     if (strcmp ($2, "type") == 0)
146117395Skan		       newtype = (type_p) 1;
147117395Skan		     for (p = $6; p->next != NULL; p = p->next)
148117395Skan		       {
149117395Skan		         p->name = $4;
150117395Skan		         p->type = newtype;
151117395Skan		       }
152117395Skan		     p->name = $4;
153117395Skan		     p->next = $1;
154117395Skan		     p->type = newtype;
155117395Skan		     $$ = $6;
156117395Skan		   }
157117395Skan		;
158117395Skan
159117395Skanyacc_ids: /* empty */
160117395Skan	{ $$ = NULL; }
161117395Skan     | yacc_ids ID
162117395Skan        {
163169689Skan	  pair_p p = XCNEW (struct pair);
164117395Skan	  p->next = $1;
165117395Skan	  p->line = lexer_line;
166169689Skan	  p->opt = XNEW (struct options);
167117395Skan	  p->opt->name = "tag";
168117395Skan	  p->opt->next = NULL;
169117395Skan	  p->opt->info = (char *)$2;
170117395Skan	  $$ = p;
171117395Skan	}
172117395Skan     | yacc_ids CHAR
173117395Skan        {
174169689Skan	  pair_p p = XCNEW (struct pair);
175117395Skan	  p->next = $1;
176117395Skan	  p->line = lexer_line;
177169689Skan	  p->opt = XNEW (struct options);
178117395Skan	  p->opt->name = "tag";
179117395Skan	  p->opt->next = NULL;
180117395Skan	  p->opt->info = xasprintf ("'%s'", $2);
181117395Skan	  $$ = p;
182117395Skan	}
183117395Skan     ;
184117395Skan
185117395Skanstruct_fields: { $$ = NULL; }
186117395Skan	       | type optionsopt ID bitfieldopt ';' struct_fields
187117395Skan	          {
188169689Skan	            pair_p p = XNEW (struct pair);
189117395Skan		    p->type = adjust_field_type ($1, $2);
190117395Skan		    p->opt = $2;
191117395Skan		    p->name = $3;
192117395Skan		    p->next = $6;
193117395Skan		    p->line = lexer_line;
194117395Skan		    $$ = p;
195117395Skan		  }
196117395Skan	       | type optionsopt ID ARRAY ';' struct_fields
197117395Skan	          {
198169689Skan	            pair_p p = XNEW (struct pair);
199117395Skan		    p->type = adjust_field_type (create_array ($1, $4), $2);
200117395Skan		    p->opt = $2;
201117395Skan		    p->name = $3;
202117395Skan		    p->next = $6;
203117395Skan		    p->line = lexer_line;
204117395Skan		    $$ = p;
205117395Skan		  }
206117395Skan	       | type optionsopt ID ARRAY ARRAY ';' struct_fields
207117395Skan	          {
208169689Skan	            pair_p p = XNEW (struct pair);
209117395Skan		    p->type = create_array (create_array ($1, $5), $4);
210117395Skan		    p->opt = $2;
211117395Skan		    p->name = $3;
212117395Skan		    p->next = $7;
213117395Skan		    p->line = lexer_line;
214117395Skan		    $$ = p;
215117395Skan		  }
216169689Skan	       | type ':' bitfieldlen ';' struct_fields
217169689Skan		  { $$ = $5; }
218117395Skan	       ;
219117395Skan
220117395Skanbitfieldopt: /* empty */
221169689Skan	     | ':' bitfieldlen
222117395Skan	     ;
223117395Skan
224169689Skanbitfieldlen: NUM | ID
225169689Skan		{ }
226169689Skan	     ;
227169689Skan
228117395Skantype: SCALAR
229117395Skan         { $$ = $1; }
230117395Skan      | ID
231117395Skan         { $$ = resolve_typedef ($1, &lexer_line); }
232117395Skan      | type '*'
233117395Skan         { $$ = create_pointer ($1); }
234117395Skan      | STRUCT ID '{' struct_fields '}'
235169689Skan         { $$ = new_structure ($2, 0, &lexer_line, $4, NULL); }
236117395Skan      | STRUCT ID
237117395Skan         { $$ = find_structure ($2, 0); }
238117395Skan      | UNION ID '{' struct_fields '}'
239169689Skan         { $$ = new_structure ($2, 1, &lexer_line, $4, NULL); }
240117395Skan      | UNION ID
241117395Skan         { $$ = find_structure ($2, 1); }
242117395Skan      | ENUM ID
243117395Skan         { $$ = create_scalar_type ($2, strlen ($2)); }
244117395Skan      | ENUM ID '{' enum_items '}'
245117395Skan         { $$ = create_scalar_type ($2, strlen ($2)); }
246117395Skan      ;
247117395Skan
248117395Skanenum_items: /* empty */
249117395Skan	    | ID '=' NUM ',' enum_items
250117395Skan	      { }
251117395Skan	    | ID ',' enum_items
252117395Skan	      { }
253117395Skan	    | ID enum_items
254117395Skan	      { }
255117395Skan	    ;
256117395Skan
257117395Skanoptionsopt: { $$ = NULL; }
258117395Skan	    | options { $$ = $1; }
259117395Skan	    ;
260117395Skan
261117395Skanoptions: GTY_TOKEN '(' '(' optionseqopt ')' ')'
262117395Skan	   { $$ = $4; }
263117395Skan	 ;
264117395Skan
265117395Skantype_option : ALIAS
266117395Skan	        { $$ = "ptr_alias"; }
267117395Skan	      | PARAM_IS
268117395Skan	        { $$ = $1; }
269117395Skan	      ;
270117395Skan
271169689Skanoption:   ID
272169689Skan	    { $$ = create_option (NULL, $1, (void *)""); }
273169689Skan        | ID '(' stringseq ')'
274169689Skan            { $$ = create_option (NULL, $1, (void *)$3); }
275169689Skan	| type_option '(' type ')'
276169689Skan	    { $$ = create_option (NULL, $1, adjust_field_type ($3, NULL)); }
277169689Skan	| NESTED_PTR '(' type ',' stringseq ',' stringseq ')'
278169689Skan	    {
279169689Skan	      struct nested_ptr_data d;
280169689Skan
281169689Skan	      d.type = adjust_field_type ($3, NULL);
282169689Skan	      d.convert_to = $5;
283169689Skan	      d.convert_from = $7;
284169689Skan	      $$ = create_option (NULL, "nested_ptr",
285169689Skan				  xmemdup (&d, sizeof (d), sizeof (d)));
286169689Skan	    }
287117395Skan	;
288117395Skan
289117395Skanoptionseq: option
290117395Skan	      {
291117395Skan	        $1->next = NULL;
292117395Skan		$$ = $1;
293117395Skan	      }
294117395Skan	    | optionseq ',' option
295117395Skan	      {
296117395Skan	        $3->next = $1;
297117395Skan		$$ = $3;
298117395Skan	      }
299117395Skan	    ;
300117395Skan
301117395Skanoptionseqopt: { $$ = NULL; }
302117395Skan	      | optionseq { $$ = $1; }
303117395Skan	      ;
304169689Skan
305169689Skanstringseq: STRING
306169689Skan	     { $$ = $1; }
307169689Skan	   | stringseq STRING
308169689Skan	     {
309169689Skan	       size_t l1 = strlen ($1);
310169689Skan	       size_t l2 = strlen ($2);
311169689Skan	       char *s = XRESIZEVEC (char, $1, l1 + l2 + 1);
312169689Skan	       memcpy (s + l1, $2, l2 + 1);
313169689Skan	       XDELETE ($2);
314169689Skan	       $$ = s;
315169689Skan	     }
316169689Skan	   ;
317117395Skan%%
318