X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCC.y;h=a81e243e31054658c253d4ad8be28566e152e8a5;hb=830f8429290c5ab30fe839957c7f62af51f482c9;hp=7f5f7e215ca2ec80f8b437eeb18a65e6c85d2fc2;hpb=3d3fd6633add67fd559ddae48691eb4e92b81903;p=fw%2Fsdcc diff --git a/src/SDCC.y b/src/SDCC.y index 7f5f7e21..a81e243e 100644 --- a/src/SDCC.y +++ b/src/SDCC.y @@ -46,6 +46,7 @@ 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 ; @@ -61,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 @@ -84,18 +87,19 @@ bool uselessDecl = TRUE; %token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN %token XOR_ASSIGN OR_ASSIGN -%token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT -%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 TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR SFR16 SFR32 +%token AT SBIT REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL +%token NONBANKED BANKED SHADOWREGS WPARAM +%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE FIXED16X16 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 JAVANATIVE OVERLAY %token INLINEASM -%token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT +%token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT GETABIT GETBYTE GETWORD %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE %token RRC RLC %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT -%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP +%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP INLINE RESTRICT %type Interrupt_storage %type identifier declarator declarator2 declarator3 enumerator_list enumerator @@ -138,6 +142,7 @@ external_definition blockNo=0; } | declaration { + ignoreTypedefType = 0; if ($1 && $1->type && IS_FUNC($1->type)) { @@ -155,7 +160,7 @@ external_definition SPEC_EXTR($1->etype) = 1; } } - addSymChain ($1); + addSymChain (&$1); allocVariables ($1) ; cleanUpLevel (SymbolTab,1); } @@ -206,6 +211,12 @@ function_attributes werror(W_BANKED_WITH_NONBANKED); } } + | SHADOWREGS {$$ = newLink (SPECIFIER); + FUNC_ISSHADOWREGS($$) = 1; + } + | WPARAM {$$ = newLink (SPECIFIER); + FUNC_ISWPARAM($$) = 1; + } | BANKED {$$ = newLink (SPECIFIER); FUNC_BANKED($$) = 1; if (FUNC_NONBANKED($$)) { @@ -252,18 +263,20 @@ postfix_expr { $$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1; } - | postfix_expr '.' identifier + | postfix_expr '.' { ignoreTypedefType = 1; } identifier { - $3 = newSymbol($3->name,NestLevel); - $3->implicit = 1; - $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3))); -/* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */ + ignoreTypedefType = 0; + $4 = newSymbol($4->name,NestLevel); + $4->implicit = 1; + $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4))); +/* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */ } - | postfix_expr PTR_OP identifier + | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier { - $3 = newSymbol($3->name,NestLevel); - $3->implicit = 1; - $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3))); + ignoreTypedefType = 0; + $4 = newSymbol($4->name,NestLevel); + $4->implicit = 1; + $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4))); } | postfix_expr INC_OP { $$ = newNode(INC_OP,$1,NULL);} @@ -395,7 +408,7 @@ conditional_expr assignment_expr : conditional_expr - | unary_expr assignment_operator assignment_expr + | cast_expr assignment_operator assignment_expr { switch ($2) { @@ -581,54 +594,67 @@ 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)) ; + SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ; } ; type_specifier2 - : CHAR { - $$=newLink(SPECIFIER); - SPEC_NOUN($$) = V_CHAR ; - } - | SHORT { - $$=newLink(SPECIFIER); - $$->select.s._short = 1 ; - } - | INT { - $$=newLink(SPECIFIER); - SPEC_NOUN($$) = V_INT ; - } - | LONG { - $$=newLink(SPECIFIER); - SPEC_LONG($$) = 1 ; - } - | SIGNED { - $$=newLink(SPECIFIER); - $$->select.s._signed = 1; - } + : CHAR { + $$=newLink(SPECIFIER); + SPEC_NOUN($$) = V_CHAR ; + ignoreTypedefType = 1; + } + | SHORT { + $$=newLink(SPECIFIER); + SPEC_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.b_signed = 1; + ignoreTypedefType = 1; + } | UNSIGNED { - $$=newLink(SPECIFIER); - SPEC_USIGN($$) = 1 ; - } - | VOID { - $$=newLink(SPECIFIER); - SPEC_NOUN($$) = V_VOID ; - } - | CONST { - $$=newLink(SPECIFIER); - SPEC_CONST($$) = 1; - } + $$=newLink(SPECIFIER); + SPEC_USIGN($$) = 1 ; + ignoreTypedefType = 1; + } + | VOID { + $$=newLink(SPECIFIER); + SPEC_NOUN($$) = V_VOID ; + ignoreTypedefType = 1; + } + | CONST { + $$=newLink(SPECIFIER); + SPEC_CONST($$) = 1; + } | VOLATILE { - $$=newLink(SPECIFIER); - SPEC_VOLATILE($$) = 1 ; - } - | FLOAT { - $$=newLink(SPECIFIER); - SPEC_NOUN($$) = V_FLOAT; - } + $$=newLink(SPECIFIER); + SPEC_VOLATILE($$) = 1 ; + } + | FLOAT { + $$=newLink(SPECIFIER); + SPEC_NOUN($$) = V_FLOAT; + ignoreTypedefType = 1; + } + | FIXED16X16 { + $$=newLink(SPECIFIER); + SPEC_NOUN($$) = V_FIXED16X16; + ignoreTypedefType = 1; + } | XDATA { $$ = newLink (SPECIFIER); SPEC_SCLS($$) = S_XDATA ; @@ -637,7 +663,7 @@ type_specifier2 $$ = newLink (SPECIFIER) ; SPEC_SCLS($$) = S_CODE ; } - | EEPROM { + | EEPROM { $$ = newLink (SPECIFIER) ; SPEC_SCLS($$) = S_EEPROM ; } @@ -653,21 +679,24 @@ type_specifier2 $$ = newLink (SPECIFIER); SPEC_SCLS($$) = S_PDATA ; } - | BIT { - $$=newLink(SPECIFIER); - SPEC_NOUN($$) = V_BIT ; - SPEC_SCLS($$) = S_BIT ; - SPEC_BLEN($$) = 1; - SPEC_BSTR($$) = 0; - } + | BIT { + $$=newLink(SPECIFIER); + SPEC_NOUN($$) = V_BIT ; + 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,7 +705,8 @@ type_specifier2 sym_link *p ; sym = findSym(TypedefTab,NULL,$1) ; $$ = p = copyLinkChain(sym->type); - SPEC_TYPEDEF(getSpec(p)) = 0; + SPEC_TYPEDEF(getSpec(p)) = 0; + ignoreTypedefType = 1; } | sfr_reg_bit ; @@ -686,6 +716,9 @@ sfr_reg_bit $$ = newLink(SPECIFIER) ; SPEC_NOUN($$) = V_SBIT; SPEC_SCLS($$) = S_SBIT; + SPEC_BLEN($$) = 1; + SPEC_BSTR($$) = 0; + ignoreTypedefType = 1; } | sfr_attributes ; @@ -697,6 +730,7 @@ sfr_attributes SPEC_NOUN($$) = V_CHAR; SPEC_SCLS($$) = S_SFR ; SPEC_USIGN($$) = 1 ; + ignoreTypedefType = 1; } | SFR BANKED { $$ = newLink(SPECIFIER) ; @@ -704,38 +738,78 @@ sfr_attributes SPEC_NOUN($$) = V_CHAR; SPEC_SCLS($$) = S_SFR ; SPEC_USIGN($$) = 1 ; + ignoreTypedefType = 1; + } + ; + +sfr_attributes + : SFR16 { + $$ = newLink(SPECIFIER) ; + FUNC_REGBANK($$) = 0; + SPEC_NOUN($$) = V_INT; + SPEC_SCLS($$) = S_SFR; + SPEC_USIGN($$) = 1 ; + ignoreTypedefType = 1; + } + ; + +sfr_attributes + : SFR32 { + $$ = newLink(SPECIFIER) ; + FUNC_REGBANK($$) = 0; + SPEC_NOUN($$) = V_INT; + SPEC_SCLS($$) = S_SFR; + SPEC_LONG($$) = 1; + 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'"); + werrorfl(sym->fileDef, 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"); + werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class"); + printTypeChainRaw (sym->type,NULL); SPEC_SCLS(sym->etype) = 0; } for (dsym=sym->next; dsym; dsym=dsym->next) { - if (strcmp(sym->name, dsym->name)==0) { - werrorfl(filename, sym->lineDef, E_DUPLICATE_MEMBER, + if (*dsym->name && strcmp(sym->name, dsym->name)==0) { + werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER, $1==STRUCT ? "struct" : "union", sym->name); + werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF); } } } /* 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 */ - + promoteAnonStructs ($1, sdef); + /* Create the specifier */ $$ = newLink (SPECIFIER) ; SPEC_NOUN($$) = V_STRUCT; @@ -745,7 +819,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"); + } } ; @@ -808,7 +892,8 @@ struct_declaration /* make sure the type is complete and sane */ checkTypeSanity(sym->etype, sym->name); } - $$ = $2; + ignoreTypedefType = 0; + $$ = $2; } ; @@ -851,45 +936,35 @@ struct_declarator else $1->bitVar = bitsize; } + | { $$ = newSymbol ("", NestLevel) ; } + ; 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($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF,csym->name); + werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF); + } - $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 ; @@ -901,8 +976,6 @@ enum_specifier $$ = newLink(SPECIFIER) ; SPEC_NOUN($$) = V_INT ; } - - SPEC_SCLS(getSpec($$)) = 0 ; } ; @@ -910,10 +983,22 @@ 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($3->fileDef, $3->lineDef, E_DUPLICATE_MEMBER, "enum", $3->name); + werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF); + } + } + + $3->next = $1 ; + $$ = $3 ; + } ; enumerator @@ -926,15 +1011,22 @@ enumerator SPEC_ENUM($1->etype) = 1; $$ = $1 ; // do this now, so we can use it for the next enums in the list - addSymChain($1); + addSymChain(&$1); } ; 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 ; } | { @@ -978,21 +1070,32 @@ declarator2_function_attributes : function_declarator2 { $$ = $1 ; } | function_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)); + struct value *args; + unsigned hasVargs; + sym_link *funcType=$1->type; - FUNC_ARGS(funcType)=args; - FUNC_HASVARARGS(funcType)=hasVargs; - - // just to be sure - memset (&$2->funcAttrs, 0, - sizeof($2->funcAttrs)); + while (funcType && !IS_FUNC(funcType)) + funcType = funcType->next; + + if (!funcType) + werror (E_FUNC_ATTR); + else + { + args=FUNC_ARGS(funcType); + 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); + addDecl ($1,0,$2); + } } ; @@ -1032,28 +1135,29 @@ declarator2 function_declarator2 : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; } - | declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')' + | declarator2 '(' { NestLevel++ ; currBlockno++; } + parameter_type_list ')' { + sym_link *funcType; addDecl ($1,FUNCTION,NULL) ; + + funcType = $1->type; + while (funcType && !IS_FUNC(funcType)) + funcType = funcType->next; - FUNC_HASVARARGS($1->type) = IS_VARG($4); - FUNC_ARGS($1->type) = reverseVal($4); + assert (funcType); + + FUNC_HASVARARGS(funcType) = IS_VARG($4); + FUNC_ARGS(funcType) = 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) + if (!IS_FUNC($1->type)) cleanUpLevel(SymbolTab,NestLevel+1); - } $$ = $1; } @@ -1168,11 +1272,11 @@ parameter_type_list ; parameter_list - : parameter_declaration + : parameter_declaration | parameter_list ',' parameter_declaration { $3->next = $1 ; - $$ = $3 ; + $$ = $3 ; } ; @@ -1183,18 +1287,20 @@ parameter_declaration pointerTypes($2->type,$1); addDecl ($2,0,$1); for (loop=$2;loop;loop->_isparm=1,loop=loop->next); - addSymChain ($2); + 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 */ @@ -1207,6 +1313,7 @@ type_name p->next = $1 ; } $$ = $2 ; + ignoreTypedefType = 0; } ; @@ -1327,24 +1434,30 @@ critical_statement labeled_statement // : identifier ':' statement { $$ = createLabel($1,$3); } - : identifier ':' { $$ = createLabel($1,NULL); } - | CASE constant_expr ':' statement + : identifier ':' { $$ = createLabel($1,NULL); + $1->isitmp = 0; } + | CASE constant_expr ':' { if (STACK_EMPTY(swStk)) - $$ = createCase(NULL,$2,$4); + $$ = createCase(NULL,$2,NULL); else - $$ = createCase(STACK_PEEK(swStk),$2,$4); + $$ = createCase(STACK_PEEK(swStk),$2,NULL); } - | DEFAULT { $$ = newNode(DEFAULT,NULL,NULL); } ':' statement + | DEFAULT { $$ = newNode(DEFAULT,NULL,NULL); } ':' { if (STACK_EMPTY(swStk)) - $$ = createDefault(NULL,$2,$4); + $$ = createDefault(NULL,$2,NULL); else - $$ = createDefault(STACK_PEEK(swStk),$2,$4); + $$ = createDefault(STACK_PEEK(swStk),$2,NULL); } ; -start_block : '{' { STACK_PUSH(blockNum,currBlockno); currBlockno = ++blockNo ; } +start_block : '{' + { + STACK_PUSH(blockNum,currBlockno); + currBlockno = ++blockNo ; + ignoreTypedefType = 0; + } ; end_block : '}' { currBlockno = STACK_POP(blockNum); } @@ -1354,10 +1467,10 @@ compound_statement : start_block end_block { $$ = createBlock(NULL,NULL); } | start_block statement_list end_block { $$ = createBlock(NULL,$2) ; } | start_block - declaration_list { addSymChain($2); } + declaration_list { addSymChain(&$2); } end_block { $$ = createBlock($2,NULL) ; } | start_block - declaration_list { addSymChain ($2); } + declaration_list { addSymChain (&$2); } statement_list end_block {$$ = createBlock($2,$4) ; } | error ';' { $$ = NULL ; } @@ -1373,6 +1486,7 @@ declaration_list } else $$ = $1 ; + ignoreTypedefType = 0; } | declaration_list declaration @@ -1395,6 +1509,7 @@ declaration_list else $$ = $2 ; } + ignoreTypedefType = 0; } ;