X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.y;h=bc7137e668b9a95f9d78f40a2fe3ff8c28da72fe;hb=f0be1f29144f92632436c652a47b7f29dcefb86a;hp=d1590b2ff5ad7896e2ee7ef70afb9e18096d4008;hpb=dc2a1b446d6e97491820555a343187052c58a792;p=fw%2Fsdcc diff --git a/src/SDCC.y b/src/SDCC.y index d1590b2f..bc7137e6 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -34,6 +34,7 @@ #include "port.h" #include "newalloc.h" #include "SDCCerr.h" +#include "SDCCutil.h" extern int yyerror (char *); extern FILE *yyin; @@ -74,7 +75,7 @@ value *cenum = NULL ; /* current enumeration type chain*/ %token IDENTIFIER TYPE_NAME %token CONSTANT STRING_LITERAL -%token SIZEOF +%token SIZEOF TYPEOF %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP %token AND_OP OR_OP %token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN @@ -85,7 +86,7 @@ value *cenum = NULL ; /* current enumeration type chain*/ %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT %token STRUCT UNION ENUM ELIPSIS RANGE FAR %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN -%token NAKED +%token NAKED JAVANATIVE OVERLAY %token INLINEASM %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE @@ -98,11 +99,11 @@ value *cenum = NULL ; /* current enumeration type chain*/ %type struct_declarator_list struct_declaration struct_declaration_list %type declaration init_declarator_list init_declarator %type declaration_list identifier_list parameter_identifier_list -%type declarator2_using_reentrant while do for +%type declarator2_function_attributes while do for %type pointer type_specifier_list type_specifier type_name %type storage_class_specifier struct_or_union_specifier %type declaration_specifiers sfr_reg_bit type_specifier2 -%type using_reentrant using_reentrant_interrupt enum_specifier +%type function_attribute function_attributes enum_specifier %type abstract_declarator abstract_declarator2 unqualified_pointer %type parameter_type_list parameter_list parameter_declaration opt_assign_expr %type stag opt_stag @@ -128,7 +129,9 @@ file ; external_definition - : function_definition { blockNo=0;} + : function_definition { + blockNo=0; + } | declaration { if ($1 && $1->type && IS_FUNC($1->type)) @@ -167,41 +170,48 @@ function_definition } ; -using_reentrant - : using_reentrant_interrupt - | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2,"using_reentrant"); } +function_attribute + : function_attributes + | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); } ; -using_reentrant_interrupt +function_attributes : USING CONSTANT { $$ = newLink() ; $$->class = SPECIFIER ; - SPEC_BNKF($$) = 1; - SPEC_BANK($$) = (int) floatFromVal($2); + FUNC_REGBANK($$) = (int) floatFromVal($2); } | REENTRANT { $$ = newLink (); $$->class = SPECIFIER ; - SPEC_RENT($$) = 1; + FUNC_ISREENT($$)=1; } | CRITICAL { $$ = newLink (); $$->class = SPECIFIER ; - SPEC_CRTCL($$) = 1; + FUNC_ISCRITICAL($$) = 1; } | NAKED { $$ = newLink (); $$->class = SPECIFIER ; - SPEC_NAKED($$) = 1; + FUNC_ISNAKED($$)=1; + } + | JAVANATIVE { $$ = newLink (); + $$->class = SPECIFIER ; + FUNC_ISJAVANATIVE($$)=1; + } + | OVERLAY { $$ = newLink (); + $$->class = SPECIFIER ; + FUNC_ISOVERLAY($$)=1; } | NONBANKED {$$ = newLink (); $$->class = SPECIFIER ; - SPEC_NONBANKED($$) = 1; - if (SPEC_BANKED($$)) { + FUNC_NONBANKED($$) = 1; + if (FUNC_BANKED($$)) { werror(W_BANKED_WITH_NONBANKED); } } | BANKED {$$ = newLink (); $$->class = SPECIFIER ; - SPEC_BANKED($$) = 1; - if (SPEC_NONBANKED($$)) { + FUNC_BANKED($$) = 1; + if (FUNC_NONBANKED($$)) { werror(W_BANKED_WITH_NONBANKED); } if (SPEC_STAT($$)) { @@ -212,8 +222,8 @@ using_reentrant_interrupt { $$ = newLink () ; $$->class = SPECIFIER ; - SPEC_INTN($$) = $1 ; - SPEC_INTRTN($$) = 1; + FUNC_INTNO($$) = $1 ; + FUNC_ISISR($$) = 1; } ; @@ -277,6 +287,7 @@ unary_expr | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; } | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); } | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); } + | TYPEOF unary_expr { $$ = newNode(TYPEOF,NULL,$2); } ; unary_operator @@ -396,34 +407,34 @@ assignment_expr $$ = newNode($2,$1,$3); break; case MUL_ASSIGN: - $$ = newNode('=',$1,newNode('*',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('*',removeIncDecOps(copyAst($1)),$3)); break; case DIV_ASSIGN: - $$ = newNode('=',$1,newNode('/',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('/',removeIncDecOps(copyAst($1)),$3)); break; case MOD_ASSIGN: - $$ = newNode('=',$1,newNode('%',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('%',removeIncDecOps(copyAst($1)),$3)); break; case ADD_ASSIGN: - $$ = newNode('=',$1,newNode('+',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('+',removeIncDecOps(copyAst($1)),$3)); break; case SUB_ASSIGN: - $$ = newNode('=',$1,newNode('-',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('-',removeIncDecOps(copyAst($1)),$3)); break; case LEFT_ASSIGN: - $$ = newNode('=',$1,newNode(LEFT_OP,copyAst($1),$3)); + $$ = newNode('=',$1,newNode(LEFT_OP,removeIncDecOps(copyAst($1)),$3)); break; case RIGHT_ASSIGN: - $$ = newNode('=',$1,newNode(RIGHT_OP,copyAst($1),$3)); + $$ = newNode('=',$1,newNode(RIGHT_OP,removeIncDecOps(copyAst($1)),$3)); break; case AND_ASSIGN: - $$ = newNode('=',$1,newNode('&',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('&',removeIncDecOps(copyAst($1)),$3)); break; case XOR_ASSIGN: - $$ = newNode('=',$1,newNode('^',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('^',removeIncDecOps(copyAst($1)),$3)); break; case OR_ASSIGN: - $$ = newNode('=',$1,newNode('|',copyAst($1),$3)); + $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); break; default : $$ = NULL; @@ -756,11 +767,11 @@ struct_declaration if (!sym->type) { sym->type = copyLinkChain($1); sym->etype = getSpec(sym->type); - /* make sure the type is complete and sane */ - checkTypeSanity(sym->etype, sym->name); } else addDecl (sym,0,cloneSpec($1)); + /* make sure the type is complete and sane */ + checkTypeSanity(sym->etype, sym->name); } $$ = $2; } @@ -777,12 +788,6 @@ struct_declarator_list struct_declarator : declarator - { - // if this was a function declarator, remove the symbol args (if any) - if (IS_FUNC($1->etype)) { - cleanUpLevel(SymbolTab,NestLevel+1); - } - } | ':' constant_expr { $$ = newSymbol (genSymName(NestLevel),NestLevel) ; $$->bitVar = (int) floatFromVal(constExprValue($2,TRUE)); @@ -795,8 +800,8 @@ struct_declarator enum_specifier : ENUM '{' enumerator_list '}' { - addSymChain ($3); - allocVariables(reverseSyms($3)) ; + //addSymChain ($3); + //allocVariables(reverseSyms($3)) ; $$ = copyLinkChain(cenum->type); } | ENUM identifier '{' enumerator_list '}' { @@ -810,8 +815,8 @@ enum_specifier werror(E_DUPLICATE_TYPEDEF,csym->name); addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0); - addSymChain ($4); - allocVariables (reverseSyms($4)); + //addSymChain ($4); + //allocVariables (reverseSyms($4)); $$ = copyLinkChain(cenum->type); SPEC_SCLS(getSpec($$)) = 0 ; } @@ -842,15 +847,17 @@ enumerator_list ; enumerator - : identifier opt_assign_expr { - /* make the symbol one level up */ - $1->level-- ; - $1->type = copyLinkChain($2->type); - $1->etype= getSpec($1->type); - SPEC_ENUM($1->etype) = 1; - $$ = $1 ; - - } + : identifier opt_assign_expr + { + /* make the symbol one level up */ + $1->level-- ; + $1->type = copyLinkChain($2->type); + $1->etype= getSpec($1->type); + SPEC_ENUM($1->etype) = 1; + $$ = $1 ; + // do this now, so we can use it for the next enums in the list + addSymChain($1); + } ; opt_assign_expr @@ -862,28 +869,47 @@ opt_assign_expr } | { if (cenum) { - sprintf(lbuff,"%d",(int) floatFromVal(cenum)+1); + SNPRINTF(lbuff, sizeof(lbuff), + "%d",(int) floatFromVal(cenum)+1); $$ = cenum = constVal(lbuff); } else { - sprintf(lbuff,"%d",0); + SNPRINTF(lbuff, sizeof(lbuff), + "%d",0); $$ = cenum = constVal(lbuff); } } ; declarator - : declarator2_using_reentrant { $$ = $1; } - | pointer declarator2_using_reentrant + : declarator2_function_attributes { $$ = $1; } + | pointer declarator2_function_attributes { addDecl ($2,0,reverseLink($1)); $$ = $2 ; } ; -declarator2_using_reentrant +declarator2_function_attributes : declarator2 { $$ = $1 ; } - | declarator2 using_reentrant { addDecl ($1,0,$2); } + | declarator2 function_attribute { + // copy the functionAttributes (not the args and hasVargs !!) + sym_link *funcType=$1->etype; + struct value *args=FUNC_ARGS(funcType); + unsigned hasVargs=FUNC_HASVARARGS(funcType); + + memcpy (&funcType->funcAttrs, &$2->funcAttrs, + sizeof($2->funcAttrs)); + + FUNC_ARGS(funcType)=args; + FUNC_HASVARARGS(funcType)=hasVargs; + + // just to be sure + memset (&$2->funcAttrs, 0, + sizeof($2->funcAttrs)); + + addDecl ($1,0,$2); + } ; declarator2 @@ -920,13 +946,24 @@ declarator2 addDecl ($1,FUNCTION,NULL) ; - $1->hasVargs = IS_VARG($4); - $1->args = reverseVal($4) ; - + FUNC_HASVARARGS($1->type) = IS_VARG($4); + FUNC_ARGS($1->type) = reverseVal($4); /* nest level was incremented to take care of the parms */ NestLevel-- ; currBlockno--; + + // if this was a pointer (to a function) + if (IS_PTR($1->type)) { + // move the args and hasVargs to the function + FUNC_ARGS($1->etype)=FUNC_ARGS($1->type); + FUNC_HASVARARGS($1->etype)=FUNC_HASVARARGS($1->type); + memset (&$1->type->funcAttrs, 0, + sizeof($1->type->funcAttrs)); + // remove the symbol args (if any) + cleanUpLevel(SymbolTab,NestLevel+1); + } + $$ = $1; } | declarator2 '(' parameter_identifier_list ')' @@ -950,7 +987,7 @@ pointer { $$ = $1 ; $$->next = $2 ; - DCL_TYPE($2)=GPOINTER; + DCL_TYPE($2)=port->unqualified_pointer; } | unqualified_pointer type_specifier_list pointer { @@ -979,7 +1016,9 @@ pointer DCL_TYPE($3) = EEPPOINTER; break; default: - werror(W_PTR_TYPE_INVALID); + // this could be just "constant" + // werror(W_PTR_TYPE_INVALID); + ; } } else @@ -998,7 +1037,20 @@ unqualified_pointer type_specifier_list : type_specifier - | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); } + //| type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); } + | type_specifier_list type_specifier { + /* if the decl $2 is not a specifier */ + /* find the spec and replace it */ + if ( !IS_SPEC($2)) { + sym_link *lnk = $2 ; + while (lnk && !IS_SPEC(lnk->next)) + lnk = lnk->next; + lnk->next = mergeSpec($1,lnk->next, "type_specifier_list"); + $$ = $2 ; + } + else + $$ = mergeSpec($1,$2, "type_specifier_list"); + } ; parameter_identifier_list @@ -1053,9 +1105,13 @@ type_name /* go to the end of the list */ sym_link *p; pointerTypes($2,$1); - for ( p = $2 ; p->next ; p=p->next); - p->next = $1 ; - $$ = $2 ; + for ( p = $2 ; p && p->next ; p=p->next); + if (!p) { + werror(E_SYNTAX_ERROR, yytext); + } else { + p->next = $1 ; + } + $$ = $2 ; } ; @@ -1098,19 +1154,32 @@ abstract_declarator2 // $1 must be a pointer to a function sym_link *p=newLink(); DCL_TYPE(p) = FUNCTION; + if (!$1) { + // ((void (code *) ()) 0) () + $1=newLink(); + DCL_TYPE($1)=CPOINTER; + $$ = $1; + } $1->next=p; } | abstract_declarator2 '(' parameter_type_list ')' { - if (!IS_VOID($3->type)) { + if (!IS_VOID($3->etype)) { // this is nonsense, so let's just burp something werror(E_TOO_FEW_PARMS); } else { // $1 must be a pointer to a function sym_link *p=newLink(); DCL_TYPE(p) = FUNCTION; + if (!$1) { + // ((void (code *) (void)) 0) () + $1=newLink(); + DCL_TYPE($1)=CPOINTER; + $$ = $1; + } $1->next=p; } } + ; initializer : assignment_expr { $$ = newiList(INIT_NODE,$1); } @@ -1132,14 +1201,14 @@ statement | jump_statement | INLINEASM ';' { ast *ex = newNode(INLINEASM,NULL,NULL); - ex->values.inlineasm = Safe_calloc(1,strlen($1)+1); - strcpy(ex->values.inlineasm,$1); + ex->values.inlineasm = strdup($1); $$ = ex; - } + } ; labeled_statement - : identifier ':' statement { $$ = createLabel($1,$3); } +// : identifier ':' statement { $$ = createLabel($1,$3); } + : identifier ':' { $$ = createLabel($1,NULL); } | CASE constant_expr ':' statement { $$ = createCase(STACK_PEEK(swStk),$2,$4); } | DEFAULT ':' statement { $$ = createDefault(STACK_PEEK(swStk),$3); } ; @@ -1226,7 +1295,8 @@ selection_statement ex->values.switchVals.swNum = swLabel ; /* now create the label */ - sprintf(lbuff,"_swBrk_%d",swLabel++); + SNPRINTF(lbuff, sizeof(lbuff), + "_swBrk_%d",swLabel++); $$ = newSymbol(lbuff,NestLevel); /* put label in the break stack */ STACK_PUSH(breakStack,$$); @@ -1242,45 +1312,49 @@ selection_statement while : WHILE { /* create and push the continue , break & body labels */ static int Lblnum = 0 ; /* continue */ - sprintf (lbuff,"_whilecontinue_%d",Lblnum); + SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum); STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel)); /* break */ - sprintf (lbuff,"_whilebreak_%d",Lblnum); + SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum); STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel)); /* body */ - sprintf (lbuff,"_whilebody_%d",Lblnum++); + SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++); $$ = newSymbol(lbuff,NestLevel); } + ; do : DO { /* create and push the continue , break & body Labels */ static int Lblnum = 0 ; /* continue */ - sprintf(lbuff,"_docontinue_%d",Lblnum); + SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum); STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel)); /* break */ - sprintf (lbuff,"_dobreak_%d",Lblnum); + SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum); STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel)); /* do body */ - sprintf (lbuff,"_dobody_%d",Lblnum++); + SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++); $$ = newSymbol (lbuff,NestLevel); } + ; + for : FOR { /* create & push continue, break & body labels */ static int Lblnum = 0 ; /* continue */ - sprintf (lbuff,"_forcontinue_%d",Lblnum); + SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum); STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel)); /* break */ - sprintf (lbuff,"_forbreak_%d",Lblnum); + SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum); STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel)); /* body */ - sprintf (lbuff,"_forbody_%d",Lblnum); + SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum); $$ = newSymbol(lbuff,NestLevel); /* condition */ - sprintf (lbuff,"_forcond_%d",Lblnum++); + SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++); STACK_PUSH(forStack,newSymbol(lbuff,NestLevel)); } + ; iteration_statement : while '(' expr ')' statement