Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140606131903

Diff

Diff from 1.374 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/cgram.y

Annotated File View

plunky
1.374
1 /*      $Id: cgram.y,v 1.374 2014/06/06 13:19:03 plunky Exp $   */
ragge
1.75
2
3 /*
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /*
29  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
34  *
35  * Redistributions of source code and documentation must retain the above
36  * copyright notice, this list of conditions and the following disclaimer.
37  * Redistributions in binary form must reproduce the above copyright
ragge
1.87
38  * notice, this list of conditions and the following disclaimer in the
ragge
1.75
39  * documentation and/or other materials provided with the distribution.
40  * All advertising materials mentioning features or use of this software
41  * must display the following acknowledgement:
42  *      This product includes software developed or owned by Caldera
43  *      International, Inc.
44  * Neither the name of Caldera International, Inc. nor the names of other
45  * contributors may be used to endorse or promote products derived from
46  * this software without specific prior written permission.
47  *
48  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
49  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
50  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
53  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
58  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
59  * POSSIBILITY OF SUCH DAMAGE.
60  */
ragge
1.88
61
ragge
1.1
62 /*
ragge
1.19
63  * Comments for this grammar file. Ragge 021123
64  *
65  * ANSI support required rewrite of the function header and declaration
ragge
1.75
66  * rules almost totally.
ragge
1.19
67  *
ragge
1.75
68  * The lex/yacc shared keywords are now split from the keywords used
69  * in the rest of the compiler, to simplify use of other frontends.
ragge
1.19
70  */
71
ragge
1.17
72 /*
ragge
1.313
73  * At last count, there were 5 shift/reduce and no reduce/reduce conflicts
74  * Four are accounted for;
ragge
1.301
75  * One is "dangling else"
ragge
1.313
76  * Two is in attribute parsing
ragge
1.301
77  * One is in ({ }) parsing
ragge
1.17
78  */
79
80 /*
ragge
1.72
81  * Token used in C lex/yacc communications.
ragge
1.50
82  */
ragge
1.71
83 %token  C_STRING        /* a string constant */
84 %token  C_ICON          /* an integer constant */
85 %token  C_FCON          /* a floating point constant */
86 %token  C_NAME          /* an identifier */
ragge
1.72
87 %token  C_TYPENAME      /* a typedef'd name */
ragge
1.71
88 %token  C_ANDAND        /* && */
89 %token  C_OROR          /* || */
90 %token  C_GOTO          /* unconditional goto */
91 %token  C_RETURN        /* return from function */
92 %token  C_TYPE          /* a type */
93 %token  C_CLASS         /* a storage class */
94 %token  C_ASOP          /* assignment ops */
95 %token  C_RELOP         /* <=, <, >=, > */
96 %token  C_EQUOP         /* ==, != */
97 %token  C_DIVOP         /* /, % */
98 %token  C_SHIFTOP       /* <<, >> */
99 %token  C_INCOP         /* ++, -- */
100 %token  C_UNOP          /* !, ~ */
101 %token  C_STROP         /* ., -> */
102 %token  C_STRUCT
103 %token  C_IF
104 %token  C_ELSE
105 %token  C_SWITCH
106 %token  C_BREAK
107 %token  C_CONTINUE
108 %token  C_WHILE 
109 %token  C_DO
110 %token  C_FOR
111 %token  C_DEFAULT
112 %token  C_CASE
113 %token  C_SIZEOF
ragge
1.290
114 %token  C_ALIGNOF
ragge
1.71
115 %token  C_ENUM
116 %token  C_ELLIPSIS
117 %token  C_QUALIFIER
118 %token  C_FUNSPEC
119 %token  C_ASM
ragge
1.184
120 %token  NOMATCH
ragge
1.230
121 %token  C_TYPEOF        /* COMPAT_GCC */
ragge
1.235
122 %token  C_ATTRIBUTE     /* COMPAT_GCC */
ragge
1.274
123 %token  PCC_OFFSETOF
ragge
1.327
124 %token  GCC_DESIG
ragge
1.172
125
126 /*
ragge
1.19
127  * Precedence
128  */
ragge
1.71
129 %left ','
130 %right '=' C_ASOP
131 %right '?' ':'
ragge
1.70
132 %left C_OROR
133 %left C_ANDAND
ragge
1.71
134 %left '|'
135 %left '^'
136 %left '&'
ragge
1.70
137 %left C_EQUOP
138 %left C_RELOP
139 %left C_SHIFTOP
ragge
1.71
140 %left '+' '-'
141 %left '*' C_DIVOP
ragge
1.70
142 %right C_UNOP
143 %right C_INCOP C_SIZEOF
ragge
1.71
144 %left '[' '(' C_STROP
ragge
1.1
145 %{
146 # include "pass1.h"
ragge
1.371
147 # include "unicode.h"
ragge
1.72
148 # include <stdarg.h>
ragge
1.124
149 # include <string.h>
ragge
1.170
150 # include <stdlib.h>
ragge
1.136
151
ragge
1.211
152 int fun_inline; /* Reading an inline function */
ragge
1.137
153 int oldstyle;   /* Current function being defined */
ragge
1.167
154 static struct symtab *xnf;
ragge
1.242
155 extern int enummer, tvaloff, inattr;
ragge
1.191
156 extern struct rstack *rpole;
ragge
1.304
157 static int widestr, alwinl;
ragge
1.225
158 NODE *cftnod;
ragge
1.290
159 static int attrwarn = 1;
ragge
1.137
160
ragge
1.214
161 #define NORETYP SNOCREAT /* no return type, save in unused field in symtab */
162
ragge
1.253
163        NODE *bdty(int op, ...);
ragge
1.137
164 static void fend(void);
165 static void fundef(NODE *tp, NODE *p);
ragge
1.251
166 static void olddecl(NODE *p, NODE *a);
ragge
1.347
167 static struct symtab *init_declarator(NODE *tn, NODE *p, int assign, NODE *a,
168         char *as);
ragge
1.137
169 static void resetbc(int mask);
170 static void swend(void);
171 static void addcase(NODE *p);
gmcgarry
1.234
172 #ifdef GCC_COMPAT
ragge
1.229
173 static void gcccase(NODE *p, NODE *);
gmcgarry
1.234
174 #endif
ragge
1.369
175 static struct attr *gcc_attr_wrapper(NODE *p);
ragge
1.137
176 static void adddef(void);
177 static void savebc(void);
stefan
1.177
178 static void swstart(int, TWORD);
179 static void genswitch(int, TWORD, struct swents **, int);
ragge
1.157
180 static char *mkpstr(char *str);
ragge
1.167
181 static struct symtab *clbrace(NODE *);
ragge
1.195
182 static NODE *cmop(NODE *l, NODE *r);
183 static NODE *xcmop(NODE *out, NODE *in, NODE *str);
184 static void mkxasm(char *str, NODE *p);
185 static NODE *xasmop(char *str, NODE *p);
ragge
1.210
186 static char *stradd(char *old, char *new);
ragge
1.215
187 static NODE *biop(int op, NODE *l, NODE *r);
gmcgarry
1.223
188 static void flend(void);
ragge
1.241
189 static char * simname(char *s);
ragge
1.230
190 static NODE *tyof(NODE *);      /* COMPAT_GCC */
ragge
1.369
191 static NODE *voidcon(void);
ragge
1.297
192 static NODE *funargs(NODE *p);
ragge
1.259
193 static void oldargs(NODE *p);
ragge
1.275
194 static void uawarn(NODE *p, char *s);
ragge
1.271
195 static int con_e(NODE *p);
ragge
1.286
196 static void dainit(NODE *d, NODE *a);
ragge
1.297
197 static NODE *tymfix(NODE *p);
198 static NODE *namekill(NODE *p, int clr);
199 static NODE *aryfix(NODE *p);
ragge
1.355
200 static void savlab(int);
201 extern int *mkclabs(void);
ragge
1.137
202
ragge
1.306
203 #define TYMFIX(inp) { \
204         NODE *pp = inp; \
205         inp = tymerge(pp->n_left, pp->n_right); \
206         nfree(pp->n_left); nfree(pp); }
ragge
1.137
207 /*
208  * State for saving current switch state (when nested switches).
209  */
210 struct savbc {
211         struct savbc *next;
212         int brklab;
213         int contlab;
214         int flostat;
215         int swx;
216 } *savbc, *savctx;
217
ragge
1.1
218 %}
219
ragge
1.136
220 %union {
221         int intval;
222         NODE *nodep;
223         struct symtab *symp;
224         struct rstack *rp;
225         char *strp;
226 }
227
ragge
1.1
228         /* define types */
229 %start ext_def_list
230
ragge
1.271
231 %type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart
ragge
1.304
232                 xbegin
ragge
1.297
233 %type <nodep> e .e term enum_dcl struct_dcl cast_type declarator
ragge
1.373
234                 elist type_sq cf_spec merge_attribs e2
ragge
1.163
235                 parameter_declaration abstract_declarator initializer
ragge
1.353
236                 parameter_type_list parameter_list
ragge
1.284
237                 declaration_specifiers designation
ragge
1.271
238                 specifier_qualifier_list merge_specifiers
ragge
1.251
239                 identifier_list arg_param_list type_qualifier_list
ragge
1.212
240                 designator_list designator xasm oplist oper cnstr funtype
ragge
1.236
241                 typeof attribute attribute_specifier /* COMPAT_GCC */
ragge
1.249
242                 attribute_list attr_spec_list attr_var /* COMPAT_GCC */
ragge
1.327
243 %type <strp>    string C_STRING GCC_DESIG
ragge
1.176
244 %type <rp>      str_head
245 %type <symp>    xnfdeclarator clbrace enum_head
ragge
1.1
246
ragge
1.242
247 %type <intval>  C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
ragge
1.105
248                 C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
ragge
1.172
249
ragge
1.242
250 %type <nodep>   C_TYPE C_QUALIFIER C_ICON C_FCON C_CLASS
ragge
1.168
251 %type <strp>    C_NAME C_TYPENAME
pj
1.135
252 %%
253
ragge
1.1
254 ext_def_list:      ext_def_list external_def
ragge
1.4
255                 | { ftnend(); }
ragge
1.1
256                 ;
ragge
1.4
257
ragge
1.241
258 external_def:      funtype kr_args compoundstmt { fend(); }
259                 |  declaration  { blevel = 0; symclear(0); }
ragge
1.127
260                 |  asmstatement ';'
ragge
1.71
261                 |  ';'
ragge
1.33
262                 |  error { blevel = 0; }
ragge
1.1
263                 ;
ragge
1.4
264
ragge
1.212
265 funtype:          /* no type given */ declarator {
ragge
1.322
266                     fundef(mkty(INT, 0, 0), $1);
ragge
1.214
267                     cftnsp->sflags |= NORETYP;
ragge
1.212
268                 }
269                 | declaration_specifiers declarator { fundef($1,$2); }
270                 ;
271
272 kr_args:          /* empty */
273                 | arg_dcl_list
ragge
1.1
274                 ;
275
ragge
1.19
276 /*
277  * Returns a node pointer or NULL, if no types at all given.
278  * Type trees are checked for correctness and merged into one
279  * type node in typenode().
280  */
281 declaration_specifiers:
ragge
1.162
282                    merge_attribs { $$ = typenode($1); }
ragge
1.19
283                 ;
284
ragge
1.243
285 merge_attribs:     type_sq { $$ = $1; }
ragge
1.247
286                 |  type_sq merge_attribs { $$ = cmop($2, $1); }
ragge
1.243
287                 |  cf_spec { $$ = $1; }
ragge
1.247
288                 |  cf_spec merge_attribs { $$ = cmop($2, $1); }
ragge
1.50
289                 ;
290
ragge
1.243
291 type_sq:           C_TYPE { $$ = $1; }
ragge
1.72
292                 |  C_TYPENAME { 
293                         struct symtab *sp = lookup($1, 0);
ragge
1.296
294                         if (sp->stype == ENUMTY) {
295                                 sp->stype = strmemb(sp->sap)->stype;
296                         }
297                         $$ = mkty(sp->stype, sp->sdf, sp->sap);
ragge
1.72
298                         $$->n_sp = sp;
299                 }
ragge
1.19
300                 |  struct_dcl { $$ = $1; }
301                 |  enum_dcl { $$ = $1; }
ragge
1.243
302                 |  C_QUALIFIER { $$ = $1; }
ragge
1.248
303                 |  attribute_specifier { $$ = biop(ATTRIB, $1, 0); }
ragge
1.243
304                 |  typeof { $$ = $1; }
305                 ;
306
307 cf_spec:           C_CLASS { $$ = $1; }
ragge
1.242
308                 |  C_FUNSPEC { fun_inline = 1;  /* XXX - hack */
ragge
1.370
309                         $$ = block(CLASS, NIL, NIL, 0, 0, 0); }
ragge
1.19
310                 ;
311
plunky
1.336
312 typeof:            C_TYPEOF '(' e ')' { $$ = tyof(eve($3)); }
ragge
1.306
313                 |  C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); }
314                 ;
ragge
1.230
315
ragge
1.235
316 attribute_specifier :
317                    C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; }
318  /*COMPAT_GCC*/ ;
319
320 attribute_list:    attribute
321                 |  attribute ',' attribute_list { $$ = cmop($3, $1); }
322                 ;
323
gmcgarry
1.252
324 attribute:         {
325 #ifdef GCC_COMPAT
326                          $$ = voidcon();
327 #endif
328                 }
ragge
1.235
329                 |  C_NAME { $$ = bdty(NAME, $1); }
ragge
1.236
330                 |  C_NAME '(' elist ')' {
ragge
1.235
331                         $$ = bdty($3 == NIL ? UCALL : CALL, bdty(NAME, $1), $3);
332                 }
333                 ;
334
ragge
1.19
335 /*
ragge
1.23
336  * Adds a pointer list to front of the declarators.
ragge
1.19
337  */
ragge
1.251
338 declarator:        '*' declarator { $$ = bdty(UMUL, $2); }
ragge
1.261
339                 |  '*' type_qualifier_list declarator {
ragge
1.296
340                         $$ = $2;
341                         $$->n_left = $3;
ragge
1.261
342                 }
ragge
1.251
343                 |  C_NAME { $$ = bdty(NAME, $1); }
ragge
1.296
344                 |  '(' attr_spec_list declarator ')' {
345                         $$ = $3;
ragge
1.369
346                         $$->n_ap = attr_add($$->n_ap, gcc_attr_wrapper($2));
ragge
1.296
347                 }
ragge
1.71
348                 |  '(' declarator ')' { $$ = $2; }
ragge
1.297
349                 |  declarator '[' e ']' { $$ = biop(LB, $1, $3); }
ragge
1.305
350                 |  declarator '[' C_CLASS e ']' {
351                         if ($3->n_type != STATIC)
352                                 uerror("bad class keyword");
353                         tfree($3); /* XXX - handle */
354                         $$ = biop(LB, $1, $4);
355                 }
ragge
1.269
356                 |  declarator '[' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
357                 |  declarator '[' '*' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
ragge
1.304
358                 |  declarator '(' parameter_type_list ')' {
359                         $$ = bdty(CALL, $1, $3);
ragge
1.259
360                 }
ragge
1.304
361                 |  declarator '(' identifier_list ')' {
362                         $$ = bdty(CALL, $1, $3);
ragge
1.29
363                         oldstyle = 1;
ragge
1.187
364                 }
ragge
1.304
365                 |  declarator '(' ')' { $$ = bdty(UCALL, $1); }
ragge
1.187
366                 ;
367
ragge
1.251
368 type_qualifier_list:
ragge
1.296
369                    C_QUALIFIER { $$ = $1; $$->n_op = UMUL; }
ragge
1.251
370                 |  type_qualifier_list C_QUALIFIER {
371                         $$ = $1;
ragge
1.296
372                         $$->n_qual |= $2->n_qual;
ragge
1.251
373                         nfree($2);
374                 }
ragge
1.296
375                 |  attribute_specifier {
ragge
1.369
376                         $$ = block(UMUL, NIL, NIL, 0, 0, gcc_attr_wrapper($1));
ragge
1.296
377                 }
ragge
1.251
378                 |  type_qualifier_list attribute_specifier {
ragge
1.369
379                         $1->n_ap = attr_add($1->n_ap, gcc_attr_wrapper($2));
ragge
1.251
380                 }
381                 ;
382
ragge
1.259
383 identifier_list:   C_NAME { $$ = bdty(NAME, $1); oldargs($$); }
ragge
1.296
384                 |  identifier_list ',' C_NAME {
385                         $$ = cmop($1, bdty(NAME, $3));
386                         oldargs($$->n_right);
387                 }
ragge
1.19
388                 ;
389
390 /*
391  * Returns as parameter_list, but can add an additional ELLIPSIS node.
392  */
393 parameter_type_list:
ragge
1.55
394                    parameter_list { $$ = $1; }
ragge
1.71
395                 |  parameter_list ',' C_ELLIPSIS {
ragge
1.215
396                         $$ = cmop($1, biop(ELLIPSIS, NIL, NIL));
ragge
1.19
397                 }
398                 ;
399
400 /*
ragge
1.55
401  * Returns a linked lists of nodes of op CM with parameters on
402  * its right and additional CM nodes of its left pointer.
403  * No CM nodes if only one parameter.
ragge
1.19
404  */
ragge
1.162
405 parameter_list:    parameter_declaration { $$ = $1; }
ragge
1.71
406                 |  parameter_list ',' parameter_declaration {
ragge
1.215
407                         $$ = cmop($1, $3);
ragge
1.19
408                 }
409                 ;
410
411 /*
412  * Returns a node pointer to the declaration.
413  */
414 parameter_declaration:
ragge
1.251
415                    declaration_specifiers declarator attr_var {
ragge
1.296
416                         if ($1->n_lval != SNULL && $1->n_lval != REGISTER)
ragge
1.187
417                                 uerror("illegal parameter class");
ragge
1.369
418                         $$ = block(TYMERGE, $1, $2, INT, 0,
419                             gcc_attr_wrapper($3));
ragge
1.19
420                 }
ragge
1.21
421                 |  declaration_specifiers abstract_declarator { 
ragge
1.342
422                         $1->n_ap = attr_add($1->n_ap, $2->n_ap);
ragge
1.297
423                         $$ = block(TYMERGE, $1, $2, INT, 0, 0);
ragge
1.21
424                 }
425                 |  declaration_specifiers {
ragge
1.297
426                         $$ = block(TYMERGE, $1, bdty(NAME, NULL), INT, 0, 0);
ragge
1.21
427                 }
ragge
1.19
428                 ;
429
430 abstract_declarator:
ragge
1.251
431                    '*' { $$ = bdty(UMUL, bdty(NAME, NULL)); }
432                 |  '*' type_qualifier_list {
ragge
1.296
433                         $$ = $2;
434                         $$->n_left = bdty(NAME, NULL);
ragge
1.251
435                 }
436                 |  '*' abstract_declarator { $$ = bdty(UMUL, $2); }
437                 |  '*' type_qualifier_list abstract_declarator {
ragge
1.296
438                         $$ = $2;
439                         $$->n_left = $3;
ragge
1.251
440                 }
441                 |  '(' abstract_declarator ')' { $$ = $2; }
442                 |  '[' ']' attr_var {
ragge
1.297
443                         $$ = block(LB, bdty(NAME, NULL), bcon(NOOFFSET),
ragge
1.369
444                             INT, 0, gcc_attr_wrapper($3));
ragge
1.251
445                 }
ragge
1.271
446                 |  '[' e ']' attr_var {
ragge
1.297
447                         $$ = block(LB, bdty(NAME, NULL), $2,
ragge
1.369
448                             INT, 0, gcc_attr_wrapper($4));
ragge
1.40
449                 }
ragge
1.251
450                 |  abstract_declarator '[' ']' attr_var {
ragge
1.297
451                         $$ = block(LB, $1, bcon(NOOFFSET),
ragge
1.369
452                             INT, 0, gcc_attr_wrapper($4));
ragge
1.214
453                 }
ragge
1.271
454                 |  abstract_declarator '[' e ']' attr_var {
ragge
1.369
455                         $$ = block(LB, $1, $3, INT, 0, gcc_attr_wrapper($5));
ragge
1.56
456                 }
ragge
1.342
457                 |  '(' ')' attr_var {
458                         $$ = bdty(UCALL, bdty(NAME, NULL));
ragge
1.369
459                         $$->n_ap = gcc_attr_wrapper($3);
ragge
1.342
460                 }
461                 |  '(' ib2 parameter_type_list ')' attr_var {
462                         $$ = block(CALL, bdty(NAME, NULL), $3, INT, 0,
ragge
1.369
463                             gcc_attr_wrapper($5));
ragge
1.56
464                 }
ragge
1.342
465                 |  abstract_declarator '(' ')' attr_var {
ragge
1.369
466                         $$ = block(UCALL, $1, NIL, INT, 0, gcc_attr_wrapper($4));
ragge
1.56
467                 }
ragge
1.342
468                 |  abstract_declarator '(' ib2 parameter_type_list ')' attr_var {
ragge
1.369
469                         $$ = block(CALL, $1, $4, INT, 0, gcc_attr_wrapper($6));
ragge
1.25
470                 }
ragge
1.19
471                 ;
472
ragge
1.304
473 ib2:              { }
ragge
1.265
474                 ;
ragge
1.29
475 /*
476  * K&R arg declaration, between ) and {
477  */
478 arg_dcl_list:      arg_declaration
ragge
1.92
479                 |  arg_dcl_list arg_declaration
ragge
1.29
480                 ;
481
482
ragge
1.89
483 arg_declaration:   declaration_specifiers arg_param_list ';' {
ragge
1.104
484                         nfree($1);
ragge
1.89
485                 }
ragge
1.29
486                 ;
487
ragge
1.297
488 arg_param_list:    declarator attr_var {
ragge
1.311
489                         olddecl(block(TYMERGE, ccopy($<nodep>0), $1,
490                             INT, 0, 0), $2);
491                 }
ragge
1.251
492                 |  arg_param_list ',' declarator attr_var {
ragge
1.311
493                         olddecl(block(TYMERGE, ccopy($<nodep>0), $3,
494                             INT, 0, 0), $4);
ragge
1.29
495                 }
496                 ;
ragge
1.19
497
498 /*
ragge
1.30
499  * Declarations in beginning of blocks.
500  */
ragge
1.182
501 block_item_list:   block_item
502                 |  block_item_list block_item
503                 ;
504
505 block_item:        declaration
506                 |  statement
ragge
1.30
507                 ;
508
509 /*
ragge
1.19
510  * Here starts the old YACC code.
511  */
512
ragge
1.30
513 /*
ragge
1.29
514  * Variables are declared in init_declarator.
ragge
1.19
515  */
ragge
1.251
516 declaration:       declaration_specifiers ';' { tfree($1); fun_inline = 0; }
ragge
1.71
517                 |  declaration_specifiers init_declarator_list ';' {
ragge
1.251
518                         tfree($1);
ragge
1.50
519                         fun_inline = 0;
ragge
1.19
520                 }
ragge
1.1
521                 ;
ragge
1.4
522
ragge
1.19
523 /*
524  * Normal declaration of variables. curtype contains the current type node.
525  * Returns nothing, variables are declared in init_declarator.
526  */
527 init_declarator_list:
ragge
1.297
528                    init_declarator { symclear(blevel); }
ragge
1.249
529                 |  init_declarator_list ',' attr_var { $<nodep>$ = $<nodep>0; } init_declarator {
ragge
1.308
530                         uawarn($3, "init_declarator");
ragge
1.297
531                         symclear(blevel);
ragge
1.249
532                 }
ragge
1.1
533                 ;
ragge
1.4
534
ragge
1.176
535 enum_dcl:          enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); }
536                 |  C_ENUM C_NAME {  $$ = enumref($2); }
ragge
1.1
537                 ;
538
ragge
1.176
539 enum_head:         C_ENUM { $$ = enumhd(NULL); }
540                 |  C_ENUM C_NAME {  $$ = enumhd($2); }
ragge
1.1
541                 ;
542
543 moe_list:          moe
ragge
1.71
544                 |  moe_list ',' moe
ragge
1.1
545                 ;
546
ragge
1.176
547 moe:               C_NAME {  moedef($1); }
ragge
1.188
548                 |  C_TYPENAME {  moedef($1); }
ragge
1.271
549                 |  C_NAME '=' e { enummer = con_e($3); moedef($1); }
550                 |  C_TYPENAME '=' e { enummer = con_e($3); moedef($1); }
ragge
1.8
551                 ;
552
ragge
1.289
553 struct_dcl:        str_head '{' struct_dcl_list '}' {
554                         NODE *p;
555
556                         $$ = dclstruct($1);
557                         if (pragma_allpacked) {
558                                 p = bdty(CALL, bdty(NAME, "packed"),
559                                     bcon(pragma_allpacked));
ragge
1.369
560                                 $$->n_ap = attr_add($$->n_ap,gcc_attr_wrapper(p)); }
ragge
1.289
561                 }
ragge
1.308
562                 |  C_STRUCT attr_var C_NAME { 
563                         $$ = rstruct($3,$1);
564                         uawarn($2, "struct_dcl");
ragge
1.249
565                 }
ragge
1.248
566  /*COMPAT_GCC*/ |  str_head '{' '}' { $$ = dclstruct($1); }
ragge
1.8
567                 ;
568
ragge
1.241
569 attr_var:          {    
ragge
1.251
570                         NODE *q, *p;
571
572                         p = pragma_aligned ? bdty(CALL, bdty(NAME, "aligned"),
573                             bcon(pragma_aligned)) : NIL;
ragge
1.255
574                         if (pragma_packed) {
ragge
1.251
575                                 q = bdty(NAME, "packed");
576                                 p = (p == NIL ? q : cmop(p, q));
577                         }
578                         pragma_aligned = pragma_packed = 0;
579                         $$ = p;
ragge
1.235
580                 }
ragge
1.249
581  /*COMPAT_GCC*/ |  attr_spec_list
ragge
1.172
582                 ;
583
ragge
1.240
584 attr_spec_list:    attribute_specifier 
ragge
1.248
585                 |  attr_spec_list attribute_specifier { $$ = cmop($1, $2); }
ragge
1.240
586                 ;
587
ragge
1.241
588 str_head:          C_STRUCT attr_var {  $$ = bstruct(NULL, $1, $2);  }
ragge
1.296
589                 |  C_STRUCT attr_var C_NAME {  $$ = bstruct($3, $1, $2);  }
ragge
1.1
590                 ;
591
ragge
1.25
592 struct_dcl_list:   struct_declaration
593                 |  struct_dcl_list struct_declaration
ragge
1.1
594                 ;
595
ragge
1.25
596 struct_declaration:
ragge
1.244
597                    specifier_qualifier_list struct_declarator_list optsemi {
ragge
1.294
598                         tfree($1);
ragge
1.4
599                 }
ragge
1.1
600                 ;
601
ragge
1.244
602 optsemi:           ';' { }
603                 |  optsemi ';' { werror("extra ; in struct"); }
604                 ;
605
ragge
1.25
606 specifier_qualifier_list:
ragge
1.72
607                    merge_specifiers { $$ = typenode($1); }
ragge
1.25
608                 ;
609
ragge
1.247
610 merge_specifiers:  type_sq merge_specifiers { $$ = cmop($2, $1); }
ragge
1.243
611                 |  type_sq { $$ = $1; }
ragge
1.25
612                 ;
ragge
1.1
613
ragge
1.25
614 struct_declarator_list:
ragge
1.297
615                    struct_declarator { symclear(blevel); }
ragge
1.71
616                 |  struct_declarator_list ',' { $<nodep>$=$<nodep>0; } 
ragge
1.297
617                         struct_declarator { symclear(blevel); }
ragge
1.25
618                 ;
619
ragge
1.251
620 struct_declarator: declarator attr_var {
ragge
1.297
621                         NODE *p;
622
623                         $1 = aryfix($1);
624                         p = tymerge($<nodep>0, tymfix($1));
ragge
1.309
625                         if ($2)
ragge
1.369
626                                 p->n_ap = attr_add(p->n_ap, gcc_attr_wrapper($2));
ragge
1.294
627                         soumemb(p, (char *)$1->n_sp, 0);
628                         tfree(p);
ragge
1.89
629                 }
ragge
1.271
630                 |  ':' e {
631                         int ie = con_e($2);
632                         if (fldchk(ie))
633                                 ie = 1;
634                         falloc(NULL, ie, $<nodep>0);
635                 }
ragge
1.314
636                 |  declarator ':' e {
637                         int ie = con_e($3);
638                         if (fldchk(ie))
639                                 ie = 1;
640                         if ($1->n_op == NAME) {
641                                 /* XXX - tymfix() may alter $1 */
642                                 tymerge($<nodep>0, tymfix($1));
643                                 soumemb($1, (char *)$1->n_sp, FIELD | ie);
644                                 nfree($1);
645                         } else
646                                 uerror("illegal declarator");
647                 }
648                 |  declarator ':' e attr_spec_list {
ragge
1.271
649                         int ie = con_e($3);
650                         if (fldchk(ie))
651                                 ie = 1;
ragge
1.72
652                         if ($1->n_op == NAME) {
ragge
1.313
653                                 /* XXX - tymfix() may alter $1 */
ragge
1.297
654                                 tymerge($<nodep>0, tymfix($1));
ragge
1.313
655                                 if ($4)
656                                         $1->n_ap = attr_add($1->n_ap,
ragge
1.369
657                                             gcc_attr_wrapper($4));
ragge
1.271
658                                 soumemb($1, (char *)$1->n_sp, FIELD | ie);
ragge
1.104
659                                 nfree($1);
ragge
1.72
660                         } else
661                                 uerror("illegal declarator");
ragge
1.4
662                 }
ragge
1.231
663                 | /* unnamed member */ {
664                         NODE *p = $<nodep>0;
665                         char *c = permalloc(10);
666
667                         if (p->n_type != STRTY && p->n_type != UNIONTY)
668                                 uerror("bad unnamed member type");
669                         snprintf(c, 10, "*%dFAKE", getlab());
670                         soumemb(p, c, 0);
671                 }
ragge
1.1
672                 ;
ragge
1.4
673
ragge
1.1
674                 /* always preceeded by attributes */
ragge
1.251
675 xnfdeclarator:     declarator attr_var {
ragge
1.347
676                         $$ = xnf = init_declarator($<nodep>0, $1, 1, $2, 0);
ragge
1.251
677                 }
ragge
1.276
678                 |  declarator C_ASM '(' string ')' {
ragge
1.347
679                         $$ = xnf = init_declarator($<nodep>0, $1, 1, NULL, 
680                             newstring($4, strlen($4)));
ragge
1.276
681                 }
ragge
1.1
682                 ;
ragge
1.6
683
ragge
1.19
684 /*
685  * Handles declarations and assignments.
686  * Returns nothing.
687  */
ragge
1.347
688 init_declarator:   declarator attr_var {
689                         init_declarator($<nodep>0, $1, 0, $2, 0);
690                 }
ragge
1.277
691                 |  declarator C_ASM '(' string ')' attr_var {
ragge
1.347
692                         init_declarator($<nodep>0, $1, 0, $6,
693                             newstring($4, strlen($4)));
ragge
1.125
694                 }
ragge
1.330
695                 |  xnfdeclarator '=' e { 
ragge
1.331
696                         if ($1->sclass == STATIC || $1->sclass == EXTDEF)
697                                 statinit++;
ragge
1.330
698                         simpleinit($1, eve($3));
ragge
1.331
699                         if ($1->sclass == STATIC || $1->sclass == EXTDEF)
700                                 statinit--;
ragge
1.330
701                         xnf = NULL;
702                 }
ragge
1.167
703                 |  xnfdeclarator '=' begbr init_list optcomma '}' {
ragge
1.333
704                         endinit(0);
ragge
1.167
705                         xnf = NULL;
706                 }
ragge
1.333
707  /*COMPAT_GCC*/ |  xnfdeclarator '=' begbr '}' { endinit(0); xnf = NULL; }
ragge
1.163
708                 ;
709
710 begbr:             '{' { beginit($<symp>-1); }
711                 ;
712
ragge
1.236
713 initializer:       e %prec ',' {  $$ = eve($1); }
ragge
1.163
714                 |  ibrace init_list optcomma '}' { $$ = NULL; }
ragge
1.233
715                 |  ibrace '}' { asginit(bcon(0)); $$ = NULL; }
ragge
1.163
716                 ;
717
ragge
1.287
718 init_list:         designation initializer { dainit($1, $2); }
719                 |  init_list ','  designation initializer { dainit($3, $4); }
ragge
1.163
720                 ;
721
ragge
1.287
722 designation:       designator_list '=' { desinit($1); $$ = NIL; }
ragge
1.327
723                 |  GCC_DESIG { desinit(bdty(NAME, $1)); $$ = NIL; }
ragge
1.282
724                 |  '[' e C_ELLIPSIS e ']' '=' { $$ = biop(CM, $2, $4); }
725                 |  { $$ = NIL; }
ragge
1.19
726                 ;
ragge
1.1
727
ragge
1.163
728 designator_list:   designator { $$ = $1; }
729                 |  designator_list designator { $$ = $2; $$->n_left = $1; }
ragge
1.1
730                 ;
ragge
1.6
731
ragge
1.271
732 designator:        '[' e ']' {
733                         int ie = con_e($2);
734                         if (ie < 0) {
stefan
1.183
735                                 uerror("designator must be non-negative");
ragge
1.282
736                                 ie = 0;
stefan
1.183
737                         }
ragge
1.271
738                         $$ = biop(LB, NIL, bcon(ie));
stefan
1.183
739                 }
ragge
1.317
740                 |  C_STROP C_TYPENAME {
741                         if ($1 != DOT)
742                                 uerror("invalid designator");
743                         $$ = bdty(NAME, $2);
744                 }
stefan
1.186
745                 |  C_STROP C_NAME {
746                         if ($1 != DOT)
747                                 uerror("invalid designator");
748                         $$ = bdty(NAME, $2);
749                 }
ragge
1.1
750                 ;
751
752 optcomma        :       /* VOID */
ragge
1.71
753                 |  ','
ragge
1.1
754                 ;
755
ragge
1.71
756 ibrace:            '{' {  ilbrace(); }
ragge
1.1
757                 ;
758
759 /*      STATEMENTS      */
760
ragge
1.219
761 compoundstmt:      begin block_item_list '}' { flend(); }
762                 |  begin '}' { flend(); }
ragge
1.1
763                 ;
764
ragge
1.71
765 begin:            '{' {
ragge
1.83
766                         struct savbc *bc = tmpalloc(sizeof(struct savbc));
ragge
1.138
767                         if (blevel == 1) {
768 #ifdef STABS
769                                 if (gflag)
ragge
1.139
770                                         stabs_line(lineno);
ragge
1.138
771 #endif
ragge
1.92
772                                 dclargs();
ragge
1.140
773                         }
ragge
1.138
774 #ifdef STABS
ragge
1.141
775                         if (gflag && blevel > 1)
ragge
1.140
776                                 stabs_lbrac(blevel+1);
ragge
1.138
777 #endif
ragge
1.8
778                         ++blevel;
ragge
1.112
779                         oldstyle = 0;
ragge
1.83
780                         bc->contlab = autooff;
781                         bc->next = savctx;
782                         savctx = bc;
ragge
1.310
783                         if (!isinlining && sspflag && blevel == 2)
gmcgarry
1.204
784                                 sspstart();
ragge
1.8
785                 }
ragge
1.1
786                 ;
787
ragge
1.236
788 statement:         e ';' { ecomp(eve($1)); symclear(blevel); }
ragge
1.1
789                 |  compoundstmt
ragge
1.142
790                 |  ifprefix statement { plabel($1); reached = 1; }
ragge
1.8
791                 |  ifelprefix statement {
ragge
1.72
792                         if ($1 != NOLAB) {
ragge
1.142
793                                 plabel( $1);
ragge
1.1
794                                 reached = 1;
ragge
1.8
795                         }
796                 }
797                 |  whprefix statement {
ragge
1.98
798                         branch(contlab);
ragge
1.142
799                         plabel( brklab );
ragge
1.8
800                         if( (flostat&FBRK) || !(flostat&FLOOP))
801                                 reached = 1;
802                         else
803                                 reached = 0;
804                         resetbc(0);
805                 }
ragge
1.71
806                 |  doprefix statement C_WHILE '(' e ')' ';' {
ragge
1.142
807                         plabel(contlab);
ragge
1.48
808                         if (flostat & FCONT)
ragge
1.8
809                                 reached = 1;
ragge
1.128
810                         if (reached)
ragge
1.318
811                                 cbranch(buildtree(NE, eve($5), bcon(0)),
812                                     bcon($1));
ragge
1.130
813                         else
ragge
1.236
814                                 tfree(eve($5));
ragge
1.142
815                         plabel( brklab);
ragge
1.8
816                         reached = 1;
817                         resetbc(0);
818                 }
ragge
1.71
819                 |  forprefix .e ')' statement
ragge
1.142
820                         {  plabel( contlab );
ragge
1.1
821                             if( flostat&FCONT ) reached = 1;
822                             if( $2 ) ecomp( $2 );
ragge
1.98
823                             branch($1);
ragge
1.142
824                             plabel( brklab );
ragge
1.1
825                             if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
826                             else reached = 0;
827                             resetbc(0);
ragge
1.361
828                             blevel--;
829                             symclear(blevel);
ragge
1.1
830                             }
831                 | switchpart statement
ragge
1.154
832                         { if( reached ) branch( brklab );
ragge
1.142
833                             plabel( $1 );
ragge
1.154
834                             swend();
ragge
1.142
835                             plabel( brklab);
ragge
1.1
836                             if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
837                             resetbc(FCONT);
838                             }
ragge
1.72
839                 |  C_BREAK  ';' {
840                         if (brklab == NOLAB)
841                                 uerror("illegal break");
842                         else if (reached)
843                                 branch(brklab);
844                         flostat |= FBRK;
845                         reached = 0;
846                 }
847                 |  C_CONTINUE  ';' {
848                         if (contlab == NOLAB)
849                                 uerror("illegal continue");
850                         else
851                                 branch(contlab);
852                         flostat |= FCONT;
853                         goto rch;
854                 }
ragge
1.106
855                 |  C_RETURN  ';' {
856                         branch(retlab);
ragge
1.214
857                         if (cftnsp->stype != VOID && 
858                             (cftnsp->sflags & NORETYP) == 0 &&
ragge
1.131
859                             cftnsp->stype != VOID+FTN)
ragge