]> andersk Git - splint.git/blob - src/cgrammar.y
Made allocations involving sizeof work correctly (test/malloc.c).
[splint.git] / src / cgrammar.y
1 /*;-*-C-*-;
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 %{
25 /*
26 **
27 ** cgrammar.y
28 **
29 ** Yacc/Bison grammar for extended ANSI C used by Splint.
30 **
31 ** original grammar by Nate Osgood ---
32 **    hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993
33 **
34 ** changes for Splint --- handle typedef names correctly
35 ** fix struct/union parsing bug (empty struct is accepted)
36 ** add productions to handle macros --- require
37 ** error correction --- main source of conflicts in grammar.
38 ** need to process initializations sequentially, L->R
39 **
40 ** production names are cryptic, so more productions fit on one line
41 **
42 ** conflicts:  87 shift/reduce, 18 reduce/reduce
43 ** most of these are due to handling macros
44 ** a few are due to handling type expressions
45 */
46
47 /*@=allmacros@*/
48
49 extern int yylex ();
50 extern void yyerror (char *);
51
52 # include "splintMacros.nf"
53 # include "basic.h"
54 # include "cscanner.h"
55 # include "cscannerHelp.h"
56 # include "cgrammar.h"
57 # include "exprChecks.h"
58
59 /*@-allmacros@*/
60 /*@-matchfields@*/
61
62 # define SHOWCSYM FALSE
63
64 /*
65 ** This is necessary, or else when the bison-generated code #include's malloc.h,
66 ** there will be a parse error.
67 **
68 ** Unfortunately, it means the error checking on malloc, etc. is lost for allocations
69 ** in bison-generated files under Win32.
70 */
71
72 # ifdef WIN32
73 # undef malloc
74 # undef calloc
75 # undef realloc
76 # endif
77
78 %}
79
80 %union
81 {
82   lltok tok;
83   int count;
84   qual typequal;
85   qualList tquallist;
86   ctype ctyp;
87   /*@dependent@*/ sRef sr;
88   /*@only@*/ sRef osr;
89
90   /*@only@*/ functionClauseList funcclauselist;
91   /*@only@*/ functionClause funcclause;  
92   /*@only@*/ flagSpec flagspec;
93   /*@only@*/ globalsClause globsclause;
94   /*@only@*/ modifiesClause modsclause;
95   /*@only@*/ warnClause warnclause;
96   /*@only@*/ stateClause stateclause;
97   /*@only@*/ pointers pointers;
98   /*@only@*/ functionConstraint fcnconstraint; 
99
100   /*@only@*/ metaStateConstraint msconstraint;
101   /*@only@*/ metaStateSpecifier msspec;
102   /*@only@*/ metaStateExpression msexpr;
103   /*@observer@*/ metaStateInfo msinfo;
104
105   /*@only@*/ sRefList srlist;
106   /*@only@*/ globSet globset;
107   /*@only@*/ qtype qtyp;
108   /*@only@*/ cstring cname;
109   /*@observer@*/ annotationInfo annotation;
110   /*@only@*/ idDecl ntyp;
111   /*@only@*/ idDeclList ntyplist;
112   /*@only@*/ uentryList flist;
113   /*@owned@*/ uentryList entrylist;
114   /*@observer@*/ /*@dependent@*/ uentry entry;
115   /*@only@*/ uentry oentry;
116   /*@only@*/ exprNode expr;
117   /*@only@*/ enumNameList enumnamelist;
118   /*@only@*/ exprNodeList exprlist;
119   /*@only@*/ sRefSet srset; 
120   /*@only@*/ cstringList cstringlist;
121
122   /*drl
123     added 1/19/2001
124   */
125   constraint con;
126   constraintList conL;
127   constraintExpr conE;
128   /* drl */  
129 }
130
131 /* standard C tokens */
132
133 %token <tok> BADTOK SKIPTOK
134 %token <tok> CTOK_ELIPSIS CASE DEFAULT CIF CELSE SWITCH WHILE DO CFOR
135 %token <tok> GOTO CONTINUE BREAK RETURN
136 %token <tok> TSEMI TLBRACE TRBRACE TCOMMA TCOLON TASSIGN TLPAREN 
137 %token <tok> TRPAREN TLSQBR TRSQBR TDOT TAMPERSAND TEXCL TTILDE
138 %token <tok> TMINUS TPLUS TMULT TDIV TPERCENT TLT TGT TCIRC TBAR TQUEST
139 %token <tok> CSIZEOF CALIGNOF CTYPEOF ARROW_OP CTYPEDEF COFFSETOF
140 %token <tok> INC_OP DEC_OP LEFT_OP RIGHT_OP
141 %token <tok> LE_OP GE_OP EQ_OP NE_OP AND_OP OR_OP
142 %token <tok> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN
143 %token <tok> LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
144 %token <tok> CSTRUCT CUNION CENUM
145 %token <tok> VA_ARG VA_DCL
146 %token <tok> QWARN
147 %token <tok> QGLOBALS
148 %token <tok> QMODIFIES 
149 %token <tok> QNOMODS
150 %token <tok> QCONSTANT
151 %token <tok> QFUNCTION
152 %token <tok> QITER
153 %token <tok> QDEFINES 
154 %token <tok> QUSES
155 %token <tok> QALLOCATES
156 %token <tok> QSETS
157 %token <tok> QRELEASES 
158 %token <tok> QPRECLAUSE 
159 %token <tok> QPOSTCLAUSE
160 %token <tok> QINVARIANT
161 %token <tok> QALT 
162 %token <tok> QUNDEF QKILLED
163 %token <tok> QENDMACRO
164
165 /* additional tokens introduced by splint pre-processor. */
166 %token <tok> LLMACRO LLMACROITER LLMACROEND TENDMACRO
167
168 /* break comments: */
169 %token <tok> QSWITCHBREAK QLOOPBREAK QINNERBREAK QSAFEBREAK
170 %token <tok> QINNERCONTINUE
171
172 /* case fall-through marker: */
173 %token <tok> QFALLTHROUGH
174
175 /* used in scanner only */
176 %token <tok> QLINTNOTREACHED
177 %token <tok> QLINTFALLTHROUGH
178 %token <tok> QLINTFALLTHRU
179 %token <tok> QARGSUSED
180 %token <tok> QPRINTFLIKE QLINTPRINTFLIKE QSCANFLIKE QMESSAGELIKE
181
182 /* not-reached marker: (used like a label) */
183 %token <tok> QNOTREACHED
184
185 /* type qualifiers: */
186 %token <tok> QCONST QRESTRICT QVOLATILE QINLINE QEXTENSION QEXTERN QSTATIC QAUTO QREGISTER
187 %token <tok> QOUT QIN QYIELD QONLY QTEMP QSHARED QREF QUNIQUE
188 %token <tok> QCHECKED QUNCHECKED QCHECKEDSTRICT QCHECKMOD
189 %token <tok> QKEEP QKEPT QPARTIAL QSPECIAL QOWNED QDEPENDENT
190 %token <tok> QRETURNED QEXPOSED QNULL QOBSERVER QISNULL 
191 %token <tok> QEXITS QMAYEXIT QNEVEREXIT QTRUEEXIT QFALSEEXIT
192 %token <tok> QLONG QSIGNED QUNSIGNED QSHORT QUNUSED QSEF QNOTNULL QRELNULL
193 %token <tok> QABSTRACT QNUMABSTRACT QCONCRETE QMUTABLE QIMMUTABLE
194 %token <tok> QTRUENULL QFALSENULL QEXTERNAL
195 %token <tok> QREFCOUNTED QREFS QNEWREF QTEMPREF QKILLREF QRELDEF
196 %token <ctyp> CGCHAR CBOOL CINT CGFLOAT CDOUBLE CVOID 
197 %token <tok> QANYTYPE QINTEGRALTYPE QUNSIGNEDINTEGRALTYPE QSIGNEDINTEGRALTYPE
198
199 %token <tok> QNULLTERMINATED
200 %token <tok> QSETBUFFERSIZE
201 %token <tok> QSETSTRINGLENGTH
202 %token <tok> QMAXSET
203 %token <tok> QMAXREAD
204 %token <tok> QTESTINRANGE
205
206 %token <tok> TCAND
207
208
209 /* identifiers, literals */
210 %token <entry> IDENTIFIER
211 %token <cname> NEW_IDENTIFIER TYPE_NAME_OR_ID 
212 %token <annotation> CANNOTATION
213 %token <expr> CCONSTANT
214 %type <cname> flagId
215 %type <flagspec> flagSpec
216 %type <expr> cconstantExpr
217 %token <entry> ITER_NAME ITER_ENDNAME 
218 %type <entry> endIter 
219
220 %type <funcclauselist> functionClauses functionClausesPlain
221 %type <funcclause> functionClause functionClause functionClausePlain
222
223 %type <globsclause> globalsClause globalsClausePlain
224 %type <modsclause> modifiesClause modifiesClausePlain nomodsClause
225 %type <warnclause> warnClause warnClausePlain optWarnClause
226 %type <funcclause> conditionClause conditionClausePlain
227 %type <stateclause> stateClause stateClausePlain
228 %type <msconstraint> metaStateConstraint 
229 %type <fcnconstraint> functionConstraint
230 %type <msspec> metaStateSpecifier
231 %type <msexpr> metaStateExpression
232
233 %type <sr> globId globIdListExpr
234 %type <globset> globIdList
235
236 %token <ctyp>  TYPE_NAME 
237 %token <msinfo> METASTATE_NAME 
238 %type <msinfo> metaStateName
239 %type <cname> enumerator newId  /*@-varuse@*/ /* yacc declares yytranslate here */
240 %type <pointers> pointers /*@=varuse@*/
241
242 %type <tok> doHeader stateTag conditionTag startConditionClause
243 %type <typequal> exitsQualifier checkQualifier stateQualifier 
244                  paramQualifier returnQualifier visibilityQualifier
245                  typedefQualifier refcountQualifier definedQualifier
246
247 /* type construction */
248 %type <ctyp> abstractDecl abstractDeclBase optAbstractDeclBase
249 %type <ctyp> suSpc enumSpc typeName typeSpecifier
250
251 %type <ntyp> namedDecl namedDeclBase optNamedDecl
252 %type <ntyp> plainNamedDecl plainNamedDeclBase
253 %type <ntyp> structNamedDecl
254 %type <ntyp> fcnDefHdrAux plainFcn
255
256 %type <oentry> paramDecl 
257 %type <entry> id 
258
259 %type <ntyplist> structNamedDeclList
260
261 %type <entrylist> genericParamList paramTypeList paramList idList paramIdList
262 %type <exprlist> argumentExprList iterArgList
263 %type <exprlist> initList namedInitializerList namedInitializerListAux namedInitializerTypeList namedInitializerTypeListAux
264 %type <flist> structDeclList structDecl
265 %type <srset> locModifies modList specClauseList optSpecClauseList
266 %type <sr>    mExpr modListExpr specClauseListExpr
267
268 /*drl*/
269 %type <con> BufConstraint
270 %type <tok> relationalOp
271 %type <tok> BufBinaryOp
272 %type <tok> bufferModifier
273
274 %type <conE> BufConstraintExpr
275
276 %type <conE> BufConstraintTerm
277 %type <sr> BufConstraintSrefExpr
278
279 %type <conL> BufConstraintList
280
281 %type <conL> optStructInvariant
282
283 %type <tok>  BufUnaryOp
284
285 /*drl 1/6/2002 either /\ or && */
286 %type <tok> constraintSeperator
287
288 %type <enumnamelist> enumeratorList 
289 %type <cstringlist> fieldDesignator
290
291 %type <expr> sizeofExpr sizeofExprAux offsetofExpr
292 %type <expr> openScope closeScope 
293 %type <expr> instanceDecl namedInitializer optDeclarators namedInitializerType
294 %type <expr> primaryExpr postfixExpr primaryIterExpr postfixIterExpr
295 %type <expr> unaryExpr castExpr timesExpr plusExpr
296 %type <expr> unaryIterExpr castIterExpr timesIterExpr plusIterExpr
297 %type <expr> shiftExpr relationalExpr equalityExpr bitandExpr
298 %type <expr> xorExpr bitorExpr andExpr
299 %type <expr> orExpr conditionalExpr assignExpr 
300 %type <expr> shiftIterExpr relationalIterExpr equalityIterExpr bitandIterExpr
301 %type <expr> xorIterExpr bitorIterExpr andIterExpr
302 %type <expr> orIterExpr conditionalIterExpr assignIterExpr iterArgExpr
303 %type <expr> expr optExpr constantExpr
304 %type <expr> init macroBody iterBody endBody partialIterStmt iterSelectionStmt
305 %type <expr> stmt stmtList fcnBody iterStmt iterDefStmt iterDefStmtList
306 %type <expr> labeledStmt caseStmt defaultStmt 
307 %type <expr> compoundStmt compoundStmtAux compoundStmtRest compoundStmtAuxErr
308 %type <expr> expressionStmt selectionStmt iterationStmt jumpStmt iterDefIterationStmt 
309 %type <expr> stmtErr stmtListErr compoundStmtErr expressionStmtErr 
310 %type <expr> iterationStmtErr initializerList typeInitializerList initializer
311 %type <expr> ifPred whilePred forPred iterWhilePred typeInitializer
312
313 %type <expr> designator designatorList designation
314
315 %type <typequal> storageSpecifier typeQualifier typeModifier globQual innerMods
316 %type <tquallist> optGlobQuals innerModsList
317 %type <qtyp> completeType completeTypeSpecifier optCompleteType
318 %type <qtyp> completeTypeSpecifierAux altType typeExpression 
319
320 %start file
321
322 %%
323
324 file
325  :              
326  | externalDefs
327  ;
328
329 externalDefs
330  : externalDef { context_checkGlobalScope (); }
331  | externalDefs externalDef { context_checkGlobalScope (); }
332  ;
333
334 externalDef
335  : fcnDef optSemi { uentry_clearDecl (); } 
336  | constantDecl   { uentry_clearDecl (); } 
337  | fcnDecl        { uentry_clearDecl (); }
338  | iterDecl       { uentry_clearDecl (); } 
339  | macroDef       { uentry_clearDecl (); } 
340  | initializer    { uentry_checkDecl (); exprNode_free ($1); }
341  | TSEMI          { uentry_clearDecl (); lltok_free ($1); /* evans 2002-02-08: okay to have a null statement */ }  
342  | error          { uentry_clearDecl (); } 
343  ;
344
345 constantDecl
346  : QCONSTANT completeTypeSpecifier NotType namedDecl NotType optSemi IsType QENDMACRO
347    { checkConstant ($2, $4); lltok_free2 ($1, $8); }
348  | QCONSTANT completeTypeSpecifier NotType namedDecl NotType TASSIGN IsType init optDeclarators optSemi QENDMACRO
349    { checkValueConstant ($2, $4, $8); lltok_free3 ($1, $6, $11); }
350 ;
351
352 fcnDecl
353  : QFUNCTION { context_enterFunctionHeader (); } plainFcn optSemi QENDMACRO 
354    { 
355      declareStaticFunction ($3); context_quietExitFunction (); 
356      context_exitFunctionHeader (); 
357      lltok_free2 ($1, $5); /*!*/
358    }
359 ;
360
361 plainFcn
362  : plainNamedDecl
363    { 
364      qtype qint = qtype_create (ctype_int);
365      $$ = idDecl_fixBase ($1, qint);
366      qtype_free (qint);
367    }
368  | completeTypeSpecifier NotType plainNamedDecl
369    { $$ = idDecl_fixBase ($3, $1); }
370 ;
371
372 plainNamedDecl
373  : plainNamedDeclBase
374  | pointers plainNamedDeclBase 
375    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
376 ;
377
378 namedDeclBase
379  : newId { $$ = idDecl_create ($1, qtype_unknown ()); }
380  | IsType TLPAREN NotType namedDecl IsType TRPAREN
381    { $$ = idDecl_expectFunction ($4); lltok_free2 ($2, $6); }
382  | namedDeclBase TLSQBR TRSQBR 
383    { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); lltok_free2 ($2, $3); }
384  | namedDeclBase TLSQBR IsType constantExpr TRSQBR NotType
385    {
386      exprNode_findValue ($4);
387      idDecl_notExpectingFunction ($1);
388
389      if (exprNode_hasValue ($4)) 
390        {
391          $$ = idDecl_replaceCtype ($1, ctype_makeInnerFixedArray (idDecl_getCtype ($1), 
392                                                                   exprNode_getLongValue ($4)));
393        } 
394      else
395        {
396          $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); 
397        }
398
399      lltok_free2 ($2, $5);
400    }
401  | namedDeclBase PushType TLPAREN TRPAREN 
402    { setCurrentParams (uentryList_missingParams); }
403    functionClauses
404    { /* need to support globals and modifies here! */
405      functionClauseList fcl;
406      ctype ct = ctype_makeFunction (idDecl_getCtype ($1), 
407                                     uentryList_makeMissingParams ());
408      
409      $$ = idDecl_replaceCtype ($1, ct);
410
411      /*drl 7/25/01 added*/
412      setImplicitfcnConstraints();
413
414      DPRINTF((message("namedDeclBase PushType TLPAREN TRPAREN...:\n adding implict constraints to functionClause List: %s",
415                       functionClauseList_unparse($6)
416                       )
417               ));
418      
419      fcl = functionClauseList_setImplicitConstraints($6);
420
421      idDecl_addClauses ($$, fcl);
422
423      DPRINTF((message("1 added fuctionClause List: %s to the Id",
424                       functionClauseList_unparse(fcl)
425                       )
426               ));
427
428      
429      context_popLoc ();
430      lltok_free2 ($3, $4);
431    }
432  | namedDeclBase PushType TLPAREN genericParamList TRPAREN 
433    { setCurrentParams ($4); } 
434    functionClauses
435    {
436      functionClauseList fcl;
437      setImplicitfcnConstraints ();
438      clearCurrentParams ();
439      $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4));
440
441      DPRINTF((message("namedDeclBase PushType TLPAREN genericParamList TRPAREN...:\n adding implict constraints to functionClause List: %s",
442                       functionClauseList_unparse($7)
443                       )
444               )) ;
445      
446      fcl = functionClauseList_setImplicitConstraints($7);
447
448      idDecl_addClauses ($$, fcl);
449
450      DPRINTF((message("added fuctionClause List: %s to the Id",
451                       functionClauseList_unparse(fcl)
452                       )
453               ));
454
455      
456      context_popLoc (); 
457      lltok_free2 ($3, $5);
458    }
459 ;
460
461 plainNamedDeclBase
462  : newId { $$ = idDecl_create ($1, qtype_unknown ()); }
463  | IsType TLPAREN NotType plainNamedDecl IsType TRPAREN
464    { $$ = idDecl_expectFunction ($4); lltok_free2 ($2, $6); }
465  | plainNamedDeclBase TLSQBR TRSQBR 
466    { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); 
467      lltok_free2 ($2, $3); 
468    }
469  | plainNamedDeclBase TLSQBR IsType constantExpr TRSQBR NotType
470    { 
471      int value;
472
473      if (exprNode_hasValue ($4) 
474          && multiVal_isInt (exprNode_getValue ($4)))
475        {
476          value = (int) multiVal_forceInt (exprNode_getValue ($4));
477        }
478      else
479        {
480          value = 0;
481        }
482
483      $$ = idDecl_replaceCtype ($1, ctype_makeInnerFixedArray (idDecl_getCtype ($1), value));
484      lltok_free2 ($2, $5);
485    }
486  | plainNamedDeclBase PushType TLPAREN TRPAREN 
487    { setCurrentParams (uentryList_missingParams); }
488    functionClausesPlain
489    {
490      ctype ct = ctype_makeFunction (idDecl_getCtype ($1), 
491                                     uentryList_makeMissingParams ());
492      
493      $$ = idDecl_replaceCtype ($1, ct);
494      idDecl_addClauses ($$, $6);
495      context_popLoc (); 
496      lltok_free2 ($3, $4);
497    }
498  | plainNamedDeclBase PushType TLPAREN genericParamList TRPAREN 
499    { setCurrentParams ($4); } 
500    functionClausesPlain
501    { 
502      clearCurrentParams ();
503      $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4));
504      idDecl_addClauses ($$, $7);
505      context_popLoc (); 
506      lltok_free ($3);
507      /*!! lltok_free2 ($3, $5); */
508    }
509 ;
510
511 iterDecl
512  : QITER newId TLPAREN genericParamList TRPAREN 
513    { setCurrentParams ($4); } functionClausesPlain
514    { clearCurrentParams (); } optSemi QENDMACRO
515    { declareCIter ($2, $4); 
516      lltok_free3 ($1, $3, $5); 
517    }
518 ;
519
520 macroDef
521  : LLMACRO macroBody TENDMACRO     { exprNode_checkMacroBody ($2); lltok_free2 ($1, $3); }
522  | LLMACROITER iterBody TENDMACRO  { exprNode_checkIterBody ($2); lltok_free2 ($1, $3); }
523  | LLMACROEND endBody TENDMACRO    { exprNode_checkIterEnd ($2); lltok_free2 ($1, $3);}
524  | LLMACRO TENDMACRO /* no stmt */ { exprChecks_checkEmptyMacroBody (); lltok_free2 ($1, $2); } 
525 ;
526
527 fcnDefHdr
528  : fcnDefHdrAux { clabstract_declareFunction ($1); }
529 ;
530
531 metaStateConstraint
532  : metaStateSpecifier TASSIGN metaStateExpression 
533    { $$ = metaStateConstraint_create ($1, $3); lltok_free ($2); }
534 ;
535
536 metaStateSpecifier
537   : BufConstraintSrefExpr { cscannerHelp_expectingMetaStateName (); } TCOLON metaStateName
538     { cscannerHelp_clearExpectingMetaStateName ();
539       $$ = metaStateSpecifier_create ($1, $4); 
540       lltok_free ($3); 
541     }
542   | CTOK_ELIPSIS { cscannerHelp_expectingMetaStateName (); } TCOLON metaStateName
543     { cscannerHelp_clearExpectingMetaStateName ();
544       $$ = metaStateSpecifier_createElipsis ($4); 
545       lltok_free2 ($1, $3);
546     }
547 ;
548
549 metaStateExpression
550 : metaStateSpecifier { $$ = metaStateExpression_create ($1); }
551 | metaStateSpecifier TBAR metaStateExpression { $$ = metaStateExpression_createMerge ($1, $3); lltok_free ($2); }
552 ;
553
554 metaStateName
555 : METASTATE_NAME
556 ;
557
558 /*drl*/
559
560 constraintSeperator
561 : TCAND
562 | AND_OP
563 ;
564
565 BufConstraintList
566 : BufConstraint constraintSeperator BufConstraintList { $$ = constraintList_add ($3, $1); }
567 | BufConstraint { $$ = constraintList_single ($1); } 
568 ;
569
570 BufConstraint
571 :  BufConstraintExpr relationalOp BufConstraintExpr {
572  $$ = makeConstraintParse3 ($1, $2, $3);
573  DPRINTF(("Done BufConstraint1\n")); }
574 ;
575
576 bufferModifier
577  : QMAXSET
578  | QMAXREAD
579 ;
580
581 relationalOp
582  : GE_OP
583  | LE_OP
584  | EQ_OP
585 ;
586
587 BufConstraintExpr
588  : BufConstraintTerm 
589  | BufUnaryOp TLPAREN BufConstraintExpr TRPAREN {$$ = constraintExpr_parseMakeUnaryOp ($1, $3);  DPRINTF( ("Got BufConstraintExpr UNary Op ") ); }
590  | TLPAREN BufConstraintExpr BufBinaryOp BufConstraintExpr TRPAREN {
591    DPRINTF( ("Got BufConstraintExpr BINary Op ") );
592    $$ = constraintExpr_parseMakeBinaryOp ($2, $3, $4); }
593 ;
594
595 BufConstraintTerm
596  : BufConstraintSrefExpr { $$ =  constraintExpr_makeTermsRef ($1);} 
597  | CCONSTANT { $$ = constraintExpr_makeIntLiteral (exprNode_getLongValue ($1)); }
598 ;
599
600 BufConstraintSrefExpr
601 : id            
602   { /*@-onlytrans@*/ $$ = checkbufferConstraintClausesId ($1); /*@=onlytrans@*/ /*@i523@*/ }
603 | NEW_IDENTIFIER                   
604   { $$ = fixStateClausesId ($1); }
605 | BufConstraintSrefExpr TLSQBR TRSQBR       
606   { $$ = sRef_makeAnyArrayFetch ($1); }
607 | BufConstraintSrefExpr  TLSQBR CCONSTANT TRSQBR 
608   {
609     /*
610     char *t; int c; 
611     t =  cstring_toCharsSafe (exprNode_unparse($3)); 
612     c = atoi( t );
613     */
614     $$ = sRef_makeArrayFetchKnown ($1, exprNode_getLongValue ($3));
615   }
616 | TMULT  BufConstraintSrefExpr               
617   { $$ = sRef_constructPointer ($2); }
618 | TLPAREN BufConstraintSrefExpr TRPAREN     
619   { $$ = $2; }  
620 | BufConstraintSrefExpr TDOT newId          
621   { cstring_markOwned ($3); $$ = sRef_buildField ($1, $3); }
622 | BufConstraintSrefExpr ARROW_OP newId      
623   { cstring_markOwned ($3); $$ = sRef_makeArrow ($1, $3); }
624
625 /*
626 | BufConstraintTerm TLSQBR TRSQBR       { $$ = sRef_makeAnyArrayFetch ($1); }
627  | specClauseListExpr TLSQBR mExpr TRSQBR { $$ = sRef_makeAnyArrayFetch ($1); }
628  | TLPAREN specClauseListExpr TRPAREN     { $$ = $2; }  
629  | specClauseListExpr TDOT newId          { cstring_markOwned ($3);
630                                             $$ = sRef_buildField ($1, $3); }
631 */
632 ;
633
634 /*BufConstraintExpr
635 : BufConstraintTerm 
636 */
637
638 BufUnaryOp
639 : bufferModifier 
640 ;
641
642 BufBinaryOp
643  : TPLUS
644 | TMINUS
645 ;
646 /*
647 ** Function clauses can appear in any order.
648 */
649
650 functionClauses
651  : { $$ = functionClauseList_new (); }
652  | functionClause functionClauses
653    { $$ = functionClauseList_prepend ($2, $1); }
654 ;
655
656 /*
657 ** Inside macro definitions, there are no end macros.
658 */
659
660 functionClausesPlain
661  : 
662    { $$ = functionClauseList_new (); }
663  | functionClausePlain functionClausesPlain
664    { $$ = functionClauseList_prepend ($2, $1); }
665 ;
666
667 functionClause
668  : globalsClause   { $$ = functionClause_createGlobals ($1); }
669  | modifiesClause  { $$ = functionClause_createModifies ($1); }
670  | nomodsClause    { $$ = functionClause_createModifies ($1); }
671  | stateClause     { $$ = functionClause_createState ($1); }  
672  | conditionClause { $$ = $1; }
673  | warnClause      { $$ = functionClause_createWarn ($1); }
674 ;
675
676 functionClausePlain
677  : globalsClausePlain   { $$ = functionClause_createGlobals ($1); }
678  | modifiesClausePlain  { $$ = functionClause_createModifies ($1); }
679  | nomodsClause         { $$ = functionClause_createModifies ($1); }
680  | stateClausePlain     { $$ = functionClause_createState ($1); }  
681  | conditionClausePlain { $$ = $1; }
682  | warnClausePlain      { $$ = functionClause_createWarn ($1); }
683 ;
684
685 globalsClause
686  : globalsClausePlain QENDMACRO { $$ = $1; }
687 ;
688
689 globalsClausePlain
690  : QGLOBALS { setProcessingGlobalsList (); } 
691    globIdList optSemi  
692    { 
693      unsetProcessingGlobals (); 
694      $$ = globalsClause_create ($1, $3); 
695    }
696 ;
697
698 nomodsClause
699  : QNOMODS { $$ = modifiesClause_createNoMods ($1); }
700 ;
701
702 modifiesClause
703  : modifiesClausePlain QENDMACRO { $$ = $1; }
704 ;
705
706 modifiesClausePlain
707  : QMODIFIES 
708    {
709      context_setProtectVars (); enterParamsTemp (); 
710      sRef_setGlobalScopeSafe (); 
711    }
712    locModifies
713    { 
714      exitParamsTemp ();
715      sRef_clearGlobalScopeSafe (); 
716      context_releaseVars ();
717      $$ = modifiesClause_create ($1, $3);
718    }
719 ;
720
721 flagSpec
722  : flagId 
723    { $$ = flagSpec_createPlain ($1); }
724  | flagId TBAR flagSpec
725    { $$ = flagSpec_createOr ($1, $3); }
726 ;
727
728 flagId
729  : NEW_IDENTIFIER
730 ;
731
732 optWarnClause
733  : warnClause
734  | /* empty */ { $$ = warnClause_undefined; }
735 ;
736
737 warnClause
738  : warnClausePlain QENDMACRO { $$ = $1; }
739 ;
740
741 warnClausePlain
742  : QWARN flagSpec cconstantExpr
743    {      
744      llassert (exprNode_knownStringValue ($3));
745      $$ = warnClause_create ($1, $2, cstring_copy (multiVal_forceString (exprNode_getValue ($3)))); 
746      exprNode_free ($3);
747    }
748  | QWARN flagSpec
749    { $$ = warnClause_create ($1, $2, cstring_undefined); }
750 ;
751
752 globIdList
753  : globIdListExpr                     { $$ = globSet_single ($1); }
754  | globIdList TCOMMA globIdListExpr   { $$ = globSet_insert ($1, $3); }
755 ;
756  
757 globIdListExpr 
758  : optGlobQuals globId { $$ = clabstract_createGlobal ($2, $1); }
759 ;
760
761 optGlobQuals
762  : /* empty */           { $$ = qualList_undefined; }
763  | globQual optGlobQuals { $$ = qualList_add ($2, $1); }
764 ;
765
766 globId
767  : id             { $$ = uentry_getSref ($1); }
768  | NEW_IDENTIFIER { $$ = clabstract_unrecognizedGlobal ($1); }
769  | initializer    { $$ = clabstract_checkGlobal ($1); }
770 ;
771
772 globQual
773  : QUNDEF   { $$ = qual_createUndef (); }
774  | QKILLED  { $$ = qual_createKilled (); }
775  | QOUT     { $$ = qual_createOut (); }
776  | QIN      { $$ = qual_createIn (); }
777  | QPARTIAL { $$ = qual_createPartial (); }
778 ;
779
780 stateTag
781  : QDEFINES
782  | QUSES
783  | QALLOCATES
784  | QSETS
785  | QRELEASES
786 ;
787
788 conditionTag
789  : QPRECLAUSE
790  | QPOSTCLAUSE
791 ;
792
793 fcnDefHdrAux
794  : namedDecl                               
795    { 
796      /**!!! deal with fred; fred (int); declarations! **/
797      qtype qint = qtype_create (ctype_int); 
798      $$ = idDecl_fixBase ($1, qint);
799      qtype_free (qint);
800    }
801  | completeTypeSpecifier NotType namedDecl 
802    { $$ = idDecl_fixBase ($3, $1); }
803 ;
804  
805 fcnBody
806  : TLBRACE { checkDoneParams (); context_enterInnerContext (); } 
807    compoundStmtRest 
808    {  
809      exprNode_checkFunctionBody ($3); $$ = $3; 
810      context_exitInner ($3); 
811    }
812  | { context_enterOldStyleScope (); } initializerList 
813    { oldStyleDoneParams (); context_enterInnerContext (); } 
814    compoundStmt 
815    {
816      exprNode_checkFunctionBody ($4); 
817      $$ = $4; /* oldstyle */ 
818      context_exitInner ($4);
819    } 
820 ;
821  
822 fcnDef
823  : fcnDefHdr fcnBody 
824    { 
825      context_setFunctionDefined (exprNode_loc ($2)); 
826      exprNode_checkFunction (context_getHeader (),  $2); 
827      /* DRL 8 8 2000 */
828      
829      context_exitFunction ();
830    }
831 ;
832
833 locModifies
834  : modList optSemi           { $$ = $1; }
835  | optSemi                   { $$ = sRefSet_new (); }
836 ;
837  
838 modListExpr
839  : id                              { $$ = uentry_getSref ($1); checkModifiesId ($1); }
840  | NEW_IDENTIFIER                  { $$ = fixModifiesId ($1); }
841  | TYPE_NAME_OR_ID                 { $$ = fixModifiesId ($1); }
842  | modListExpr TLSQBR TRSQBR       { $$ = modListArrayFetch ($1, sRef_undefined); }
843  | modListExpr TLSQBR mExpr TRSQBR { $$ = modListArrayFetch ($1, $3); }
844  | TMULT modListExpr               { $$ = modListPointer ($2); }
845  | TLPAREN modListExpr TRPAREN     { $$ = $2; }  
846  | modListExpr TDOT newId          { $$ = modListFieldAccess ($1, $3); }
847  | modListExpr ARROW_OP newId      { $$ = modListArrowAccess ($1, $3); }
848 ;
849
850 mExpr
851   : modListExpr     { $$ = $1; }
852   | cconstantExpr   { $$ = sRef_makeUnknown (); /* sRef_makeConstant ($1); ? */ }
853     /* arithmetic? */
854 ;
855
856 modList
857   : modListExpr                { $$ = sRefSet_single ($1); }
858   | modList TCOMMA modListExpr { $$ = sRefSet_insert ($1, $3); }
859 ;
860
861 specClauseListExpr
862  : id                                     
863    { $$ = checkStateClausesId ($1); }
864  | NEW_IDENTIFIER                         
865    { $$ = fixStateClausesId ($1); }
866  | specClauseListExpr TLSQBR TRSQBR       { $$ = sRef_makeAnyArrayFetch ($1); }
867  | specClauseListExpr TLSQBR mExpr TRSQBR { $$ = sRef_makeAnyArrayFetch ($1); }
868  | TMULT specClauseListExpr               { $$ = sRef_constructPointer ($2); }
869  | TLPAREN specClauseListExpr TRPAREN     { $$ = $2; }  
870  | specClauseListExpr TDOT newId          { cstring_markOwned ($3);
871                                             $$ = sRef_buildField ($1, $3); }
872  | specClauseListExpr ARROW_OP newId      { cstring_markOwned ($3);
873                                             $$ = sRef_makeArrow ($1, $3); }
874 ;
875
876 optSpecClauseList
877  : /* empty */ { DPRINTF ((message("Empty optSpecClauseList") )); $$ = sRefSet_undefined }
878  | specClauseList
879  ;
880
881 specClauseList
882   : specClauseListExpr                       
883     { if (sRef_isValid ($1)) { $$ = sRefSet_single ($1); } 
884       else {
885         DPRINTF((message("returning sRefSEt_undefined ")  ));
886         $$ = sRefSet_undefined; } 
887     }
888   | specClauseList TCOMMA specClauseListExpr 
889     { if (sRef_isValid ($3))
890         {
891           $$ = sRefSet_insert ($1, $3); 
892         }
893       else
894         {
895           $$ = $1;
896         }
897     }
898 ;
899
900 primaryExpr
901  : id { $$ = exprNode_fromIdentifier ($1); }
902  | NEW_IDENTIFIER { $$ = exprNode_fromUIO ($1); } 
903  | cconstantExpr
904  | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); }
905  | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (cscannerHelp_coerceId ($1)); } 
906  | QEXTENSION { $$ = exprNode_makeError (); }
907  | TLPAREN { exprChecks_inCompoundStatementExpression (); } 
908    compoundStmt TRPAREN 
909    { exprChecks_leaveCompoundStatementExpression (); $$ = exprNode_compoundStatementExpression ($1, $3); }
910 ;
911  
912 postfixExpr
913  : primaryExpr 
914  | postfixExpr TLSQBR expr TRSQBR { $$ = exprNode_arrayFetch ($1, $3); }
915  | postfixExpr TLPAREN TRPAREN { $$ = exprNode_functionCall ($1, exprNodeList_new ()); }
916  | postfixExpr TLPAREN argumentExprList TRPAREN { $$ = exprNode_functionCall ($1, $3); }
917  | VA_ARG TLPAREN assignExpr TCOMMA typeExpression TRPAREN { $$ = exprNode_vaArg ($1, $3, $5); }
918  | postfixExpr NotType TDOT newId IsType { $$ = exprNode_fieldAccess ($1, $3, $4); }
919  | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $3, $4); }
920  | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); }
921  | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); }
922  | TLPAREN typeExpression TRPAREN TLBRACE typeInitializerList optComma TRBRACE 
923    { /* added for C99 */ $$ = exprNode_undefined; /*@i87 no checking */ }
924 ;
925
926 argumentExprList
927  : assignExpr { $$ = exprNodeList_singleton ($1); }
928  | argumentExprList TCOMMA assignExpr { $$ = exprNodeList_push ($1, $3); }
929 ;
930  
931 unaryExpr
932  : postfixExpr 
933  | INC_OP unaryExpr { $$ = exprNode_preOp ($2, $1); }
934  | DEC_OP unaryExpr { $$ = exprNode_preOp ($2, $1); }
935  | TAMPERSAND castExpr { $$ = exprNode_preOp ($2, $1); }
936  | TMULT castExpr  { $$ = exprNode_preOp ($2, $1); }
937  | TPLUS castExpr  { $$ = exprNode_preOp ($2, $1); }
938  | TMINUS castExpr { $$ = exprNode_preOp ($2, $1); }
939  | TTILDE castExpr { $$ = exprNode_preOp ($2, $1); }
940  | TEXCL castExpr  { $$ = exprNode_preOp ($2, $1); }
941  | processSizeof sizeofExpr endprocessSizeof      { $$ = $2; }
942  | offsetofExpr    { $$ = $1; }
943 ;
944
945 fieldDesignator
946  : fieldDesignator TDOT newId         { $$ = cstringList_add ($1, $3); lltok_free ($2); }
947  | fieldDesignator TLSQBR expr TRSQBR { $$ = $1; lltok_free2 ($2, $4); }
948    /* evans 2002-07-02: offsetof designators can use array indexes */
949  | newId                              { $$ = cstringList_single ($1); }
950 ;
951
952 offsetofExpr
953  : COFFSETOF IsType TLPAREN typeExpression NotType TCOMMA fieldDesignator TRPAREN IsType
954    { $$ = exprNode_offsetof ($4, $7); 
955      lltok_free3 ($1, $3, $6); lltok_free ($8); }
956 ;
957
958 sizeofExpr
959  : IsType { context_setProtectVars (); } 
960    sizeofExprAux { context_sizeofReleaseVars (); $$ = $3; }
961 ;
962
963 processSizeof: {context_enterSizeof()};
964
965
966 endprocessSizeof: {context_leaveSizeof()};
967
968
969 sizeofExprAux 
970  : CSIZEOF TLPAREN typeExpression TRPAREN { $$ = exprNode_sizeofType ($3); lltok_free3 ($1, $2, $4);  } 
971  | CSIZEOF  unaryExpr                      { $$ = exprNode_sizeofExpr ($2); lltok_free ($1); }
972  | CALIGNOF TLPAREN typeExpression TRPAREN { $$ = exprNode_alignofType ($3); lltok_free3 ($1, $2, $4); } 
973  | CALIGNOF unaryExpr                      { $$ = exprNode_alignofExpr ($2); lltok_free ($1); }
974 ;
975
976
977
978 castExpr
979  : unaryExpr 
980  | TLPAREN typeExpression TRPAREN castExpr 
981    { $$ = exprNode_cast ($1, $4, $2); lltok_free ($3); } 
982 ;
983  
984 timesExpr
985  : castExpr 
986  | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); }
987  | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); }
988  | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); }
989 ;
990
991 plusExpr
992  : timesExpr 
993  | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
994  | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
995 ;
996
997 shiftExpr
998  : plusExpr 
999  | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
1000  | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
1001 ;
1002
1003 relationalExpr
1004  : shiftExpr 
1005  | relationalExpr TLT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1006  | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1007  | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1008  | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1009 ;
1010  
1011 equalityExpr 
1012  : relationalExpr 
1013  | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
1014  | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
1015 ;
1016
1017 bitandExpr
1018  : equalityExpr 
1019  | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); }
1020 ;
1021
1022 xorExpr
1023  : bitandExpr 
1024  | xorExpr TCIRC bitandExpr { $$ = exprNode_op ($1, $3, $2); }
1025
1026
1027 bitorExpr
1028  : xorExpr 
1029  | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); }
1030 ;
1031
1032 andExpr 
1033  : bitorExpr 
1034  | andExpr AND_OP 
1035    { exprNode_produceGuards ($1); 
1036      context_enterAndClause ($1); 
1037    } 
1038    bitorExpr 
1039    { 
1040      $$ = exprNode_op ($1, $4, $2); 
1041      context_exitAndClause ($$, $4);
1042    }
1043 ;
1044
1045 orExpr
1046  : andExpr 
1047  | orExpr OR_OP 
1048    { 
1049      exprNode_produceGuards ($1);
1050      context_enterOrClause ($1); 
1051    } 
1052    andExpr 
1053    { 
1054      $$ = exprNode_op ($1, $4, $2); 
1055      context_exitOrClause ($$, $4);
1056    }
1057 ;
1058
1059 conditionalExpr 
1060  : orExpr 
1061  | orExpr TQUEST { exprNode_produceGuards ($1); context_enterTrueClause ($1); } expr TCOLON 
1062    { context_enterFalseClause ($1); } conditionalExpr
1063    { $$ = exprNode_cond ($1, $4, $7); context_exitClause ($1, $4, $7); }
1064 ;
1065
1066 assignExpr
1067  : conditionalExpr 
1068  | unaryExpr TASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1069  | unaryExpr MUL_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1070  | unaryExpr DIV_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1071  | unaryExpr MOD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1072  | unaryExpr ADD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1073  | unaryExpr SUB_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1074  | unaryExpr LEFT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1075  | unaryExpr RIGHT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1076  | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1077  | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1078  | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1079 ;
1080
1081 expr
1082  : assignExpr 
1083  | expr TCOMMA assignExpr { $$ = exprNode_comma ($1, $3); } 
1084 ;
1085
1086 optExpr
1087  : /* empty */ { $$ = exprNode_undefined; }
1088  | expr 
1089  ;
1090
1091 constantExpr
1092  : conditionalExpr 
1093 ;
1094
1095 /* instance_orTypeDecl_and_possible_initialization */
1096
1097 initializer
1098  : instanceDecl { $$ = $1; }
1099  | VA_DCL       { doVaDcl (); $$ = exprNode_makeError (); } 
1100  | typeDecl     { $$ = exprNode_makeError (); }
1101 ;
1102
1103 instanceDecl
1104  : completeTypeSpecifier IsType TSEMI 
1105    { $$ = exprNode_makeError (); } 
1106      /*
1107      ** This causes r/r conflicts with function definitions.
1108      ** Instead we need to snarf one first. (gack)
1109      **
1110      ** | completeTypeSpecifier { setProcessingVars ($1); } 
1111      ** NotType 
1112      ** namedInitializerList IsType TSEMI 
1113      ** { unsetProcessingVars (); }
1114      **;
1115      **
1116      ** the solution is pretty ugly:
1117      */
1118  | completeTypeSpecifier NotType namedDecl NotType 
1119    {
1120      setProcessingVars ($1); 
1121      processNamedDecl ($3); 
1122    }
1123    IsType optDeclarators TSEMI IsType 
1124    { 
1125      unsetProcessingVars (); 
1126      $$ = exprNode_makeEmptyInitialization ($3); 
1127      DPRINTF (("Empty initialization: %s", exprNode_unparse ($$)));
1128    }
1129  | completeTypeSpecifier NotType namedDecl NotType TASSIGN 
1130    { setProcessingVars ($1); processNamedDecl ($3); }
1131    IsType init optDeclarators TSEMI IsType 
1132    { $$ = exprNode_concat ($9, exprNode_makeInitialization ($3, $8)); 
1133      unsetProcessingVars ();
1134    }
1135 ;
1136
1137 namedInitializerType
1138  : namedInitializer { $$ = $1; } 
1139  | TYPE_NAME { $$ = exprNode_fromIdentifier (usymtab_getTypeEntry (ctype_typeId ($1))); }
1140 ;
1141
1142 namedInitializer
1143  : namedDecl NotType 
1144    { 
1145      processNamedDecl ($1); 
1146      $$ = exprNode_makeEmptyInitialization ($1);
1147    }
1148  | namedDecl NotType TASSIGN { processNamedDecl ($1); } IsType init
1149    { $$ = exprNode_makeInitialization ($1, $6); }
1150 ;
1151
1152 typeDecl
1153  : CTYPEDEF completeTypeSpecifier { setProcessingTypedef ($2); } 
1154    NotType namedInitializerTypeList IsType optWarnClause TSEMI 
1155    { clabstract_declareType ($5, $7); }
1156  | CTYPEDEF completeTypeSpecifier IsType TSEMI { /* in the ANSI grammar, semantics unclear */ }
1157  | CTYPEDEF namedInitializerList IsType TSEMI { /* in the ANSI grammar, semantics unclear */ } 
1158 ;
1159
1160 IsType
1161  : { cscannerHelp_setExpectingTypeName (); }
1162 ;
1163
1164 PushType
1165  : { cscannerHelp_setExpectingTypeName (); context_pushLoc (); }
1166 ;
1167
1168 namedInitializerList
1169  :  namedInitializerListAux IsType { $$ = $1; }
1170 ;
1171
1172 namedInitializerListAux
1173  : namedInitializer { $$ = exprNodeList_singleton ($1); }
1174  | namedInitializerList TCOMMA NotType namedInitializer { $$ = exprNodeList_push ($1, $4); }
1175 ;
1176
1177 namedInitializerTypeList
1178  :  namedInitializerTypeListAux IsType { $$ = $1; }
1179 ;
1180
1181 namedInitializerTypeListAux
1182  : namedInitializerType { $$ = exprNodeList_singleton ($1); }
1183  | namedInitializerTypeList TCOMMA NotType namedInitializerType { $$ = exprNodeList_push ($1, $4); }
1184 ;
1185
1186 optDeclarators
1187  : /* empty */      { $$ = exprNode_makeError (); }
1188  | optDeclarators TCOMMA NotType namedInitializer { $$ = exprNode_concat ($1, $4); }
1189 ;
1190
1191 init
1192  : assignExpr                      
1193  | TLBRACE initList TRBRACE        { $$ = exprNode_makeInitBlock ($1, $2); lltok_free ($3); }
1194  | TLBRACE initList TCOMMA TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); lltok_free2 ($3, $4); }
1195  | designation init                { $$ = exprNode_undefined; }
1196 ;
1197
1198 /*
1199 ** Splint parses these (added in ISO C99), but no checking yet...
1200 */
1201
1202 designation
1203  : designatorList TASSIGN          { $$ = $1; }
1204  | newId TCOLON                    { $$ = exprNode_undefined; 
1205                                      /* gcc extension, obsolete since 2.5 */ }
1206 ;
1207
1208 designatorList
1209  : designator                      { $$ = exprNode_undefined; } 
1210  | designatorList designator       { $$ = exprNode_undefined; }
1211 ;
1212
1213 designator
1214  : TLSQBR constantExpr TRSQBR      { $$ = exprNode_undefined; }
1215  | TDOT newId                      { $$ = exprNode_undefined; }
1216 ;
1217
1218 initList
1219  : init 
1220    { $$ = exprNodeList_singleton ($1); }
1221  | initList TCOMMA init 
1222    { $$ = exprNodeList_push ($1, $3); }
1223 ;
1224
1225 /*
1226 ** need to do the storage class global hack so tags are
1227 ** declared with the right storage class.
1228 */
1229
1230 storageSpecifier
1231  : QEXTERN   { setStorageClass (SCEXTERN); $$ = qual_createExtern (); }
1232  | QINLINE   { $$ = qual_createInline (); }
1233  | QSTATIC   { setStorageClass (SCSTATIC); $$ = qual_createStatic (); }
1234  | QAUTO     { $$ = qual_createAuto (); }
1235  | QREGISTER { $$ = qual_createRegister (); }
1236 ;
1237
1238 stateClause
1239  : stateClausePlain QENDMACRO { $$ = $1; }
1240 ;
1241
1242 stateClausePlain
1243  : stateTag NotType
1244    {
1245      context_setProtectVars (); 
1246      enterParamsTemp (); 
1247      sRef_setGlobalScopeSafe (); 
1248    }
1249    specClauseList optSemi IsType
1250    { 
1251      exitParamsTemp ();
1252      sRef_clearGlobalScopeSafe (); 
1253      context_releaseVars ();
1254      $$ = stateClause_createPlain ($1, $4);
1255    }
1256 ;
1257
1258 conditionClause
1259  : conditionClausePlain QENDMACRO { $$ = $1; }
1260 ;
1261
1262 startConditionClause
1263 : conditionTag NotType { $$ = $1; context_enterFunctionHeader (); } 
1264 ;
1265
1266 conditionClausePlain
1267  : startConditionClause stateQualifier
1268    {
1269      context_exitFunctionHeader ();
1270      context_setProtectVars (); 
1271      enterParamsTemp (); 
1272      sRef_setGlobalScopeSafe (); 
1273    }
1274    optSpecClauseList optSemi IsType
1275    { 
1276      exitParamsTemp ();
1277      sRef_clearGlobalScopeSafe (); 
1278      context_releaseVars ();
1279      $$ = functionClause_createState (stateClause_create ($1, $2, $4));
1280    }
1281  | startConditionClause
1282    {
1283      context_setProtectVars (); 
1284      enterParamsTemp (); 
1285      sRef_setGlobalScopeSafe (); 
1286    } 
1287    functionConstraint optSemi IsType
1288    {
1289      context_exitFunctionHeader ();
1290      exitParamsTemp ();
1291      sRef_clearGlobalScopeSafe (); 
1292      context_releaseVars ();
1293      DPRINTF (("done optGlobBufConstraintsAux\n"));
1294
1295      if (lltok_isEnsures ($1)) 
1296        {
1297          $$ = functionClause_createEnsures ($3);
1298        }
1299      else if (lltok_isRequires ($1))
1300        {
1301          $$ = functionClause_createRequires ($3);
1302        }
1303      else
1304        {
1305          BADBRANCH;
1306        }
1307
1308      DPRINTF (("FunctionclauseS: %s", functionClause_unparse ($$)));
1309    }
1310 ;
1311
1312 functionConstraint
1313  : BufConstraintList   { $$ = functionConstraint_createBufferConstraint ($1); }
1314  | metaStateConstraint { $$ = functionConstraint_createMetaStateConstraint ($1); DPRINTF (("Made constraint: %s", functionConstraint_unparse ($$))); } 
1315 ;
1316  
1317 exitsQualifier
1318  : QEXITS        { $$ = qual_createExits (); }
1319  | QMAYEXIT      { $$ = qual_createMayExit (); }
1320  | QTRUEEXIT     { $$ = qual_createTrueExit (); }
1321  | QFALSEEXIT    { $$ = qual_createFalseExit (); }
1322  | QNEVEREXIT    { $$ = qual_createNeverExit (); }
1323 ;
1324
1325 checkQualifier
1326  : QCHECKED        { $$ = qual_createChecked (); }
1327  | QCHECKMOD       { $$ = qual_createCheckMod (); }
1328  | QUNCHECKED      { $$ = qual_createUnchecked (); }
1329  | QCHECKEDSTRICT  { $$ = qual_createCheckedStrict (); }
1330 ;
1331
1332 stateQualifier
1333  : QOWNED        { $$ = qual_createOwned (); }
1334  | QDEPENDENT    { $$ = qual_createDependent (); }
1335  | QYIELD        { $$ = qual_createYield (); }
1336  | QTEMP         { $$ = qual_createTemp (); }
1337  | QONLY         { $$ = qual_createOnly (); }
1338  | QKEEP         { $$ = qual_createKeep (); }
1339  | QKEPT         { $$ = qual_createKept (); }
1340  | QSHARED       { $$ = qual_createShared (); }
1341  | QUNIQUE       { $$ = qual_createUnique (); }
1342  | QNULL         { $$ = qual_createNull (); }
1343  | QISNULL       { $$ = qual_createIsNull (); }
1344  | QRELNULL      { $$ = qual_createRelNull (); }
1345  | QNOTNULL      { $$ = qual_createNotNull (); }
1346  | QEXPOSED      { $$ = qual_createExposed (); }
1347  | QOBSERVER     { $$ = qual_createObserver (); }
1348  | QNULLTERMINATED { $$ = qual_createNullTerminated (); } 
1349  | CANNOTATION   { $$ = qual_createMetaState ($1); }
1350 ;
1351
1352 paramQualifier
1353  : QRETURNED     { $$ = qual_createReturned (); }
1354  | QSEF          { $$ = qual_createSef (); }
1355 ;
1356
1357 visibilityQualifier
1358  : QUNUSED       { $$ = qual_createUnused (); }
1359  | QEXTERNAL     { $$ = qual_createExternal (); }
1360 ;
1361
1362 returnQualifier
1363  : QTRUENULL     { $$ = qual_createTrueNull (); }
1364  | QFALSENULL    { $$ = qual_createFalseNull (); }
1365 ;
1366
1367 typedefQualifier
1368  : QABSTRACT     { $$ = qual_createAbstract (); }
1369  | QNUMABSTRACT  { $$ = qual_createNumAbstract (); }
1370  | QCONCRETE     { $$ = qual_createConcrete (); }
1371  | QMUTABLE      { $$ = qual_createMutable (); }
1372  | QIMMUTABLE    { $$ = qual_createImmutable (); }
1373 ;
1374
1375 refcountQualifier
1376  : QREFCOUNTED   { $$ = qual_createRefCounted (); }
1377  | QREFS         { $$ = qual_createRefs (); }
1378  | QKILLREF      { $$ = qual_createKillRef (); }
1379  | QRELDEF       { $$ = qual_createRelDef (); }
1380  | QNEWREF       { $$ = qual_createNewRef (); }
1381  | QTEMPREF      { $$ = qual_createTempRef (); }
1382 ;
1383
1384 typeModifier
1385  : QSHORT            { $$ = qual_createShort (); }
1386  | QLONG             { $$ = qual_createLong (); }
1387  | QSIGNED           { $$ = qual_createSigned (); }
1388  | QUNSIGNED         { $$ = qual_createUnsigned (); }
1389 ;
1390
1391 definedQualifier
1392  : QOUT              { $$ = qual_createOut (); }
1393  | QIN               { $$ = qual_createIn (); }
1394  | QPARTIAL          { $$ = qual_createPartial (); }
1395  | QSPECIAL          { $$ = qual_createSpecial (); }
1396 ;
1397
1398 typeQualifier
1399  : QCONST IsType       { $$ = qual_createConst (); }
1400  | QVOLATILE IsType    { $$ = qual_createVolatile (); }
1401  | QRESTRICT IsType    { $$ = qual_createRestrict (); }
1402  | definedQualifier IsType { $$ = $1; } 
1403  | stateQualifier IsType { $$ = $1; } 
1404  | exitsQualifier IsType { $$ = $1; }
1405  | paramQualifier IsType { $$ = $1; }
1406  | checkQualifier IsType { $$ = $1; }
1407  | returnQualifier IsType { $$ = $1; }
1408  | visibilityQualifier IsType { $$ = $1; }
1409  | typedefQualifier IsType { $$ = $1; }
1410  | refcountQualifier IsType { $$ = $1; }
1411 ;
1412
1413 /*
1414 ** This is copied into the mtgrammar!
1415 */
1416
1417 typeSpecifier
1418  : CGCHAR NotType 
1419  | CINT NotType 
1420  | CBOOL NotType
1421  | CGFLOAT NotType
1422  | CDOUBLE NotType
1423  | CVOID NotType 
1424  | QANYTYPE NotType              { $$ = ctype_makeAnytype (); }
1425  | QINTEGRALTYPE NotType         { $$ = ctype_anyintegral; }
1426  | QUNSIGNEDINTEGRALTYPE NotType { $$ = ctype_unsignedintegral; }
1427  | QSIGNEDINTEGRALTYPE NotType   { $$ = ctype_signedintegral; }
1428  | typeName NotType     
1429  | suSpc NotType 
1430  | enumSpc NotType
1431  | typeModifier NotType           { $$ = ctype_fromQual ($1); }
1432 ;
1433
1434 completeType
1435  : IsType completeTypeSpecifier IsType
1436    { $$ = qtype_resolve ($2); }
1437 ;
1438
1439 completeTypeSpecifier
1440  : completeTypeSpecifierAux { $$ = $1; }
1441  | completeTypeSpecifierAux QALT altType QENDMACRO  
1442    { $$ = qtype_mergeAlt ($1, $3); }
1443 ;
1444
1445 altType
1446  : typeExpression
1447  | typeExpression TCOMMA altType
1448    { $$ = qtype_mergeAlt ($1, $3); } 
1449 ;
1450
1451 completeTypeSpecifierAux
1452  : storageSpecifier optCompleteType        { $$ = qtype_addQual ($2, $1); }
1453  | typeQualifier optCompleteType           { $$ = qtype_addQual ($2, $1); } 
1454  | typeSpecifier optCompleteType           { $$ = qtype_combine ($2, $1); }
1455 ;
1456
1457 optCompleteType
1458  : /* empty */                             { $$ = qtype_unknown (); }
1459  | completeTypeSpecifier                   { $$ = $1; }
1460 ;
1461
1462 optStructInvariant
1463 : /* empty */ { $$ = constraintList_undefined; }
1464 /*  drl commenting before a CVS commit 
1465    |  QINVARIANT BufConstraintList QENDMACRO { $$ = $2 }
1466 */
1467 ;
1468
1469 suSpc
1470  : NotType CSTRUCT newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1471    CreateStructInnerScope 
1472    structDeclList  DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); }
1473    TRBRACE 
1474    optStructInvariant 
1475    { ctype ct; ct = declareStruct ($3, $8); /* context_setGlobalStructInfo(ct, $12); */ $$ = ct; } 
1476  | NotType CUNION  newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1477    CreateStructInnerScope 
1478    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } 
1479    TRBRACE
1480    { $$ = declareUnion ($3, $8); } 
1481  | NotType CSTRUCT newId IsType TLBRACE TRBRACE 
1482    { $$ = declareStruct ($3, uentryList_new ()); }
1483  | NotType CUNION  newId IsType TLBRACE TRBRACE 
1484    { $$ = declareUnion ($3, uentryList_new ()); }
1485  | NotType CSTRUCT IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1486    CreateStructInnerScope 
1487    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); }
1488    TRBRACE 
1489    { $$ = declareUnnamedStruct ($7); }
1490  | NotType CUNION IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1491    CreateStructInnerScope structDeclList DeleteStructInnerScope 
1492    { sRef_clearGlobalScopeSafe (); }
1493    TRBRACE 
1494    { $$ = declareUnnamedUnion ($7); } 
1495  | NotType CSTRUCT IsType TLBRACE TRBRACE
1496    { $$ = ctype_createUnnamedStruct (uentryList_new ()); }
1497  | NotType CUNION IsType TLBRACE TRBRACE 
1498    { $$ = ctype_createUnnamedUnion (uentryList_new ()); } 
1499  | NotType CSTRUCT newId NotType { $$ = handleStruct ($3); } 
1500  | NotType CUNION newId NotType { $$ = handleUnion ($3); }
1501 ;
1502
1503 NotType
1504 : { cscannerHelp_clearExpectingTypeName (); }
1505 ;
1506
1507 structDeclList
1508  : structDecl 
1509  | macroDef { $$ = uentryList_undefined; /* bogus! */ }
1510  | structDeclList structDecl { $$ = uentryList_mergeFields ($1, $2); }
1511 ;
1512
1513 structDecl
1514  : completeTypeSpecifier NotType structNamedDeclList IsType TSEMI 
1515    { $$ = fixUentryList ($3, $1); }
1516  | completeTypeSpecifier IsType TSEMI 
1517    { $$ = fixUnnamedDecl ($1); }
1518 ;
1519
1520 structNamedDeclList 
1521  : structNamedDecl NotType                            
1522    { $$ = idDeclList_singleton ($1); }
1523  | structNamedDeclList TCOMMA structNamedDecl NotType
1524    { $$ = idDeclList_add ($1, $3); }
1525 ;
1526
1527 structNamedDecl  /* hack to get around namespace problems */ 
1528  : namedDecl                            { $$ = $1; }
1529  | TCOLON IsType constantExpr           { $$ = idDecl_undefined; }
1530  | namedDecl TCOLON IsType constantExpr { $$ = $1; }
1531    /* Need the IsType in case there is a cast in the constant expression. */
1532 ;
1533
1534 enumSpc
1535  : NotType CENUM TLBRACE enumeratorList TRBRACE IsType 
1536    { $$ = declareUnnamedEnum ($4); }
1537  | NotType CENUM newId TLBRACE { context_pushLoc (); } enumeratorList TRBRACE IsType
1538    { context_popLoc (); $$ = declareEnum ($3, $6); }
1539  | NotType CENUM newId IsType { $$ = handleEnum ($3); }
1540 ;
1541
1542 enumeratorList
1543  : enumerator 
1544    { $$ = enumNameList_single ($1); }
1545  | enumeratorList TCOMMA enumerator 
1546    { $$ = enumNameList_push ($1, $3); }
1547  | enumeratorList TCOMMA
1548  ;
1549
1550 enumerator
1551  : newId 
1552    { uentry ue = uentry_makeEnumConstant ($1, ctype_unknown);
1553      usymtab_supGlobalEntry (ue);
1554      $$ = $1;
1555    }
1556  | newId TASSIGN IsType constantExpr 
1557    { uentry ue = uentry_makeEnumInitializedConstant ($1, ctype_unknown, $4);
1558      usymtab_supGlobalEntry (ue);
1559      $$ = $1; 
1560    }
1561 ;
1562
1563 optNamedDecl
1564  : namedDeclBase
1565  | optAbstractDeclBase   { $$ = idDecl_create (cstring_undefined, qtype_create ($1)); }
1566  | pointers TYPE_NAME    
1567    { 
1568      qtype qt = qtype_unknown ();
1569      qtype_adjustPointers ($1, qt);
1570      $$ = idDecl_create (cstring_copy (cscannerHelp_observeLastIdentifier ()), qt);
1571    }
1572  | pointers optNamedDecl 
1573    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
1574 ;
1575
1576 namedDecl
1577  : namedDeclBase
1578  | pointers namedDeclBase 
1579    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
1580 ;
1581
1582 genericParamList
1583  : paramTypeList       { $$ = handleParamTypeList ($1); }
1584  | NotType paramIdList { $$ = handleParamIdList ($2); }  
1585 ;
1586
1587 innerMods
1588  : QCONST    { $$ = qual_createConst (); }
1589  | QRESTRICT { $$ = qual_createRestrict (); }
1590  | QVOLATILE { $$ = qual_createVolatile (); }
1591 ;
1592
1593 innerModsList
1594  : innerMods { $$ = qualList_single ($1); }
1595  | innerModsList innerMods { $$ = qualList_add ($1, $2); }
1596 ;
1597
1598 pointers
1599  : TMULT { $$ = pointers_create ($1); }
1600  | TMULT innerModsList { $$ = pointers_createMods ($1, $2); }
1601  | TMULT pointers { $$ = pointers_extend (pointers_create ($1), $2); } 
1602  | TMULT innerModsList pointers { $$ = pointers_extend (pointers_createMods ($1, $2), $3); }
1603 ;
1604
1605 paramIdList
1606  : idList 
1607  | idList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); }
1608 ;
1609
1610 idList
1611  : newId { $$ = uentryList_single (uentry_makeVariableLoc ($1, ctype_int)); }
1612  | idList TCOMMA newId { $$ = uentryList_add ($1, uentry_makeVariableLoc ($3, ctype_int)); }
1613 ;
1614
1615 paramTypeList
1616  : CTOK_ELIPSIS { $$ = uentryList_single (uentry_makeElipsisMarker ()); }
1617  | paramList 
1618  | paramList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); }
1619 ;
1620
1621 paramList
1622  : { storeLoc (); } paramDecl { $$ = uentryList_single ($2); }
1623  | paramList TCOMMA { storeLoc (); } paramDecl 
1624    { $$ = uentryList_add ($1, $4); }
1625 ;
1626
1627 paramDecl
1628  : IsType completeTypeSpecifier optNamedDecl IsType
1629    { 
1630      if (isFlipOldStyle ()) 
1631        { 
1632          llparseerror (cstring_makeLiteral ("Inconsistent function parameter syntax (mixing old and new style declaration)")); 
1633        }
1634      else 
1635        { 
1636          setNewStyle (); 
1637        }
1638      $$ = makeCurrentParam (idDecl_fixParamBase ($3, $2)); 
1639    }
1640  | newId /* its an old-style declaration */
1641    { 
1642      idDecl tparam = idDecl_create ($1, qtype_unknown ());
1643
1644      if (isNewStyle ()) 
1645        {
1646          llparseerror (message ("Inconsistent function parameter syntax: %q",
1647                                 idDecl_unparse (tparam))); 
1648        }
1649
1650      setFlipOldStyle ();
1651      $$ = makeCurrentParam (tparam);
1652      idDecl_free (tparam);
1653    } 
1654 ;
1655
1656 typeExpression
1657  : completeType
1658  | completeType abstractDecl  { $$ = qtype_newBase ($1, $2); }
1659 ;
1660
1661 abstractDecl
1662  : pointers { $$ = ctype_adjustPointers ($1, ctype_unknown); }
1663  | abstractDeclBase
1664  | pointers abstractDeclBase { $$ = ctype_adjustPointers ($1, $2); }
1665 ;
1666
1667 optAbstractDeclBase
1668  : /* empty */ { $$ = ctype_unknown; }
1669  | abstractDeclBase 
1670  ;
1671
1672 abstractDeclBase
1673  : IsType TLPAREN NotType abstractDecl TRPAREN 
1674    { $$ = ctype_expectFunction ($4); }
1675  | TLSQBR TRSQBR { $$ = ctype_makeArray (ctype_unknown); }
1676  | TLSQBR constantExpr TRSQBR 
1677    { $$ = ctype_makeFixedArray (ctype_unknown, exprNode_getLongValue ($2)); }
1678  | abstractDeclBase TLSQBR TRSQBR { $$ = ctype_makeInnerArray ($1); }
1679  | abstractDeclBase TLSQBR constantExpr TRSQBR 
1680    { $$ = ctype_makeInnerFixedArray ($1, exprNode_getLongValue ($3)); }
1681  | IsType TLPAREN TRPAREN 
1682    { $$ = ctype_makeFunction (ctype_unknown, uentryList_makeMissingParams ()); }
1683  | IsType TLPAREN paramTypeList TRPAREN 
1684    { $$ = ctype_makeParamsFunction (ctype_unknown, $3); }
1685  | abstractDeclBase IsType TLPAREN TRPAREN 
1686    { $$ = ctype_makeFunction ($1, uentryList_makeMissingParams ()); }  
1687  | abstractDeclBase IsType TLPAREN paramTypeList TRPAREN 
1688    { $$ = ctype_makeParamsFunction ($1, $4); }  
1689 ;
1690
1691 /* statement */
1692
1693 stmt
1694  : labeledStmt 
1695  | caseStmt 
1696  | defaultStmt
1697  | compoundStmt 
1698  | expressionStmt
1699  | selectionStmt 
1700  | iterationStmt 
1701  | iterStmt
1702  | jumpStmt 
1703 ;
1704
1705
1706 iterBody
1707  : iterDefStmtList { $$ = $1; }
1708 ;
1709
1710 endBody
1711  : iterBody
1712 ;
1713
1714 iterDefStmtList
1715  : iterDefStmt                 
1716  | iterDefStmtList iterDefStmt 
1717    { $$ = exprNode_concat ($1, $2); }
1718 ;
1719
1720 iterDefIterationStmt
1721  : iterWhilePred iterDefStmtList         
1722    { $$ = exprNode_while ($1, $2); }
1723  | doHeader stmtErr WHILE TLPAREN expr TRPAREN TSEMI 
1724    { $$ = exprNode_doWhile ($2, $5); }
1725  | doHeader stmtErr WHILE TLPAREN expr TRPAREN
1726    { $$ = exprNode_doWhile ($2, $5); }
1727  | forPred iterDefStmt
1728    { $$ = exprNode_for ($1, $2); } 
1729 ;
1730
1731 forPred
1732  : CFOR TLPAREN optExpr TSEMI optExpr TSEMI 
1733    { context_setProtectVars (); } optExpr { context_sizeofReleaseVars (); }
1734    TRPAREN 
1735    { $$ = exprNode_forPred ($3, $5, $8); 
1736      context_enterForClause ($5); }
1737 ;
1738
1739 partialIterStmt
1740  : ITER_NAME CreateInnerScope TLPAREN 
1741    { setProcessingIterVars ($1); } 
1742    iterArgList TRPAREN 
1743    { $$ = exprNode_iterStart ($1, $5); }
1744  | ITER_ENDNAME { $$ = exprNode_createId ($1); }
1745 ;
1746
1747 iterDefStmt
1748  : labeledStmt 
1749  | caseStmt 
1750  | defaultStmt
1751  | openScope initializerList { $$ = $1; DPRINTF (("def stmt: %s", exprNode_unparse ($$))); }
1752  | openScope
1753  | closeScope
1754  | expressionStmt
1755  | iterSelectionStmt 
1756  | iterDefIterationStmt 
1757  | partialIterStmt
1758  | jumpStmt 
1759  | TLPAREN iterDefStmt TRPAREN { $$ = $2; }
1760  | error { $$ = exprNode_makeError (); }
1761 ;
1762
1763 iterSelectionStmt
1764  : ifPred { exprNode_checkIfPred ($1); } iterDefStmt 
1765    { /* don't: context_exitTrueClause ($1, $2); */
1766      $$ = exprNode_if ($1, $3); 
1767    }
1768 ;
1769
1770 openScope
1771  : CreateInnerScope TLBRACE { $$ = exprNode_createTok ($2); }
1772 ;
1773
1774 closeScope
1775  : DeleteInnerScopeSafe TRBRACE { $$ = exprNode_createTok ($2); }
1776 ;
1777
1778 macroBody
1779  : stmtErr    
1780  | stmtListErr
1781 ;
1782  
1783 stmtErr
1784  : labeledStmt
1785  | caseStmt 
1786  | defaultStmt 
1787  | compoundStmtErr
1788  | expressionStmtErr
1789  | selectionStmt 
1790  | iterStmt
1791  | iterationStmtErr
1792  | TLPAREN stmtErr TRPAREN { $$ = exprNode_addParens ($1, $2); }
1793  | jumpStmt 
1794  | error { $$ = exprNode_makeError (); }
1795 ;
1796
1797 labeledStmt
1798  : newId TCOLON      { $$ = exprNode_labelMarker ($1); }
1799  | QNOTREACHED stmt  { $$ = exprNode_notReached ($2); }
1800 ;
1801
1802 /*
1803 ** We allow more than one QFALLTHROUGH token to support mixed lint/splint markers.
1804 */
1805
1806 optExtraFallThroughs
1807  : /* empty */ { ; }
1808  | QFALLTHROUGH optExtraFallThroughs { ; }
1809 ;
1810
1811 /* Note that we can semantically check that the object to the case is
1812  indeed constant. In this case, we may not want to go through this effort */
1813
1814 caseStmt
1815  : CASE constantExpr { context_enterCaseClause ($2); } 
1816    TCOLON            { $$ = exprNode_caseMarker ($2, FALSE); }
1817  | QFALLTHROUGH optExtraFallThroughs CASE constantExpr { context_enterCaseClause ($4); } 
1818    TCOLON            { $$ = exprNode_caseMarker ($4, TRUE); }
1819 ;
1820
1821 defaultStmt
1822  : DEFAULT { context_enterCaseClause (exprNode_undefined); } 
1823    TCOLON { $$ = exprNode_defaultMarker ($1, FALSE); }
1824  | QFALLTHROUGH optExtraFallThroughs DEFAULT { context_enterCaseClause (exprNode_undefined); } 
1825    TCOLON { $$ = exprNode_defaultMarker ($3, TRUE); }
1826 ;
1827
1828 compoundStmt
1829  : TLPAREN compoundStmt TRPAREN { $$ = $2; }
1830  | CreateInnerScope compoundStmtAux 
1831    { $$ = $2; context_exitInner ($2); }
1832 ;
1833
1834 compoundStmtErr
1835  : CreateInnerScope compoundStmtAuxErr DeleteInnerScope { $$ = $2; }
1836 ;
1837
1838 CreateInnerScope
1839  : { context_enterInnerContext (); }
1840 ;
1841
1842 DeleteInnerScope
1843  : { context_exitInnerPlain (); }
1844 ;
1845
1846 CreateStructInnerScope
1847  : { context_enterStructInnerContext (); }
1848 ;
1849
1850 DeleteStructInnerScope
1851  : { context_exitStructInnerContext (); }
1852 ;
1853
1854 DeleteInnerScopeSafe
1855  : { context_exitInnerSafe (); }
1856 ;
1857
1858 compoundStmtRest
1859  : TRBRACE { $$ = exprNode_createTok ($1); }
1860  | QNOTREACHED TRBRACE { $$ = exprNode_notReached (exprNode_createTok ($2)); }
1861  | stmtList TRBRACE { $$ = exprNode_updateLocation ($1, lltok_getLoc ($2)); }
1862  | stmtList QNOTREACHED TRBRACE 
1863    { $$ = exprNode_notReached (exprNode_updateLocation ($1, lltok_getLoc ($3))); }
1864  | initializerList TRBRACE { $$ = exprNode_updateLocation ($1, lltok_getLoc ($2)); }
1865  | initializerList QNOTREACHED TRBRACE 
1866    { $$ = exprNode_notReached (exprNode_updateLocation ($1, lltok_getLoc ($3))); }
1867  | initializerList stmtList TRBRACE
1868    { $$ = exprNode_updateLocation (exprNode_concat ($1, $2), lltok_getLoc ($3)); }
1869  | initializerList stmtList QNOTREACHED TRBRACE
1870    { $$ = exprNode_notReached (exprNode_updateLocation (exprNode_concat ($1, $2), 
1871                                                         lltok_getLoc ($3))); 
1872    }
1873 ;
1874
1875 compoundStmtAux
1876  : TLBRACE compoundStmtRest 
1877    { $$ = exprNode_makeBlock ($2); }
1878 ;
1879
1880 compoundStmtAuxErr
1881  : TLBRACE TRBRACE 
1882    { $$ = exprNode_createTok ($2); }
1883  | TLBRACE stmtListErr TRBRACE 
1884    { $$ = exprNode_updateLocation ($2, lltok_getLoc ($3)); }
1885  | TLBRACE initializerList TRBRACE 
1886    { $$ = exprNode_updateLocation ($2, lltok_getLoc ($3)); }
1887  | TLBRACE initializerList stmtList TRBRACE 
1888    { $$ = exprNode_updateLocation (exprNode_concat ($2, $3), lltok_getLoc ($4)); }
1889 ;
1890
1891 stmtListErr
1892  : stmtErr 
1893  | stmtListErr stmtErr { $$ = exprNode_concat ($1, $2); }
1894 ;
1895
1896 initializerList
1897  : initializer { $$ = $1; }
1898  | initializerList initializer { $$ = exprNode_concat ($1, $2); }
1899 ;
1900
1901 typeInitializerList
1902  : typeInitializer { $$ = $1; }
1903  | typeInitializerList TCOMMA typeInitializer { $$ = exprNode_concat ($1, $3); }
1904 ;
1905
1906 typeInitializer
1907  : assignExpr { $$ = $1; }
1908  | TLBRACE typeInitializerList optComma TRBRACE { $$ = $2; } 
1909 ;
1910
1911 stmtList
1912  : stmt { $$ = $1; }
1913  | stmtList stmt { $$ = exprNode_concat ($1, $2); }
1914 ;
1915
1916 expressionStmt 
1917  : TSEMI { $$ = exprNode_createTok ($1); }
1918  | expr TSEMI { $$ = exprNode_statement ($1, $2); }
1919 ;
1920
1921 expressionStmtErr
1922  : TSEMI { $$ = exprNode_createTok ($1); }
1923  | expr TSEMI { $$ = exprNode_statement ($1, $2); }
1924  | expr { $$ = exprNode_checkExpr ($1); } 
1925 ;
1926
1927 ifPred
1928  : CIF TLPAREN expr TRPAREN 
1929    { 
1930      exprNode_produceGuards ($3); context_enterTrueClause ($3); 
1931      exprNode_checkIfPred ($3);
1932      $$ = $3;
1933    }
1934
1935  /*
1936  ** not ANSI: | CIF TLPAREN compoundStmt TRPAREN 
1937  **             { $$ = $3; context_enterTrueClause (); } 
1938  */
1939 ;
1940
1941 selectionStmt
1942  : ifPred stmt 
1943    { 
1944      context_exitTrueClause ($1, $2);
1945      $$ = exprNode_if ($1, $2); 
1946    }
1947  | ifPred stmt CELSE  { context_enterFalseClause ($1); } stmt 
1948    {
1949      context_exitClause ($1, $2, $5);
1950      $$ = exprNode_ifelse ($1, $2, $5); 
1951    }
1952  | SWITCH TLPAREN expr { context_enterSwitch ($3); } 
1953    TRPAREN stmt        { $$ = exprNode_switch ($3, $6); }
1954 ;
1955  
1956 whilePred
1957  : WHILE TLPAREN expr TRPAREN 
1958    { $$ = exprNode_whilePred ($3); context_enterWhileClause ($3); }
1959    /* not ANSI: | WHILE TLPAREN compoundStmt TRPAREN stmt { $$ = exprNode_while ($3, $5); } */
1960 ;
1961
1962 iterWhilePred
1963  : WHILE TLPAREN expr TRPAREN { $$ = exprNode_whilePred($3); }
1964 ;
1965
1966 iterStmt
1967  : ITER_NAME { context_enterIterClause (); } 
1968    CreateInnerScope TLPAREN { setProcessingIterVars ($1); } 
1969    iterArgList TRPAREN 
1970    compoundStmt endIter DeleteInnerScope
1971    { 
1972      $$ = exprNode_iter ($1, $6, $8, $9); 
1973
1974    } 
1975 ;
1976  
1977 iterArgList 
1978  : iterArgExpr { $$ = exprNodeList_singleton ($1); }
1979  | iterArgList { nextIterParam (); } TCOMMA iterArgExpr 
1980    { $$ = exprNodeList_push ($1, $4); }
1981 ;
1982
1983 iterArgExpr
1984   : assignIterExpr  { $$ = exprNode_iterExpr ($1); }
1985   | id              { $$ = exprNode_iterId ($1); }
1986   | TYPE_NAME_OR_ID { uentry ue = cscannerHelp_coerceIterId ($1);
1987
1988                       if (uentry_isValid (ue)) 
1989                         {
1990                           $$ = exprNode_iterId (ue);
1991                         }
1992                       else
1993                         {
1994                           $$ = exprNode_iterNewId (cstring_copy (cscannerHelp_observeLastIdentifier ()));
1995                         }
1996                     }
1997   | NEW_IDENTIFIER  { $$ = exprNode_iterNewId ($1); }
1998 ;
1999
2000 /*
2001 ** everything is the same, EXCEPT it cannot be a NEW_IDENTIFIER 
2002 */
2003
2004 cconstantExpr
2005  : CCONSTANT
2006  | cconstantExpr CCONSTANT { $$ = exprNode_combineLiterals ($1, $2); }  
2007 ;
2008
2009 primaryIterExpr
2010  : cconstantExpr 
2011  | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); }
2012 ;
2013  
2014 postfixIterExpr
2015  : primaryIterExpr 
2016  | postfixExpr TLSQBR expr TRSQBR { $$ = exprNode_arrayFetch ($1, $3); }
2017  | postfixExpr TLPAREN TRPAREN { $$ = exprNode_functionCall ($1, exprNodeList_new ()); }
2018  | postfixExpr TLPAREN argumentExprList TRPAREN { $$ = exprNode_functionCall ($1, $3); }
2019  | VA_ARG TLPAREN assignExpr TCOMMA typeExpression TRPAREN
2020        { $$ = exprNode_vaArg ($1, $3, $5); }
2021  | postfixExpr NotType TDOT newId IsType { $$ = exprNode_fieldAccess ($1, $3, $4); }
2022  | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $3, $4); }
2023  | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); }
2024  | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); }
2025 ;
2026  
2027 unaryIterExpr
2028  : postfixIterExpr 
2029  | INC_OP unaryExpr    { $$ = exprNode_preOp ($2, $1); }
2030  | DEC_OP unaryExpr    { $$ = exprNode_preOp ($2, $1); }
2031  | TAMPERSAND castExpr { $$ = exprNode_preOp ($2, $1); }
2032  | TMULT castExpr      { $$ = exprNode_preOp ($2, $1); }
2033  | TPLUS castExpr      { $$ = exprNode_preOp ($2, $1); }
2034  | TMINUS castExpr     { $$ = exprNode_preOp ($2, $1); }
2035  | TTILDE castExpr     { $$ = exprNode_preOp ($2, $1); }
2036  | TEXCL castExpr      { $$ = exprNode_preOp ($2, $1); }
2037  | sizeofExpr          { $$ = $1; }
2038 ;
2039
2040 castIterExpr
2041  : unaryIterExpr 
2042  | TLPAREN typeExpression TRPAREN castExpr { $$ = exprNode_cast ($1, $4, $2); } 
2043 ;
2044  
2045 timesIterExpr
2046  : castIterExpr 
2047  | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); }
2048  | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); }
2049  | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); }
2050 ;
2051
2052 plusIterExpr
2053  : timesIterExpr 
2054  | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
2055  | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
2056 ;
2057
2058 shiftIterExpr
2059  : plusIterExpr 
2060  | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
2061  | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
2062 ;
2063
2064 relationalIterExpr
2065  : shiftIterExpr 
2066  | relationalExpr TLT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
2067  | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
2068  | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
2069  | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
2070 ;
2071  
2072 equalityIterExpr 
2073  : relationalIterExpr 
2074  | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
2075  | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
2076 ;
2077
2078 bitandIterExpr
2079  : equalityIterExpr 
2080  | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); }
2081 ;
2082
2083 xorIterExpr
2084  : bitandIterExpr 
2085  | xorExpr TCIRC bitandExpr { $$ = exprNode_op ($1, $3, $2); }
2086
2087
2088 bitorIterExpr
2089  : xorIterExpr 
2090  | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); }
2091 ;
2092
2093 andIterExpr 
2094  : bitorIterExpr 
2095  | andExpr AND_OP bitorExpr { $$ = exprNode_op ($1, $3, $2); }
2096 ;
2097
2098 orIterExpr
2099  : andIterExpr 
2100  | orExpr OR_OP andExpr { $$ = exprNode_op ($1, $3, $2); }
2101 ;
2102
2103 conditionalIterExpr 
2104  : orIterExpr 
2105  | orExpr TQUEST { context_enterTrueClause ($1); } 
2106    expr TCOLON { context_enterFalseClause ($1); } conditionalExpr
2107    { $$ = exprNode_cond ($1, $4, $7); }
2108 ;
2109
2110 assignIterExpr
2111  : conditionalIterExpr 
2112  | unaryExpr TASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2113  | unaryExpr MUL_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2114  | unaryExpr DIV_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2115  | unaryExpr MOD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2116  | unaryExpr ADD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2117  | unaryExpr SUB_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2118  | unaryExpr LEFT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2119  | unaryExpr RIGHT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2120  | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2121  | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2122  | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
2123 ;
2124
2125 endIter
2126  : ITER_ENDNAME { $$ = $1; }
2127  | /* empty */  { $$ = uentry_undefined; } 
2128 ;
2129
2130 doHeader
2131  : DO { context_enterDoWhileClause (); $$ = $1; }
2132 ;
2133   
2134 iterationStmt 
2135  : whilePred stmt 
2136    { $$ = exprNode_while ($1, $2); context_exitWhileClause ($1, $2); }
2137  | doHeader stmt WHILE TLPAREN expr TRPAREN TSEMI 
2138    { $$ = exprNode_statement (exprNode_doWhile ($2, $5), $7); }
2139  | forPred stmt 
2140    { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); }
2141 ;
2142
2143 iterationStmtErr 
2144  : whilePred stmtErr { $$ = exprNode_while ($1, $2); context_exitWhileClause ($1, $2); }
2145  | doHeader stmtErr WHILE TLPAREN expr TRPAREN TSEMI
2146    { $$ = exprNode_statement (exprNode_doWhile ($2, $5), $7); }
2147  | doHeader stmtErr WHILE TLPAREN expr TRPAREN 
2148    { $$ = exprNode_doWhile ($2, $5); }
2149  | forPred stmtErr { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); }
2150 ;
2151  
2152 jumpStmt
2153  : GOTO newId TSEMI         { $$ = exprNode_goto ($2); }
2154  | CONTINUE TSEMI           { $$ = exprNode_continue ($1, BADTOK); }
2155  | QINNERCONTINUE CONTINUE TSEMI    
2156                             { $$ = exprNode_continue ($1, QINNERCONTINUE); }
2157  | BREAK TSEMI              { $$ = exprNode_break ($1, BADTOK); }
2158  | QSWITCHBREAK BREAK TSEMI { $$ = exprNode_break ($2, QSWITCHBREAK); }
2159  | QLOOPBREAK BREAK TSEMI   { $$ = exprNode_break ($2, QLOOPBREAK); }
2160  | QINNERBREAK BREAK TSEMI  { $$ = exprNode_break ($2, QINNERBREAK); }
2161  | QSAFEBREAK BREAK TSEMI   { $$ = exprNode_break ($2, QSAFEBREAK); }
2162  | RETURN TSEMI             { $$ = exprNode_nullReturn ($1); }
2163  | RETURN expr TSEMI        { $$ = exprNode_return ($2); }
2164 ;
2165  
2166 optSemi
2167  : 
2168  | TSEMI { ; } 
2169 ;
2170
2171 optComma
2172  : 
2173  | TCOMMA { ; } 
2174 ;
2175
2176 id
2177  : IDENTIFIER 
2178 ;
2179
2180 newId
2181  : NEW_IDENTIFIER 
2182  | ITER_NAME       { $$ = uentry_getName ($1); }
2183  | ITER_ENDNAME    { $$ = uentry_getName ($1); }
2184  | id              { $$ = uentry_getName ($1); }
2185  | TYPE_NAME_OR_ID { $$ = $1; } 
2186 ;
2187
2188 typeName
2189  : TYPE_NAME
2190  | TYPE_NAME_OR_ID { $$ = ctype_unknown; }
2191  | CTYPEOF TLPAREN expr TRPAREN { $$ = exprNode_getType ($3); exprNode_free ($3); }
2192  | CTYPEOF TLPAREN typeExpression TRPAREN { $$ = qtype_getType ($3); } 
2193 ;
2194
2195 %%
2196
2197 /*@-redecl@*/ /*@-namechecks@*/
2198 extern char *yytext;
2199 /*@=redecl@*/ /*@=namechecks@*/
2200
2201 # include "bison.reset"
2202
2203 void yyerror (/*@unused@*/ char *s) 
2204 {
2205   static bool givehint = FALSE;
2206
2207   if (context_inIterDef ())
2208     {
2209       llerror (FLG_SYNTAX, message ("Iter syntax not parseable: %s", 
2210                                     context_inFunctionName ()));
2211     }
2212   else if (context_inIterEnd ())
2213     {
2214       llerror (FLG_SYNTAX, message ("Iter finalizer syntax not parseable: %s", 
2215                                     context_inFunctionName ()));
2216     }
2217   else if (context_inMacro ())
2218     {
2219       llerror (FLG_SYNTAX, message ("Macro syntax not parseable: %s", 
2220                                     context_inFunctionName ()));
2221       
2222       if (context_inUnknownMacro ())
2223         {
2224           if (!givehint)
2225             {
2226               llhint (cstring_makeLiteral 
2227                      ("Precede macro definition with /*@notfunction@*/ "
2228                       "to suppress checking and force expansion"));
2229               givehint = TRUE;
2230             }
2231         }
2232
2233       cscannerHelp_swallowMacro ();
2234       context_exitAllClausesQuiet ();
2235     }
2236   else
2237     {
2238       llparseerror (cstring_undefined);
2239     }
2240 }
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
This page took 0.207385 seconds and 5 git commands to generate.