X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/fafc64cf2c3dd143d33b627f008ce8a36f224320..312c981596ce6202de7686f2d4c46aec1bae3939:/src/cgrammar.y diff --git a/src/cgrammar.y b/src/cgrammar.y index 41fbca6..3367716 100644 --- a/src/cgrammar.y +++ b/src/cgrammar.y @@ -1,6 +1,6 @@ /*;-*-C-*-; ** Splint - annotation-assisted static program checker -** Copyright (C) 1994-2001 University of Virginia, +** Copyright (C) 1994-2002 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -17,8 +17,8 @@ ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ** MA 02111-1307, USA. ** -** For information on lclint: lclint-request@cs.virginia.edu -** To report a bug: lclint-bug@cs.virginia.edu +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org ** For more information: http://www.splint.org */ %{ @@ -26,12 +26,12 @@ ** ** cgrammar.y ** -** Yacc/Bison grammar for extended ANSI C used by LCLint. +** Yacc/Bison grammar for extended ANSI C used by Splint. ** ** original grammar by Nate Osgood --- ** hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993 ** -** changes for LCLint --- handle typedef names correctly +** changes for Splint --- handle typedef names correctly ** fix struct/union parsing bug (empty struct is accepted) ** add productions to handle macros --- require ** error correction --- main source of conflicts in grammar. @@ -47,10 +47,9 @@ /*@=allmacros@*/ extern int yylex (); -extern void swallowMacro (void); extern void yyerror (char *); -# include "lclintMacros.nf" +# include "splintMacros.nf" # include "basic.h" # include "cscanner.h" # include "cgrammar.h" @@ -94,7 +93,7 @@ extern void yyerror (char *); /*@only@*/ modifiesClause modsclause; /*@only@*/ warnClause warnclause; /*@only@*/ stateClause stateclause; - + /*@only@*/ pointers pointers; /*@only@*/ functionConstraint fcnconstraint; /*@only@*/ metaStateConstraint msconstraint; @@ -136,7 +135,7 @@ extern void yyerror (char *); %token TSEMI TLBRACE TRBRACE TCOMMA TCOLON TASSIGN TLPAREN %token TRPAREN TLSQBR TRSQBR TDOT TAMPERSAND TEXCL TTILDE %token TMINUS TPLUS TMULT TDIV TPERCENT TLT TGT TCIRC TBAR TQUEST -%token CSIZEOF CALIGNOF ARROW_OP CTYPEDEF COFFSETOF +%token CSIZEOF CALIGNOF CTYPEOF ARROW_OP CTYPEDEF COFFSETOF %token INC_OP DEC_OP LEFT_OP RIGHT_OP %token LE_OP GE_OP EQ_OP NE_OP AND_OP OR_OP %token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN @@ -156,12 +155,13 @@ extern void yyerror (char *); %token QSETS %token QRELEASES %token QPRECLAUSE -%token QPOSTCLAUSE +%token QPOSTCLAUSE +%token QINVARIANT %token QALT %token QUNDEF QKILLED %token QENDMACRO -/* additional tokens introduced by lclint pre-processor. */ +/* additional tokens introduced by splint pre-processor. */ %token LLMACRO LLMACROITER LLMACROEND TENDMACRO /* break comments: */ @@ -182,7 +182,7 @@ extern void yyerror (char *); %token QNOTREACHED /* type qualifiers: */ -%token QCONST QVOLATILE QINLINE QEXTENSION QEXTERN QSTATIC QAUTO QREGISTER +%token QCONST QRESTRICT QVOLATILE QINLINE QEXTENSION QEXTERN QSTATIC QAUTO QREGISTER %token QOUT QIN QYIELD QONLY QTEMP QSHARED QREF QUNIQUE %token QCHECKED QUNCHECKED QCHECKEDSTRICT QCHECKMOD %token QKEEP QKEPT QPARTIAL QSPECIAL QOWNED QDEPENDENT @@ -195,7 +195,6 @@ extern void yyerror (char *); %token CGCHAR CBOOL CINT CGFLOAT CDOUBLE CVOID %token QANYTYPE QINTEGRALTYPE QUNSIGNEDINTEGRALTYPE QSIGNEDINTEGRALTYPE -%type nullterminatedQualifier %token QNULLTERMINATED %token QSETBUFFERSIZE %token QSETSTRINGLENGTH @@ -237,7 +236,7 @@ extern void yyerror (char *); %token METASTATE_NAME %type metaStateName %type enumerator newId /*@-varuse@*/ /* yacc declares yytranslate here */ -%type pointers /*@=varuse@*/ +%type pointers /*@=varuse@*/ %type doHeader stateTag conditionTag startConditionClause %type exitsQualifier checkQualifier stateQualifier @@ -278,8 +277,13 @@ extern void yyerror (char *); %type BufConstraintList +%type optStructInvariant + %type BufUnaryOp +/*drl 1/6/2002 either /\ or && */ +%type constraintSeperator + %type enumeratorList %type fieldDesignator @@ -302,13 +306,15 @@ extern void yyerror (char *); %type compoundStmt compoundStmtAux compoundStmtRest compoundStmtAuxErr %type expressionStmt selectionStmt iterationStmt jumpStmt iterDefIterationStmt %type stmtErr stmtListErr compoundStmtErr expressionStmtErr -%type iterationStmtErr initializerList initializer ifPred whilePred forPred iterWhilePred +%type iterationStmtErr initializerList typeInitializerList initializer +%type ifPred whilePred forPred iterWhilePred typeInitializer -%type storageSpecifier typeQualifier typeModifier globQual -%type optGlobQuals +%type designator designatorList designation + +%type storageSpecifier typeQualifier typeModifier globQual innerMods +%type optGlobQuals innerModsList %type completeType completeTypeSpecifier optCompleteType %type completeTypeSpecifierAux altType typeExpression -/*%type lclintassertion*/ %start file @@ -329,19 +335,21 @@ externalDef | iterDecl { uentry_clearDecl (); } | macroDef { uentry_clearDecl (); } | initializer { uentry_checkDecl (); exprNode_free ($1); } + | TSEMI { uentry_clearDecl (); lltok_free ($1); /* evans 2002-02-08: okay to have a null statement */ } | error { uentry_clearDecl (); } constantDecl : QCONSTANT completeTypeSpecifier NotType namedDecl NotType optSemi IsType QENDMACRO - { checkConstant ($2, $4); } + { checkConstant ($2, $4); lltok_free2 ($1, $8); } | QCONSTANT completeTypeSpecifier NotType namedDecl NotType TASSIGN IsType init optDeclarators optSemi QENDMACRO - { checkValueConstant ($2, $4, $8) ; } + { checkValueConstant ($2, $4, $8); lltok_free3 ($1, $6, $11); } fcnDecl : QFUNCTION { context_enterFunctionHeader (); } plainFcn optSemi QENDMACRO { declareStaticFunction ($3); context_quietExitFunction (); context_exitFunctionHeader (); + lltok_free2 ($1, $5); /*!*/ } plainFcn @@ -362,20 +370,25 @@ plainNamedDecl namedDeclBase : newId { $$ = idDecl_create ($1, qtype_unknown ()); } | IsType TLPAREN NotType namedDecl IsType TRPAREN - { $$ = idDecl_expectFunction ($4); } + { $$ = idDecl_expectFunction ($4); lltok_free2 ($2, $6); } | namedDeclBase TLSQBR TRSQBR - { $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); } + { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); lltok_free2 ($2, $3); } | namedDeclBase TLSQBR IsType constantExpr TRSQBR NotType { - exprNode_findValue($4); + exprNode_findValue ($4); + idDecl_notExpectingFunction ($1); + if (exprNode_hasValue ($4)) { - $$ = idDecl_replaceCtype ($1, ctype_makeFixedArray (idDecl_getCtype ($1), exprNode_getLongValue ($4))); + $$ = idDecl_replaceCtype ($1, ctype_makeInnerFixedArray (idDecl_getCtype ($1), + exprNode_getLongValue ($4))); } else { - $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); + $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); } + + lltok_free2 ($2, $5); } | namedDeclBase PushType TLPAREN TRPAREN { setCurrentParams (uentryList_missingParams); } @@ -385,27 +398,37 @@ namedDeclBase uentryList_makeMissingParams ()); $$ = idDecl_replaceCtype ($1, ct); - idDecl_addClauses ($$, $6); - context_popLoc (); + /*drl 7/25/01 added*/ setImplictfcnConstraints(); + + functionClauseList_ImplictConstraints($6); + + idDecl_addClauses ($$, $6); + context_popLoc (); + lltok_free2 ($3, $4); } | namedDeclBase PushType TLPAREN genericParamList TRPAREN { setCurrentParams ($4); } functionClauses - { setImplictfcnConstraints (); + { + setImplictfcnConstraints (); + functionClauseList_ImplictConstraints($6); clearCurrentParams (); $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4)); idDecl_addClauses ($$, $7); context_popLoc (); + lltok_free2 ($3, $5); } plainNamedDeclBase : newId { $$ = idDecl_create ($1, qtype_unknown ()); } | IsType TLPAREN NotType plainNamedDecl IsType TRPAREN - { $$ = idDecl_expectFunction ($4); } + { $$ = idDecl_expectFunction ($4); lltok_free2 ($2, $6); } | plainNamedDeclBase TLSQBR TRSQBR - { $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); } + { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); + lltok_free2 ($2, $3); + } | plainNamedDeclBase TLSQBR IsType constantExpr TRSQBR NotType { int value; @@ -420,7 +443,8 @@ plainNamedDeclBase value = 0; } - $$ = idDecl_replaceCtype ($1, ctype_makeFixedArray (idDecl_getCtype ($1), value)); + $$ = idDecl_replaceCtype ($1, ctype_makeInnerFixedArray (idDecl_getCtype ($1), value)); + lltok_free2 ($2, $5); } | plainNamedDeclBase PushType TLPAREN TRPAREN { setCurrentParams (uentryList_missingParams); } @@ -432,6 +456,7 @@ plainNamedDeclBase $$ = idDecl_replaceCtype ($1, ct); idDecl_addClauses ($$, $6); context_popLoc (); + lltok_free2 ($3, $4); } | plainNamedDeclBase PushType TLPAREN genericParamList TRPAREN { setCurrentParams ($4); } @@ -441,46 +466,58 @@ plainNamedDeclBase $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4)); idDecl_addClauses ($$, $7); context_popLoc (); + lltok_free ($3); + /*!! lltok_free2 ($3, $5); */ } iterDecl : QITER newId TLPAREN genericParamList TRPAREN { setCurrentParams ($4); } functionClausesPlain { clearCurrentParams (); } optSemi QENDMACRO - { declareCIter ($2, $4); } + { declareCIter ($2, $4); + lltok_free3 ($1, $3, $5); + } macroDef - : LLMACRO macroBody TENDMACRO { exprNode_checkMacroBody ($2); } - | LLMACROITER iterBody TENDMACRO { exprNode_checkIterBody ($2); } - | LLMACROEND endBody TENDMACRO { exprNode_checkIterEnd ($2); } - | LLMACRO TENDMACRO /* no stmt */ { exprChecks_checkEmptyMacroBody (); } + : LLMACRO macroBody TENDMACRO { exprNode_checkMacroBody ($2); lltok_free2 ($1, $3); } + | LLMACROITER iterBody TENDMACRO { exprNode_checkIterBody ($2); lltok_free2 ($1, $3); } + | LLMACROEND endBody TENDMACRO { exprNode_checkIterEnd ($2); lltok_free2 ($1, $3);} + | LLMACRO TENDMACRO /* no stmt */ { exprChecks_checkEmptyMacroBody (); lltok_free2 ($1, $2); } fcnDefHdr : fcnDefHdrAux { clabstract_declareFunction ($1); } metaStateConstraint : metaStateSpecifier TASSIGN metaStateExpression - { $$ = metaStateConstraint_create ($1, $3); } + { $$ = metaStateConstraint_create ($1, $3); lltok_free ($2); } metaStateSpecifier : BufConstraintSrefExpr { cscanner_expectingMetaStateName (); } TCOLON metaStateName { cscanner_clearExpectingMetaStateName (); - $$ = metaStateSpecifier_create ($1, $4); } + $$ = metaStateSpecifier_create ($1, $4); + lltok_free ($3); + } | CTOK_ELIPSIS { cscanner_expectingMetaStateName (); } TCOLON metaStateName { cscanner_clearExpectingMetaStateName (); - $$ = metaStateSpecifier_createElipsis ($4); } + $$ = metaStateSpecifier_createElipsis ($4); + lltok_free2 ($1, $3); + } metaStateExpression : metaStateSpecifier { $$ = metaStateExpression_create ($1); } -| metaStateSpecifier TBAR metaStateExpression { $$ = metaStateExpression_createMerge ($1, $3); } +| metaStateSpecifier TBAR metaStateExpression { $$ = metaStateExpression_createMerge ($1, $3); lltok_free ($2); } metaStateName : METASTATE_NAME /*drl*/ +constraintSeperator +: TCAND +| AND_OP + BufConstraintList -: BufConstraint TCAND BufConstraintList { $$ = constraintList_add ($3, $1); } +: BufConstraint constraintSeperator BufConstraintList { $$ = constraintList_add ($3, $1); } | BufConstraint { $$ = constraintList_single ($1); } BufConstraint @@ -682,7 +719,8 @@ conditionTag fcnDefHdrAux : namedDecl { - qtype qint = qtype_create (ctype_int); + /**!!! deal with fred; fred (int); declarations! **/ + qtype qint = qtype_create (ctype_int); $$ = idDecl_fixBase ($1, qint); qtype_free (qint); } @@ -780,6 +818,9 @@ primaryExpr | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); } | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (coerceId ($1)); } | QEXTENSION { $$ = exprNode_makeError (); } + | TLPAREN { exprChecks_inCompoundStatementExpression (); } + compoundStmt TRPAREN + { exprChecks_leaveCompoundStatementExpression (); $$ = exprNode_compoundStatementExpression ($1, $3); } postfixExpr : primaryExpr @@ -791,7 +832,9 @@ postfixExpr | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $3, $4); } | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); } | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); } - + | TLPAREN typeExpression TRPAREN TLBRACE typeInitializerList optComma TRBRACE + { /* added for C99 */ $$ = exprNode_undefined; /*@i87 no checking */ } + argumentExprList : assignExpr { $$ = exprNodeList_singleton ($1); } | argumentExprList TCOMMA assignExpr { $$ = exprNodeList_push ($1, $3); } @@ -810,27 +853,30 @@ unaryExpr | offsetofExpr { $$ = $1; } fieldDesignator - : fieldDesignator TDOT newId { $$ = cstringList_add ($1, $3); } - | newId { $$ = cstringList_single ($1); } + : fieldDesignator TDOT newId { $$ = cstringList_add ($1, $3); lltok_free ($2); } + | fieldDesignator TLSQBR expr TRSQBR { $$ = $1; lltok_free2 ($2, $4); } + /* evans 2002-07-02: offsetof designators can use array indexes */ + | newId { $$ = cstringList_single ($1); } offsetofExpr : COFFSETOF IsType TLPAREN typeExpression NotType TCOMMA fieldDesignator TRPAREN IsType - { $$ = exprNode_offsetof ($4, $7); } + { $$ = exprNode_offsetof ($4, $7); + lltok_free3 ($1, $3, $6); lltok_free ($8); } sizeofExpr : IsType { context_setProtectVars (); } sizeofExprAux { context_sizeofReleaseVars (); $$ = $3; } sizeofExprAux - : CSIZEOF TLPAREN typeExpression TRPAREN { $$ = exprNode_sizeofType ($3); } - | CSIZEOF unaryExpr { $$ = exprNode_sizeofExpr ($2); } - | CALIGNOF TLPAREN typeExpression TRPAREN { $$ = exprNode_alignofType ($3); } - | CALIGNOF unaryExpr { $$ = exprNode_alignofExpr ($2); } + : CSIZEOF TLPAREN typeExpression TRPAREN { $$ = exprNode_sizeofType ($3); lltok_free3 ($1, $2, $4); } + | CSIZEOF unaryExpr { $$ = exprNode_sizeofExpr ($2); lltok_free ($1); } + | CALIGNOF TLPAREN typeExpression TRPAREN { $$ = exprNode_alignofType ($3); lltok_free3 ($1, $2, $4); } + | CALIGNOF unaryExpr { $$ = exprNode_alignofExpr ($2); lltok_free ($1); } castExpr : unaryExpr | TLPAREN typeExpression TRPAREN castExpr - { $$ = exprNode_cast ($1, $4, $2); } + { $$ = exprNode_cast ($1, $4, $2); lltok_free ($3); } timesExpr : castExpr @@ -938,8 +984,8 @@ initializer instanceDecl : completeTypeSpecifier IsType TSEMI - { $$ = exprNode_makeError (); } - /* + { $$ = exprNode_makeError (); } + /* ** This causes r/r conflicts with function definitions. ** Instead we need to snarf one first. (gack) ** @@ -1004,9 +1050,26 @@ optDeclarators init : assignExpr - | TLBRACE initList TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); } - | TLBRACE initList TCOMMA TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); } + | TLBRACE initList TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); lltok_free ($3); } + | TLBRACE initList TCOMMA TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); lltok_free2 ($3, $4); } + | designation init { $$ = exprNode_undefined; } +/* +** Splint parses these (added in ISO C99), but no checking yet... +*/ + +designation + : designatorList TASSIGN { $$ = $1; } + | newId TCOLON { $$ = exprNode_undefined; + /* gcc extension, obsolete since 2.5 */ } + +designatorList + : designator { $$ = exprNode_undefined; } + | designatorList designator { $$ = exprNode_undefined; } + +designator + : TLSQBR constantExpr TRSQBR { $$ = exprNode_undefined; } + | TDOT newId { $$ = exprNode_undefined; } initList : init @@ -1026,9 +1089,6 @@ storageSpecifier | QAUTO { $$ = qual_createAuto (); } | QREGISTER { $$ = qual_createRegister (); } -nullterminatedQualifier: - QNULLTERMINATED IsType { $$ = qual_createNullTerminated (); } - stateClause : stateClausePlain QENDMACRO { $$ = $1; } @@ -1176,6 +1236,7 @@ definedQualifier typeQualifier : QCONST IsType { $$ = qual_createConst (); } | QVOLATILE IsType { $$ = qual_createVolatile (); } + | QRESTRICT IsType { $$ = qual_createRestrict (); } | definedQualifier IsType { $$ = $1; } | stateQualifier IsType { $$ = $1; } | exitsQualifier IsType { $$ = $1; } @@ -1197,14 +1258,14 @@ typeSpecifier | CGFLOAT NotType | CDOUBLE NotType | CVOID NotType - | QANYTYPE NotType { $$ = ctype_unknown; } + | QANYTYPE NotType { $$ = ctype_makeAnytype (); } | QINTEGRALTYPE NotType { $$ = ctype_anyintegral; } | QUNSIGNEDINTEGRALTYPE NotType { $$ = ctype_unsignedintegral; } | QSIGNEDINTEGRALTYPE NotType { $$ = ctype_signedintegral; } | typeName NotType | suSpc NotType | enumSpc NotType - | typeModifier NotType { $$ = ctype_fromQual ($1); } + | typeModifier NotType { $$ = ctype_fromQual ($1); } completeType : IsType completeTypeSpecifier IsType @@ -1229,12 +1290,19 @@ optCompleteType : /* empty */ { $$ = qtype_unknown (); } | completeTypeSpecifier { $$ = $1; } + +optStructInvariant +: /* empty */ { $$ = constraintList_undefined; } +/* drl commenting before a CVS commit + | QINVARIANT BufConstraintList QENDMACRO { $$ = $2 } +*/ suSpc : NotType CSTRUCT newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } CreateStructInnerScope - structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } + structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } TRBRACE - { $$ = declareStruct ($3, $8); } + optStructInvariant + { ctype ct; ct = declareStruct ($3, $8); setGlobalStructInfo(ct, $12); $$ = ct; } | NotType CUNION newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } CreateStructInnerScope structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } @@ -1256,10 +1324,10 @@ suSpc { $$ = declareUnnamedUnion ($7); } | NotType CSTRUCT IsType TLBRACE TRBRACE { $$ = ctype_createUnnamedStruct (uentryList_new ()); } - | NotType CUNION IsType TLBRACE TRBRACE + | NotType CUNION IsType TLBRACE TRBRACE { $$ = ctype_createUnnamedUnion (uentryList_new ()); } | NotType CSTRUCT newId NotType { $$ = handleStruct ($3); } - | NotType CUNION newId NotType { $$ = handleUnion ($3); } + | NotType CUNION newId NotType { $$ = handleUnion ($3); } NotType : { g_expectingTypeName = FALSE; } @@ -1319,9 +1387,8 @@ optNamedDecl | pointers TYPE_NAME { qtype qt = qtype_unknown (); - qtype_adjustPointers ($1, qt); - $$ = idDecl_create (cstring_copy (LastIdentifier ()), qt); + $$ = idDecl_create (cstring_copy (cscanner_observeLastIdentifier ()), qt); } | pointers optNamedDecl { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); } @@ -1336,18 +1403,19 @@ genericParamList | NotType paramIdList { $$ = handleParamIdList ($2); } innerMods - : QCONST { /* ignored for now */; } - | QVOLATILE { ; } + : QCONST { $$ = qual_createConst (); } + | QRESTRICT { $$ = qual_createRestrict (); } + | QVOLATILE { $$ = qual_createVolatile (); } innerModsList - : innerMods { ; } - | innerModsList innerMods { ; } + : innerMods { $$ = qualList_single ($1); } + | innerModsList innerMods { $$ = qualList_add ($1, $2); } pointers - : TMULT { $$ = 1; } - | TMULT innerModsList { $$ = 1; } - | TMULT pointers { $$ = 1 + $2; } - | TMULT innerModsList pointers { $$ = 1 + $3; } + : TMULT { $$ = pointers_create ($1); } + | TMULT innerModsList { $$ = pointers_createMods ($1, $2); } + | TMULT pointers { $$ = pointers_extend (pointers_create ($1), $2); } + | TMULT innerModsList pointers { $$ = pointers_extend (pointers_createMods ($1, $2), $3); } paramIdList : idList @@ -1414,9 +1482,9 @@ abstractDeclBase | TLSQBR TRSQBR { $$ = ctype_makeArray (ctype_unknown); } | TLSQBR constantExpr TRSQBR { $$ = ctype_makeFixedArray (ctype_unknown, exprNode_getLongValue ($2)); } - | abstractDeclBase TLSQBR TRSQBR { $$ = ctype_makeArray ($1); } + | abstractDeclBase TLSQBR TRSQBR { $$ = ctype_makeInnerArray ($1); } | abstractDeclBase TLSQBR constantExpr TRSQBR - { $$ = ctype_makeFixedArray ($1, exprNode_getLongValue ($3)); } + { $$ = ctype_makeInnerFixedArray ($1, exprNode_getLongValue ($3)); } | IsType TLPAREN TRPAREN { $$ = ctype_makeFunction (ctype_unknown, uentryList_makeMissingParams ()); } | IsType TLPAREN paramTypeList TRPAREN @@ -1438,18 +1506,7 @@ stmt | iterationStmt | iterStmt | jumpStmt -/* | lclintassertion {$$ = $1; printf ("Doing stmt lclintassertion\n"); }*/ -/* -lclintassertion - : QSETBUFFERSIZE id CCONSTANT QENDMACRO { printf(" QSETBUFFERSIZE id CCONSTANT HEllo World\n"); uentry_setBufferSize($2, $3); $$ = exprNode_createTok ($4); - } - | QSETSTRINGLENGTH id CCONSTANT QENDMACRO { printf(" QSETSTRINGLENGTH id CCONSTANT HEllo World\n"); uentry_setStringLength($2, $3); $$ = exprNode_createTok ($4); - } - | QTESTINRANGE id CCONSTANT QENDMACRO {printf(" QTESTINRANGE\n"); uentry_testInRange($2, $3); $$ = exprNode_createTok ($4); - } - -/* | QSETBUFFERSIZE id id {$$ = $2; printf(" QSETBUFFERSIZE id id HEllo World\n");} */ iterBody : iterDefStmtList { $$ = $1; } @@ -1502,9 +1559,9 @@ iterDefStmt | error { $$ = exprNode_makeError (); } iterSelectionStmt - : ifPred iterDefStmt + : ifPred { exprNode_checkIfPred ($1); } iterDefStmt { /* don't: context_exitTrueClause ($1, $2); */ - $$ = exprNode_if ($1, $2); + $$ = exprNode_if ($1, $3); } openScope @@ -1618,6 +1675,14 @@ initializerList : initializer { $$ = $1; } | initializerList initializer { $$ = exprNode_concat ($1, $2); } +typeInitializerList + : typeInitializer { $$ = $1; } + | typeInitializerList TCOMMA typeInitializer { $$ = exprNode_concat ($1, $3); } + +typeInitializer + : assignExpr { $$ = $1; } + | TLBRACE typeInitializerList optComma TRBRACE { $$ = $2; } + stmtList : stmt { $$ = $1; } | stmtList stmt { $$ = exprNode_concat ($1, $2); } @@ -1633,7 +1698,12 @@ expressionStmtErr ifPred : CIF TLPAREN expr TRPAREN - { $$ = $3; exprNode_produceGuards ($3); context_enterTrueClause ($3); } + { + exprNode_produceGuards ($3); context_enterTrueClause ($3); + exprNode_checkIfPred ($3); + $$ = $3; + } + /* ** not ANSI: | CIF TLPAREN compoundStmt TRPAREN ** { $$ = $3; context_enterTrueClause (); } @@ -1645,7 +1715,7 @@ selectionStmt context_exitTrueClause ($1, $2); $$ = exprNode_if ($1, $2); } - | ifPred stmt CELSE { context_enterFalseClause ($1); } stmt + | ifPred stmt CELSE { context_enterFalseClause ($1); } stmt { context_exitClause ($1, $2, $5); $$ = exprNode_ifelse ($1, $2, $5); @@ -1687,7 +1757,7 @@ iterArgExpr } else { - $$ = exprNode_iterNewId (cstring_copy (LastIdentifier ())); + $$ = exprNode_iterNewId (cstring_copy (cscanner_observeLastIdentifier ())); } } | NEW_IDENTIFIER { $$ = exprNode_iterNewId ($1); } @@ -1841,6 +1911,10 @@ optSemi : | TSEMI { ; } +optComma + : + | TCOMMA { ; } + id : IDENTIFIER @@ -1854,6 +1928,8 @@ newId typeName : TYPE_NAME | TYPE_NAME_OR_ID { $$ = ctype_unknown; } + | CTYPEOF TLPAREN expr TRPAREN { $$ = exprNode_getType ($3); exprNode_free ($3); } + | CTYPEOF TLPAREN typeExpression TRPAREN { $$ = qtype_getType ($3); } %% @@ -1893,7 +1969,7 @@ void yyerror (/*@unused@*/ char *s) } } - swallowMacro (); + cscanner_swallowMacro (); context_exitAllClausesQuiet (); } else