X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.y;h=7fe71788c8bb5d71c8d135bb40027c4fdace5b91;hb=777749ea16f6ffb540f71c834281e153fc8dc885;hp=5775b3259a6ac96d5a6a1e7c8a66d479b65b1d49;hpb=71def00dac09afdf8dab5093b680cc762bc04b82;p=fw%2Fsdcc diff --git a/src/SDCC.y b/src/SDCC.y index 5775b325..7fe71788 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -31,6 +31,9 @@ #include "SDCCval.h" #include "SDCCmem.h" #include "SDCCast.h" +#include "port.h" +#include "newalloc.h" +#include "SDCCerr.h" extern int yyerror (char *); extern FILE *yyin; @@ -59,11 +62,11 @@ value *cenum = NULL ; /* current enumeration type chain*/ symbol *sym ; /* symbol table pointer */ structdef *sdef; /* structure definition */ char yychar[SDCC_NAME_MAX+1]; - link *lnk ; /* declarator or specifier */ + sym_link *lnk ; /* declarator or specifier */ int yyint; /* integer value returned */ value *val ; /* for integer constant */ initList *ilist; /* initial list */ - char yyinline[MAX_INLINEASM]; /* inlined assembler code */ + char *yyinline; /* inlined assembler code */ ast *asts; /* expression tree */ } @@ -79,7 +82,8 @@ value *cenum = NULL ; /* current enumeration type chain*/ %token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT %token STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM -%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN +%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN +%token NAKED %token INLINEASM %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE @@ -124,6 +128,23 @@ file external_definition : function_definition { blockNo=0;} | declaration { + if ($1 && $1->type + && IS_FUNC($1->type)) + { + /* The only legal storage classes for + * a function prototype (declaration) + * are extern and static. extern is the + * default. Thus, if this function isn't + * explicitly marked static, mark it + * extern. + */ + if ($1->etype + && IS_SPEC($1->etype) + && !SPEC_STAT($1->etype)) + { + SPEC_EXTR($1->etype) = 1; + } + } addSymChain ($1); allocVariables ($1) ; cleanUpLevel (SymbolTab,1); @@ -164,6 +185,10 @@ using_reentrant_interrupt $$->class = SPECIFIER ; SPEC_CRTCL($$) = 1; } + | NAKED { $$ = newLink (); + $$->class = SPECIFIER ; + SPEC_NAKED($$) = 1; + } | NONBANKED {$$ = newLink (); $$->class = SPECIFIER ; SPEC_NONBANKED($$) = 1; @@ -200,14 +225,14 @@ function_body ; primary_expr - : identifier { $$ = newAst(EX_VALUE,symbolVal($1)); } - | CONSTANT { $$ = newAst(EX_VALUE,$1); } + : identifier { $$ = newAst_VALUE(symbolVal($1)); } + | CONSTANT { $$ = newAst_VALUE($1); } | string_literal | '(' expr ')' { $$ = $2 ; } ; string_literal - : STRING_LITERAL { $$ = newAst(EX_VALUE,$1); } + : STRING_LITERAL { $$ = newAst_VALUE($1); } ; postfix_expr @@ -223,14 +248,14 @@ postfix_expr { $3 = newSymbol($3->name,NestLevel); $3->implicit = 1; - $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3))); + $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3))); /* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */ } | postfix_expr PTR_OP identifier { $3 = newSymbol($3->name,NestLevel); $3->implicit = 1; - $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3))); + $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3))); } | postfix_expr INC_OP { $$ = newNode(INC_OP,$1,NULL);} @@ -249,7 +274,7 @@ unary_expr | DEC_OP unary_expr { $$ = newNode(DEC_OP,NULL,$2); } | unary_operator cast_expr { $$ = newNode($1,$2,NULL) ; } | SIZEOF unary_expr { $$ = newNode(SIZEOF,NULL,$2); } - | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); } + | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); } ; unary_operator @@ -263,7 +288,7 @@ unary_operator cast_expr : unary_expr - | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); } + | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); } ; multiplicative_expr @@ -287,41 +312,40 @@ shift_expr relational_expr : shift_expr - | relational_expr '<' shift_expr { $$ = newNode('<',$1,$3); } - | relational_expr '>' shift_expr { $$ = newNode('>',$1,$3); } + | relational_expr '<' shift_expr { + $$ = (port->lt_nge ? + newNode('!',newNode(GE_OP,$1,$3),NULL) : + newNode('<', $1,$3)); + } + | relational_expr '>' shift_expr { + $$ = (port->gt_nle ? + newNode('!',newNode(LE_OP,$1,$3),NULL) : + newNode('>',$1,$3)); + } | relational_expr LE_OP shift_expr { - /* $$ = newNode(LE_OP,$1,$3); */ - /* getting 8051 specific here : will change - LE_OP operation to "not greater than" i.e. - ( a <= b ) === ( ! ( a > b )) */ - $$ = newNode('!', - newNode('>', $1 , $3 ), - NULL); + $$ = (port->le_ngt ? + newNode('!', newNode('>', $1 , $3 ), NULL) : + newNode(LE_OP,$1,$3)); } | relational_expr GE_OP shift_expr { - /* $$ = newNode(GE_OP,$1,$3) ; */ - /* getting 8051 specific here : will change - GE_OP operation to "not less than" i.e. - ( a >= b ) === ( ! ( a < b )) */ - $$ = newNode('!', - newNode('<', $1 , $3 ), - NULL); + $$ = (port->ge_nlt ? + newNode('!', newNode('<', $1 , $3 ), NULL) : + newNode(GE_OP,$1,$3)); } ; equality_expr : relational_expr - | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);} - | equality_expr NE_OP relational_expr - { - /* $$ = newNode(NE_OP,$1,$3); */ - /* NE_OP changed : - expr1 != expr2 is equivalent to - (! expr1 == expr2) */ - $$ = newNode('!', - newNode(EQ_OP,$1,$3), - NULL); - } + | equality_expr EQ_OP relational_expr { + $$ = (port->eq_nne ? + newNode('!',newNode(NE_OP,$1,$3),NULL) : + newNode(EQ_OP,$1,$3)); + } + | equality_expr NE_OP relational_expr { + $$ = (port->ne_neq ? + newNode('!', newNode(EQ_OP,$1,$3), NULL) : + newNode(NE_OP,$1,$3)); + } ; and_expr @@ -437,7 +461,7 @@ declaration symbol *sym , *sym1; for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) { - link *lnk = copyLinkChain($1); + sym_link *lnk = copyLinkChain($1); /* do the pointer stuff */ pointerTypes(sym->type,lnk); addDecl (sym,0,lnk) ; @@ -453,7 +477,7 @@ declaration_specifiers /* if the decl $2 is not a specifier */ /* find the spec and replace it */ if ( !IS_SPEC($2)) { - link *lnk = $2 ; + sym_link *lnk = $2 ; while (lnk && !IS_SPEC(lnk->next)) lnk = lnk->next; lnk->next = mergeSpec($1,lnk->next); @@ -467,7 +491,7 @@ declaration_specifiers /* if the decl $2 is not a specifier */ /* find the spec and replace it */ if ( !IS_SPEC($2)) { - link *lnk = $2 ; + sym_link *lnk = $2 ; while (lnk && !IS_SPEC(lnk->next)) lnk = lnk->next; lnk->next = mergeSpec($1,lnk->next); @@ -541,8 +565,7 @@ type_specifier2 | SHORT { $$=newLink(); $$->class = SPECIFIER ; - SPEC_LONG($$) = 0 ; - SPEC_SHORT($$) = 1 ; + $$->select.s._short = 1 ; } | INT { $$=newLink(); @@ -552,18 +575,17 @@ type_specifier2 | LONG { $$=newLink(); $$->class = SPECIFIER ; - SPEC_LONG($$) = 1 ; - SPEC_SHORT($$) = 0; + SPEC_LONG($$) = 1 ; } | SIGNED { $$=newLink(); $$->class = SPECIFIER ; - SPEC_USIGN($$) = 0 ; + $$->select.s._signed = 1 ; } | UNSIGNED { $$=newLink(); $$->class = SPECIFIER ; - SPEC_USIGN($$) = 1 ; + SPEC_USIGN($$) = 1 ; } | VOID { $$=newLink(); @@ -573,7 +595,7 @@ type_specifier2 | CONST { $$=newLink(); $$->class = SPECIFIER ; - SPEC_SCLS($$) = S_CONSTANT ; + //SPEC_SCLS($$) = S_CONSTANT ; SPEC_CONST($$) = 1; } | VOLATILE { @@ -633,8 +655,7 @@ type_specifier2 | TYPE_NAME { symbol *sym; - link *p ; - + sym_link *p ; sym = findSym(TypedefTab,NULL,$1) ; $$ = p = copyLinkChain(sym->type); SPEC_TYPEDEF(getSpec(p)) = 0; @@ -732,10 +753,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)); - } $$ = $2; } @@ -858,7 +880,7 @@ declarator2 | '(' declarator ')' { $$ = $2; } | declarator2 '[' ']' { - link *p; + sym_link *p; p = newLink (); DCL_TYPE(p) = ARRAY ; @@ -867,7 +889,7 @@ declarator2 } | declarator2 '[' constant_expr ']' { - link *p ; + sym_link *p ; value *tval; p = (tval = constExprValue($3,TRUE))->etype; @@ -899,7 +921,7 @@ declarator2 { werror(E_OLD_STYLE,$1->name) ; - /* assume it returns an it */ + /* assume it returns an int */ $1->type = $1->etype = newIntLink(); $$ = $1 ; } @@ -1029,7 +1051,7 @@ type_name | type_specifier_list abstract_declarator { /* go to the end of the list */ - link *p; + sym_link *p; pointerTypes($2,$1); for ( p = $2 ; p->next ; p=p->next); p->next = $1 ; @@ -1096,7 +1118,7 @@ statement | jump_statement | INLINEASM ';' { ast *ex = newNode(INLINEASM,NULL,NULL); - ALLOC_ATOMIC(ex->values.inlineasm,strlen($1)); + ex->values.inlineasm = Safe_calloc(1,strlen($1)+1); strcpy(ex->values.inlineasm,$1); $$ = ex; } @@ -1298,7 +1320,7 @@ expr_opt jump_statement : GOTO identifier ';' { $2->islbl = 1; - $$ = newAst(EX_VALUE,symbolVal($2)); + $$ = newAst_VALUE(symbolVal($2)); $$ = newNode(GOTO,$$,NULL); } | CONTINUE ';' { @@ -1308,7 +1330,7 @@ jump_statement $$ = NULL; } else { - $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack))); + $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack))); $$ = newNode(GOTO,$$,NULL); /* mark the continue label as referenced */ STACK_PEEK(continueStack)->isref = 1; @@ -1319,7 +1341,7 @@ jump_statement werror(E_BREAK_CONTEXT); $$ = NULL; } else { - $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack))); + $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack))); $$ = newNode(GOTO,$$,NULL); STACK_PEEK(breakStack)->isref = 1; }