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