#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;
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 */
}
%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 <yyinline> INLINEASM
%token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
%token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
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);
$$->class = SPECIFIER ;
SPEC_CRTCL($$) = 1;
}
+ | NAKED { $$ = newLink ();
+ $$->class = SPECIFIER ;
+ SPEC_NAKED($$) = 1;
+ }
| NONBANKED {$$ = newLink ();
$$->class = SPECIFIER ;
SPEC_NONBANKED($$) = 1;
;
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
{
$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);}
| 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
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
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
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) ;
/* 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);
/* 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);
| SHORT {
$$=newLink();
$$->class = SPECIFIER ;
- SPEC_LONG($$) = 0 ;
- SPEC_SHORT($$) = 1 ;
+ SPEC_SHORT($$) = 1 ;
}
| INT {
$$=newLink();
| LONG {
$$=newLink();
$$->class = SPECIFIER ;
- SPEC_LONG($$) = 1 ;
- SPEC_SHORT($$) = 0;
+ SPEC_LONG($$) = 1 ;
}
| SIGNED {
$$=newLink();
$$->class = SPECIFIER ;
- SPEC_USIGN($$) = 0 ;
+ SPEC_SIGNED($$) = 1 ;
}
| UNSIGNED {
$$=newLink();
$$->class = SPECIFIER ;
- SPEC_USIGN($$) = 1 ;
+ SPEC_USIGN($$) = 1 ;
}
| VOID {
$$=newLink();
| TYPE_NAME
{
symbol *sym;
- link *p ;
+ sym_link *p ;
sym = findSym(TypedefTab,NULL,$1) ;
$$ = p = copyLinkChain(sym->type);
| '(' declarator ')' { $$ = $2; }
| declarator2 '[' ']'
{
- link *p;
+ sym_link *p;
p = newLink ();
DCL_TYPE(p) = ARRAY ;
}
| declarator2 '[' constant_expr ']'
{
- link *p ;
+ sym_link *p ;
value *tval;
p = (tval = constExprValue($3,TRUE))->etype;
| 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 ;
| 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;
}
jump_statement
: GOTO identifier ';' {
$2->islbl = 1;
- $$ = newAst(EX_VALUE,symbolVal($2));
+ $$ = newAst_VALUE(symbolVal($2));
$$ = newNode(GOTO,$$,NULL);
}
| CONTINUE ';' {
$$ = 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;
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;
}