X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.y;h=a7cf2431586c0144bae478967fb04eab35fe0e5b;hb=00b554d5087d574b05c2cd034b4e9e0211c7e481;hp=5d1473bfd60ab44075c5c8addd28e2edce5a1286;hpb=b99d2631c97709d691d8dd49d8d4fb9ac2213558;p=fw%2Fsdcc diff --git a/src/SDCC.y b/src/SDCC.y index 5d1473bf..a7cf2431 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -45,6 +45,8 @@ int reentrant = 0 ; int blockNo = 0 ; /* sequential block number */ int currBlockno=0 ; int inCritical= 0 ; +int seqPointNo= 1 ; /* sequence point number */ +int ignoreTypedefType=0; extern int yylex(); int yyparse(void); extern int noLineno ; @@ -60,6 +62,8 @@ STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3) value *cenum = NULL ; /* current enumeration type chain*/ bool uselessDecl = TRUE; +#define YYDEBUG 1 + %} %expect 6 @@ -137,6 +141,7 @@ external_definition blockNo=0; } | declaration { + ignoreTypedefType = 0; if ($1 && $1->type && IS_FUNC($1->type)) { @@ -373,21 +378,21 @@ inclusive_or_expr logical_and_expr : inclusive_or_expr - | logical_and_expr AND_OP inclusive_or_expr - { $$ = newNode(AND_OP,$1,$3);} + | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr + { $$ = newNode(AND_OP,$1,$4);} ; logical_or_expr : logical_and_expr - | logical_or_expr OR_OP logical_and_expr - { $$ = newNode(OR_OP,$1,$3); } + | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr + { $$ = newNode(OR_OP,$1,$4); } ; conditional_expr : logical_or_expr - | logical_or_expr '?' logical_or_expr ':' conditional_expr + | logical_or_expr '?' { seqPointNo++;} logical_or_expr ':' conditional_expr { - $$ = newNode(':',$3,$5) ; + $$ = newNode(':',$4,$6) ; $$ = newNode('?',$1,$$) ; } ; @@ -465,7 +470,7 @@ assignment_operator expr : assignment_expr - | expr ',' assignment_expr { $$ = newNode(',',$1,$3);} + | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);} ; constant_expr @@ -580,7 +585,7 @@ type_specifier : type_specifier2 | type_specifier2 AT constant_expr { - /* add this to the storage class specifier */ + /* add this to the storage class specifier */ SPEC_ABSA($1) = 1; /* set the absolute addr flag */ /* now get the abs addr from value */ SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ; @@ -591,30 +596,37 @@ type_specifier2 : CHAR { $$=newLink(SPECIFIER); SPEC_NOUN($$) = V_CHAR ; + ignoreTypedefType = 1; } | SHORT { $$=newLink(SPECIFIER); $$->select.s._short = 1 ; + ignoreTypedefType = 1; } | INT { $$=newLink(SPECIFIER); SPEC_NOUN($$) = V_INT ; + ignoreTypedefType = 1; } | LONG { $$=newLink(SPECIFIER); SPEC_LONG($$) = 1 ; + ignoreTypedefType = 1; } | SIGNED { $$=newLink(SPECIFIER); $$->select.s._signed = 1; + ignoreTypedefType = 1; } | UNSIGNED { $$=newLink(SPECIFIER); SPEC_USIGN($$) = 1 ; + ignoreTypedefType = 1; } | VOID { $$=newLink(SPECIFIER); SPEC_NOUN($$) = V_VOID ; + ignoreTypedefType = 1; } | CONST { $$=newLink(SPECIFIER); @@ -627,6 +639,7 @@ type_specifier2 | FLOAT { $$=newLink(SPECIFIER); SPEC_NOUN($$) = V_FLOAT; + ignoreTypedefType = 1; } | XDATA { $$ = newLink (SPECIFIER); @@ -658,15 +671,18 @@ type_specifier2 SPEC_SCLS($$) = S_BIT ; SPEC_BLEN($$) = 1; SPEC_BSTR($$) = 0; + ignoreTypedefType = 1; } | struct_or_union_specifier { uselessDecl = FALSE; $$ = $1 ; + ignoreTypedefType = 1; } | enum_specifier { cenum = NULL ; uselessDecl = FALSE; + ignoreTypedefType = 1; $$ = $1 ; } | TYPE_NAME @@ -676,6 +692,7 @@ type_specifier2 sym = findSym(TypedefTab,NULL,$1) ; $$ = p = copyLinkChain(sym->type); SPEC_TYPEDEF(getSpec(p)) = 0; + ignoreTypedefType = 1; } | sfr_reg_bit ; @@ -685,6 +702,7 @@ sfr_reg_bit $$ = newLink(SPECIFIER) ; SPEC_NOUN($$) = V_SBIT; SPEC_SCLS($$) = S_SBIT; + ignoreTypedefType = 1; } | sfr_attributes ; @@ -696,6 +714,7 @@ sfr_attributes SPEC_NOUN($$) = V_CHAR; SPEC_SCLS($$) = S_SFR ; SPEC_USIGN($$) = 1 ; + ignoreTypedefType = 1; } | SFR BANKED { $$ = newLink(SPECIFIER) ; @@ -703,23 +722,38 @@ sfr_attributes SPEC_NOUN($$) = V_CHAR; SPEC_SCLS($$) = S_SFR ; SPEC_USIGN($$) = 1 ; + ignoreTypedefType = 1; } ; struct_or_union_specifier - : struct_or_union opt_stag '{' struct_declaration_list '}' + : struct_or_union opt_stag + { + if (!$2->type) + { + $2->type = $1; + } + else + { + if ($2->type != $1) + werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union"); + } + + } + '{' struct_declaration_list '}' { structdef *sdef ; symbol *sym, *dsym; // check for errors in structure members - for (sym=$4; sym; sym=sym->next) { + for (sym=$5; sym; sym=sym->next) { if (IS_ABSOLUTE(sym->etype)) { werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "'at'"); SPEC_ABSA(sym->etype) = 0; } if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) { werrorfl(filename, sym->lineDef, E_NOT_ALLOWED, "storage class"); + printTypeChainRaw (sym->type,NULL); SPEC_SCLS(sym->etype) = 0; } for (dsym=sym->next; dsym; dsym=dsym->next) { @@ -732,7 +766,7 @@ struct_or_union_specifier /* Create a structdef */ sdef = $2 ; - sdef->fields = reverseSyms($4) ; /* link the fields */ + sdef->fields = reverseSyms($5) ; /* link the fields */ sdef->size = compStructSize($1,sdef); /* update size of */ /* Create the specifier */ @@ -744,7 +778,17 @@ struct_or_union_specifier { $$ = newLink(SPECIFIER) ; SPEC_NOUN($$) = V_STRUCT; - SPEC_STRUCT($$) = $2 ; + SPEC_STRUCT($$) = $2; + + if (!$2->type) + { + $2->type = $1; + } + else + { + if ($2->type != $1) + werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union"); + } } ; @@ -807,7 +851,8 @@ struct_declaration /* make sure the type is complete and sane */ checkTypeSanity(sym->etype, sym->name); } - $$ = $2; + ignoreTypedefType = 0; + $$ = $2; } ; @@ -854,41 +899,26 @@ struct_declarator enum_specifier : ENUM '{' enumerator_list '}' { - symbol *sym, *dsym; - char _error=0; - - // check for duplicate enums - for (sym=$3; sym; sym=sym->next) { - for (dsym=sym->next; dsym; dsym=dsym->next) { - if (strcmp(sym->name, dsym->name)==0) { - werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, "enum", sym->name); - _error++; - } - } - } - if (_error==0) { - $$ = copyLinkChain(cenum->type); - } else { - $$ = newIntLink(); - SPEC_NOUN($$)=0; - } + $$ = newEnumType ($3); //copyLinkChain(cenum->type); + SPEC_SCLS(getSpec($$)) = 0; } | ENUM identifier '{' enumerator_list '}' { symbol *csym ; + sym_link *enumtype; + + csym=findSym(enumTab,$2,$2->name); + if ((csym && csym->level == $2->level)) + werrorfl(filename, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name); - $2->type = copyLinkChain(cenum->type); - $2->etype = getSpec($2->type); - /* add this to the enumerator table */ - if (!(csym=findSym(enumTab,$2,$2->name)) && - (csym && csym->level == $2->level)) - werror(E_DUPLICATE_TYPEDEF,csym->name); + enumtype = newEnumType ($4); //copyLinkChain(cenum->type); + SPEC_SCLS(getSpec(enumtype)) = 0; + $2->type = enumtype; - addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0); - //addSymChain ($4); - //allocVariables (reverseSyms($4)); - $$ = copyLinkChain(cenum->type); - SPEC_SCLS(getSpec($$)) = 0 ; + /* add this to the enumerator table */ + if (!csym) + addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0); + $$ = copyLinkChain(enumtype); } | ENUM identifier { symbol *csym ; @@ -900,8 +930,6 @@ enum_specifier $$ = newLink(SPECIFIER) ; SPEC_NOUN($$) = V_INT ; } - - SPEC_SCLS(getSpec($$)) = 0 ; } ; @@ -909,10 +937,19 @@ enumerator_list : enumerator | enumerator_list ',' { } - | enumerator_list ',' enumerator { - $3->next = $1 ; - $$ = $3 ; - } + | enumerator_list ',' enumerator + { + symbol *dsym; + + for (dsym=$1; dsym; dsym=dsym->next) + { + if (strcmp($3->name, dsym->name)==0) + werrorfl(filename, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name); + } + + $3->next = $1 ; + $$ = $3 ; + } ; enumerator @@ -932,8 +969,15 @@ enumerator opt_assign_expr : '=' constant_expr { value *val ; - - val = constExprValue($2,TRUE); + + val = constExprValue($2,TRUE); + if (!IS_INT(val->type) && !IS_CHAR(val->type)) + { + werror(E_ENUM_NON_INTEGER); + SNPRINTF(lbuff, sizeof(lbuff), + "%d",(int) floatFromVal(val)); + val = constVal(lbuff); + } $$ = cenum = val ; } | { @@ -1031,7 +1075,8 @@ declarator2 function_declarator2 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; } - | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' + | declarator2 '(' { NestLevel++ ; currBlockno++; } + parameter_type_list ')' { addDecl ($1,FUNCTION,NULL) ; @@ -1167,11 +1212,11 @@ parameter_type_list ; parameter_list - : parameter_declaration + : parameter_declaration | parameter_list ',' parameter_declaration { $3->next = $1 ; - $$ = $3 ; + $$ = $3 ; } ; @@ -1184,16 +1229,18 @@ parameter_declaration for (loop=$2;loop;loop->_isparm=1,loop=loop->next); addSymChain ($2); $$ = symbolVal($2); + ignoreTypedefType = 0; } | type_name { $$ = newValue() ; $$->type = $1; $$->etype = getSpec($$->type); + ignoreTypedefType = 0; } ; type_name - : type_specifier_list { $$ = $1 ;} + : type_specifier_list { $$ = $1; ignoreTypedefType = 0;} | type_specifier_list abstract_declarator { /* go to the end of the list */ @@ -1206,6 +1253,7 @@ type_name p->next = $1 ; } $$ = $2 ; + ignoreTypedefType = 0; } ; @@ -1297,8 +1345,11 @@ statement | jump_statement | critical_statement | INLINEASM ';' { - ast *ex = newNode(INLINEASM,NULL,NULL); + ast *ex; + seqPointNo++; + ex = newNode(INLINEASM,NULL,NULL); ex->values.inlineasm = strdup($1); + seqPointNo++; $$ = ex; } ; @@ -1340,7 +1391,12 @@ labeled_statement } ; -start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; } +start_block : '{' + { + STACK_PUSH(blockNum,currBlockno); + currBlockno = ++blockNo ; + ignoreTypedefType = 0; + } ; end_block : '}' { currBlockno = STACK_POP(blockNum); } @@ -1369,6 +1425,7 @@ declaration_list } else $$ = $1 ; + ignoreTypedefType = 0; } | declaration_list declaration @@ -1391,6 +1448,7 @@ declaration_list else $$ = $2 ; } + ignoreTypedefType = 0; } ; @@ -1401,7 +1459,7 @@ statement_list expression_statement : ';' { $$ = NULL;} - | expr ';' + | expr ';' { $$ = $1; seqPointNo++;} ; else_statement @@ -1411,11 +1469,17 @@ else_statement selection_statement - : IF '(' expr ')' statement else_statement { noLineno++ ; $$ = createIf ($3, $5, $6 ); noLineno--;} + : IF '(' expr ')' { seqPointNo++;} statement else_statement + { + noLineno++ ; + $$ = createIf ($3, $6, $7 ); + noLineno--; + } | SWITCH '(' expr ')' { ast *ex ; static int swLabel = 0 ; + seqPointNo++; /* create a node for expression */ ex = newNode(SWITCH,$3,NULL); STACK_PUSH(swStk,ex); /* save it in the stack */ @@ -1484,16 +1548,17 @@ for : FOR { /* create & push continue, break & body labels */ ; iteration_statement - : while '(' expr ')' statement + : while '(' expr ')' { seqPointNo++;} statement { noLineno++ ; $$ = createWhile ( $1, STACK_POP(continueStack), - STACK_POP(breakStack), $3, $5 ); + STACK_POP(breakStack), $3, $6 ); $$->lineno = $1->lineDef ; noLineno-- ; } | do statement WHILE '(' expr ')' ';' { + seqPointNo++; noLineno++ ; $$ = createDo ( $1 , STACK_POP(continueStack), STACK_POP(breakStack), $5, $2); @@ -1528,8 +1593,8 @@ iteration_statement ; expr_opt - : { $$ = NULL ; } - | expr + : { $$ = NULL ; seqPointNo++; } + | expr { $$ = $1 ; seqPointNo++; } ; jump_statement @@ -1562,6 +1627,7 @@ jump_statement } } | RETURN ';' { + seqPointNo++; if (inCritical) { werror(E_INVALID_CRITICAL); $$ = NULL; @@ -1570,6 +1636,7 @@ jump_statement } } | RETURN expr ';' { + seqPointNo++; if (inCritical) { werror(E_INVALID_CRITICAL); $$ = NULL;