Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120818154413

Diff

Diff from 1.355 to:

Annotations

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

Annotated File View

ragge
1.355
1 /*      $Id: cgram.y,v 1.355 2012/08/18 15:44:13 ragge 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.72
147 # include <stdarg.h>
ragge
1.124
148 # include <string.h>
ragge
1.170
149 # include <stdlib.h>
ragge
1.136
150
ragge
1.211
151 int fun_inline; /* Reading an inline function */
ragge
1.137
152 int oldstyle;   /* Current function being defined */
ragge
1.167
153 static struct symtab *xnf;
ragge
1.242
154 extern int enummer, tvaloff, inattr;
ragge
1.191
155 extern struct rstack *rpole;
ragge
1.304
156 static int widestr, alwinl;
ragge
1.225
157 NODE *cftnod;
ragge
1.290
158 static int attrwarn = 1;
ragge
1.137
159
ragge
1.214
160 #define NORETYP SNOCREAT /* no return type, save in unused field in symtab */
161
ragge
1.253
162        NODE *bdty(int op, ...);
ragge
1.137
163 static void fend(void);
164 static void fundef(NODE *tp, NODE *p);
ragge
1.251
165 static void olddecl(NODE *p, NODE *a);
ragge
1.347
166 static struct symtab *init_declarator(NODE *tn, NODE *p, int assign, NODE *a,
167         char *as);
ragge
1.137
168 static void resetbc(int mask);
169 static void swend(void);
170 static void addcase(NODE *p);
gmcgarry
1.234
171 #ifdef GCC_COMPAT
ragge
1.229
172 static void gcccase(NODE *p, NODE *);
gmcgarry
1.234
173 #endif
ragge
1.137
174 static void adddef(void);
175 static void savebc(void);
stefan
1.177
176 static void swstart(int, TWORD);
177 static void genswitch(int, TWORD, struct swents **, int);
ragge
1.157
178 static char *mkpstr(char *str);
ragge
1.167
179 static struct symtab *clbrace(NODE *);
ragge
1.195
180 static NODE *cmop(NODE *l, NODE *r);
181 static NODE *xcmop(NODE *out, NODE *in, NODE *str);
182 static void mkxasm(char *str, NODE *p);
183 static NODE *xasmop(char *str, NODE *p);
ragge
1.207
184 static int maxstlen(char *str);
ragge
1.210
185 static char *stradd(char *old, char *new);
ragge
1.215
186 static NODE *biop(int op, NODE *l, NODE *r);
gmcgarry
1.223
187 static void flend(void);
ragge
1.241
188 static char * simname(char *s);
gmcgarry
1.234
189 #ifdef GCC_COMPAT
ragge
1.230
190 static NODE *tyof(NODE *);      /* COMPAT_GCC */
ragge
1.235
191 static NODE *voidcon(void);     /* COMPAT_GCC */
gmcgarry
1.234
192 #endif
ragge
1.297
193 static NODE *funargs(NODE *p);
ragge
1.259
194 static void oldargs(NODE *p);
ragge
1.275
195 static void uawarn(NODE *p, char *s);
ragge
1.271
196 static int con_e(NODE *p);
ragge
1.286
197 static void dainit(NODE *d, NODE *a);
ragge
1.297
198 static NODE *tymfix(NODE *p);
199 static NODE *namekill(NODE *p, int clr);
200 static NODE *aryfix(NODE *p);
ragge
1.355
201 static void savlab(int);
202 extern int *mkclabs(void);
ragge
1.137
203
ragge
1.306
204 #define TYMFIX(inp) { \
205         NODE *pp = inp; \
206         inp = tymerge(pp->n_left, pp->n_right); \
207         nfree(pp->n_left); nfree(pp); }
ragge
1.137
208 /*
209  * State for saving current switch state (when nested switches).
210  */
211 struct savbc {
212         struct savbc *next;
213         int brklab;
214         int contlab;
215         int flostat;
216         int swx;
217 } *savbc, *savctx;
218
ragge
1.1
219 %}
220
ragge
1.136
221 %union {
222         int intval;
223         NODE *nodep;
224         struct symtab *symp;
225         struct rstack *rp;
226         char *strp;
227 }
228
ragge
1.1
229         /* define types */
230 %start ext_def_list
231
ragge
1.271
232 %type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart
ragge
1.304
233                 xbegin
ragge
1.297
234 %type <nodep> e .e term enum_dcl struct_dcl cast_type declarator
ragge
1.251
235                 elist type_sq cf_spec merge_attribs
ragge
1.163
236                 parameter_declaration abstract_declarator initializer
ragge
1.353
237                 parameter_type_list parameter_list
ragge
1.284
238                 declaration_specifiers designation
ragge
1.271
239                 specifier_qualifier_list merge_specifiers
ragge
1.251
240                 identifier_list arg_param_list type_qualifier_list
ragge
1.212
241                 designator_list designator xasm oplist oper cnstr funtype
ragge
1.236
242                 typeof attribute attribute_specifier /* COMPAT_GCC */
ragge
1.249
243                 attribute_list attr_spec_list attr_var /* COMPAT_GCC */
ragge
1.327
244 %type <strp>    string C_STRING GCC_DESIG
ragge
1.176
245 %type <rp>      str_head
246 %type <symp>    xnfdeclarator clbrace enum_head
ragge
1.1
247
ragge
1.242
248 %type <intval>  C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
ragge
1.105
249                 C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
ragge
1.172
250
ragge
1.242
251 %type <nodep>   C_TYPE C_QUALIFIER C_ICON C_FCON C_CLASS
ragge
1.168
252 %type <strp>    C_NAME C_TYPENAME
pj
1.135
253 %%
254
ragge
1.1
255 ext_def_list:      ext_def_list external_def
ragge
1.4
256                 | { ftnend(); }
ragge
1.1
257                 ;
ragge
1.4
258
ragge
1.241
259 external_def:      funtype kr_args compoundstmt { fend(); }
260                 |  declaration  { blevel = 0; symclear(0); }
ragge
1.127
261                 |  asmstatement ';'
ragge
1.71
262                 |  ';'
ragge
1.33
263                 |  error { blevel = 0; }
ragge
1.1
264                 ;
ragge
1.4
265
ragge
1.212
266 funtype:          /* no type given */ declarator {
ragge
1.322
267                     fundef(mkty(INT, 0, 0), $1);
ragge
1.214
268                     cftnsp->sflags |= NORETYP;
ragge
1.212
269                 }
270                 | declaration_specifiers declarator { fundef($1,$2); }
271                 ;
272
273 kr_args:          /* empty */
274                 | arg_dcl_list
ragge
1.1
275                 ;
276
ragge
1.19
277 /*
278  * Returns a node pointer or NULL, if no types at all given.
279  * Type trees are checked for correctness and merged into one
280  * type node in typenode().
281  */
282 declaration_specifiers:
ragge
1.162
283                    merge_attribs { $$ = typenode($1); }
ragge
1.19
284                 ;
285
ragge
1.243
286 merge_attribs:     type_sq { $$ = $1; }
ragge
1.247
287                 |  type_sq merge_attribs { $$ = cmop($2, $1); }
ragge
1.243
288                 |  cf_spec { $$ = $1; }
ragge
1.247
289                 |  cf_spec merge_attribs { $$ = cmop($2, $1); }
ragge
1.50
290                 ;
291
ragge
1.243
292 type_sq:           C_TYPE { $$ = $1; }
ragge
1.72
293                 |  C_TYPENAME { 
294                         struct symtab *sp = lookup($1, 0);
ragge
1.296
295                         if (sp->stype == ENUMTY) {
296                                 sp->stype = strmemb(sp->sap)->stype;
297                         }
298                         $$ = mkty(sp->stype, sp->sdf, sp->sap);
ragge
1.72
299                         $$->n_sp = sp;
300                 }
ragge
1.19
301                 |  struct_dcl { $$ = $1; }
302                 |  enum_dcl { $$ = $1; }
ragge
1.243
303                 |  C_QUALIFIER { $$ = $1; }
ragge
1.248
304                 |  attribute_specifier { $$ = biop(ATTRIB, $1, 0); }
ragge
1.243
305                 |  typeof { $$ = $1; }
306                 ;
307
308 cf_spec:           C_CLASS { $$ = $1; }
ragge
1.242
309                 |  C_FUNSPEC { fun_inline = 1;  /* XXX - hack */
310                         $$ = block(QUALIFIER, NIL, NIL, 0, 0, 0); }
ragge
1.19
311                 ;
312
plunky
1.336
313 typeof:            C_TYPEOF '(' e ')' { $$ = tyof(eve($3)); }
ragge
1.306
314                 |  C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); }
315                 ;
ragge
1.230
316
ragge
1.235
317 attribute_specifier :
318                    C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; }
319  /*COMPAT_GCC*/ ;
320
321 attribute_list:    attribute
322                 |  attribute ',' attribute_list { $$ = cmop($3, $1); }
323                 ;
324
gmcgarry
1.252
325 attribute:         {
326 #ifdef GCC_COMPAT
327                          $$ = voidcon();
328 #endif
329                 }
ragge
1.235
330                 |  C_NAME { $$ = bdty(NAME, $1); }
ragge
1.236
331                 |  C_NAME '(' elist ')' {
ragge
1.235
332                         $$ = bdty($3 == NIL ? UCALL : CALL, bdty(NAME, $1), $3);
333                 }
334                 ;
335
ragge
1.19
336 /*
ragge
1.23
337  * Adds a pointer list to front of the declarators.
ragge
1.19
338  */
ragge
1.251
339 declarator:        '*' declarator { $$ = bdty(UMUL, $2); }
ragge
1.261
340                 |  '*' type_qualifier_list declarator {
ragge
1.296
341                         $$ = $2;
342                         $$->n_left = $3;
ragge
1.261
343                 }
ragge
1.251
344                 |  C_NAME { $$ = bdty(NAME, $1); }
ragge
1.296
345                 |  '(' attr_spec_list declarator ')' {
346                         $$ = $3;
347                         $$->n_ap = attr_add($$->n_ap, gcc_attr_parse($2));
348                 }
ragge
1.71
349                 |  '(' declarator ')' { $$ = $2; }
ragge
1.297
350                 |  declarator '[' e ']' { $$ = biop(LB, $1, $3); }
ragge
1.305
351                 |  declarator '[' C_CLASS e ']' {
352                         if ($3->n_type != STATIC)
353                                 uerror("bad class keyword");
354                         tfree($3); /* XXX - handle */
355                         $$ = biop(LB, $1, $4);
356                 }
ragge
1.269
357                 |  declarator '[' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
358                 |  declarator '[' '*' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); }
ragge
1.304
359                 |  declarator '(' parameter_type_list ')' {
360                         $$ = bdty(CALL, $1, $3);
ragge
1.259
361                 }
ragge
1.304
362                 |  declarator '(' identifier_list ')' {
363                         $$ = bdty(CALL, $1, $3);
ragge
1.29
364                         oldstyle = 1;
ragge
1.187
365                 }
ragge
1.304
366                 |  declarator '(' ')' { $$ = bdty(UCALL, $1); }
ragge
1.187
367                 ;
368
ragge
1.251
369 type_qualifier_list:
ragge
1.296
370                    C_QUALIFIER { $$ = $1; $$->n_op = UMUL; }
ragge
1.251
371                 |  type_qualifier_list C_QUALIFIER {
372                         $$ = $1;
ragge
1.296
373                         $$->n_qual |= $2->n_qual;
ragge
1.251
374                         nfree($2);
375                 }
ragge
1.296
376                 |  attribute_specifier {
377                         $$ = block(UMUL, NIL, NIL, 0, 0, gcc_attr_parse($1));
378                 }
ragge
1.251
379                 |  type_qualifier_list attribute_specifier {
ragge
1.296
380                         $1->n_ap = attr_add($1->n_ap, gcc_attr_parse($2));
ragge
1.251
381                 }
382                 ;
383
ragge
1.259
384 identifier_list:   C_NAME { $$ = bdty(NAME, $1); oldargs($$); }
ragge
1.296
385                 |  identifier_list ',' C_NAME {
386                         $$ = cmop($1, bdty(NAME, $3));
387                         oldargs($$->n_right);
388                 }
ragge
1.19
389                 ;
390
391 /*
392  * Returns as parameter_list, but can add an additional ELLIPSIS node.
393  */
394 parameter_type_list:
ragge
1.55
395                    parameter_list { $$ = $1; }
ragge
1.71
396                 |  parameter_list ',' C_ELLIPSIS {
ragge
1.215
397                         $$ = cmop($1, biop(ELLIPSIS, NIL, NIL));
ragge
1.19
398                 }
399                 ;
400
401 /*
ragge
1.55
402  * Returns a linked lists of nodes of op CM with parameters on
403  * its right and additional CM nodes of its left pointer.
404  * No CM nodes if only one parameter.
ragge
1.19
405  */
ragge
1.162
406 parameter_list:    parameter_declaration { $$ = $1; }
ragge
1.71
407                 |  parameter_list ',' parameter_declaration {
ragge
1.215
408                         $$ = cmop($1, $3);
ragge
1.19
409                 }
410                 ;
411
412 /*
413  * Returns a node pointer to the declaration.
414  */
415 parameter_declaration:
ragge
1.251
416                    declaration_specifiers declarator attr_var {
ragge
1.296
417                         if ($1->n_lval != SNULL && $1->n_lval != REGISTER)
ragge
1.187
418                                 uerror("illegal parameter class");
ragge
1.297
419                         $$ = block(TYMERGE, $1, $2, INT, 0, gcc_attr_parse($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),
444                             INT, 0, gcc_attr_parse($3));
ragge
1.251
445                 }
ragge
1.271
446                 |  '[' e ']' attr_var {
ragge
1.297
447                         $$ = block(LB, bdty(NAME, NULL), $2,
448                             INT, 0, gcc_attr_parse($4));
ragge
1.40
449                 }
ragge
1.251
450                 |  abstract_declarator '[' ']' attr_var {
ragge
1.297
451                         $$ = block(LB, $1, bcon(NOOFFSET),
452                             INT, 0, gcc_attr_parse($4));
ragge
1.214
453                 }
ragge
1.271
454                 |  abstract_declarator '[' e ']' attr_var {
ragge
1.297
455                         $$ = block(LB, $1, $3, INT, 0, gcc_attr_parse($5));
ragge
1.56
456                 }
ragge
1.342
457                 |  '(' ')' attr_var {
458                         $$ = bdty(UCALL, bdty(NAME, NULL));
459                         $$->n_ap = gcc_attr_parse($3);
460                 }
461                 |  '(' ib2 parameter_type_list ')' attr_var {
462                         $$ = block(CALL, bdty(NAME, NULL), $3, INT, 0,
463                             gcc_attr_parse($5));
ragge
1.56
464                 }
ragge
1.342
465                 |  abstract_declarator '(' ')' attr_var {
466                         $$ = block(UCALL, $1, NIL, INT, 0, gcc_attr_parse($4));
ragge
1.56
467                 }
ragge
1.342
468                 |  abstract_declarator '(' ib2 parameter_type_list ')' attr_var {
469                         $$ = block(CALL, $1, $4, INT, 0, gcc_attr_parse($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.321
560                                 $$->n_ap = attr_add($$->n_ap,gcc_attr_parse(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)
626                                 p->n_ap = attr_add(p->n_ap, gcc_attr_parse($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,
657                                             gcc_attr_parse($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.320
828                             symclear(blevel); /* if declaration inside for() */
ragge
1.1
829                             }
830                 | switchpart statement
ragge
1.154
831                         { if( reached ) branch( brklab );
ragge
1.142
832                             plabel( $1 );
ragge
1.154
833                             swend();
ragge
1.142
834                             plabel( brklab);
ragge
1.1
835                             if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
836                             resetbc(FCONT);
837                             }
ragge
1.72
838                 |  C_BREAK  ';' {
839                         if (brklab == NOLAB)
840                                 uerror("illegal break");
841                         else if (reached)
842                                 branch(brklab);
843                         flostat |= FBRK;
844                         reached = 0;
845                 }
846                 |  C_CONTINUE  ';' {
847                         if (contlab == NOLAB)
848                                 uerror("illegal continue");
849                         else
850                                 branch(contlab);
851                         flostat |= FCONT;
852                         goto rch;
853                 }
ragge
1.106
854                 |  C_RETURN  ';' {
855                         branch(retlab);
ragge
1.214
856                         if (cftnsp->stype != VOID && 
857                             (cftnsp->sflags & NORETYP) == 0 &&
ragge
1.131
858                             cftnsp->stype != VOID+FTN)
ragge
1.106
859                                 uerror("return value required");
ragge
1.1
860                         rch:
ragge
1.316
861                         if (!reached)
862                                 warner(Wunreachable_code, NULL);
ragge
1.106
863                         reached = 0;
864                 }
ragge
1.71
865                 |  C_RETURN e  ';' {
ragge
1.