#include "SDCCmem.h"
#include "SDCCast.h"
#include "port.h"
+#include "newalloc.h"
+#include "SDCCerr.h"
extern int yyerror (char *);
extern FILE *yyin;
value *cenum = NULL ; /* current enumeration type chain*/
%}
+%expect 6
+
%union {
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
%token RRC RLC
-%token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND
+%token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
%type <yyint> Interrupt_storage
%type <sym> identifier declarator declarator2 enumerator_list enumerator
using_reentrant
: using_reentrant_interrupt
- | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2); }
+ | using_reentrant_interrupt using_reentrant { $$ = mergeSpec($1,$2,"using_reentrant"); }
;
using_reentrant_interrupt
$$->class = SPECIFIER ;
SPEC_CRTCL($$) = 1;
}
+ | NAKED { $$ = newLink ();
+ $$->class = SPECIFIER ;
+ SPEC_NAKED($$) = 1;
+ }
| NONBANKED {$$ = newLink ();
$$->class = SPECIFIER ;
SPEC_NONBANKED($$) = 1;
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);
+ lnk->next = mergeSpec($1,lnk->next, yytext);
$$ = $2 ;
}
else
- $$ = mergeSpec($1,$2);
+ $$ = mergeSpec($1,$2, yytext);
}
| type_specifier { $$ = $1; }
| type_specifier 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);
+ lnk->next = mergeSpec($1,lnk->next, yytext);
$$ = $2 ;
}
else
- $$ = mergeSpec($1,$2);
+ $$ = mergeSpec($1,$2, yytext);
}
;
| SHORT {
$$=newLink();
$$->class = SPECIFIER ;
- SPEC_LONG($$) = 0 ;
- SPEC_SHORT($$) = 1 ;
+ $$->select.s._short = 1 ;
}
| INT {
$$=newLink();
| 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();
| CONST {
$$=newLink();
$$->class = SPECIFIER ;
- SPEC_SCLS($$) = S_CONSTANT ;
SPEC_CONST($$) = 1;
}
| VOLATILE {
| TYPE_NAME
{
symbol *sym;
- link *p ;
-
+ sym_link *p ;
sym = findSym(TypedefTab,NULL,$1) ;
$$ = p = copyLinkChain(sym->type);
SPEC_TYPEDEF(getSpec(p)) = 0;
;
opt_stag
- : stag
- | { /* synthesize a name add to structtable */
- $$ = newStruct(genSymName(NestLevel)) ;
- $$->level = NestLevel ;
- addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
- }
- ;
+: stag
+| { /* synthesize a name add to structtable */
+ $$ = newStruct(genSymName(NestLevel)) ;
+ $$->level = NestLevel ;
+ addSym (StructTab, $$, $$->tag,$$->level,currBlockno, 0);
+};
stag
- : identifier { /* add name to structure table */
- $$ = findSymWithBlock (StructTab,$1,currBlockno);
- if (! $$ ) {
- $$ = newStruct($1->name) ;
- $$->level = NestLevel ;
- addSym (StructTab, $$, $$->tag,$$->level,currBlockno) ;
- }
- }
- ;
+: identifier { /* add name to structure table */
+ $$ = findSymWithBlock (StructTab,$1,currBlockno);
+ if (! $$ ) {
+ $$ = newStruct($1->name) ;
+ $$->level = NestLevel ;
+ addSym (StructTab, $$, $$->tag,$$->level,currBlockno,0);
+ }
+};
+
struct_declaration_list
: struct_declaration
symbol *sym ;
for ( sym = $2 ; sym != NULL ; sym = sym->next ) {
+ /* make the symbol one level up */
+ sym->level-- ;
+
pointerTypes(sym->type,copyLinkChain($1));
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;
}
(csym && csym->level == $2->level))
werror(E_DUPLICATE_TYPEDEF,csym->name);
- addSym ( enumTab,$2,$2->name,$2->level,$2->block);
+ addSym ( enumTab,$2,$2->name,$2->level,$2->block, 0);
addSymChain ($4);
allocVariables (reverseSyms($4));
$$ = copyLinkChain(cenum->type);
enumerator_list
: enumerator
+ | enumerator_list ',' {
+ }
| enumerator_list ',' enumerator {
$3->next = $1 ;
$$ = $3 ;
| '(' 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;
{
werror(E_OLD_STYLE,$1->name) ;
- /* assume it returns an it */
+ /* assume it returns an int */
$1->type = $1->etype = newIntLink();
$$ = $1 ;
}
type_specifier_list
: type_specifier
- | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2); }
+ | type_specifier_list type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); }
;
parameter_identifier_list
| 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;
}