%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 STRUCT UNION ENUM ELIPSIS RANGE FAR _XDATA _CODE _GENERIC _NEAR _PDATA _IDATA _EEPROM
+%token STRUCT UNION ENUM ELIPSIS RANGE FAR
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
%token NAKED
%token <yyinline> INLINEASM
%type <lnk> storage_class_specifier struct_or_union_specifier
%type <lnk> declaration_specifiers sfr_reg_bit type_specifier2
%type <lnk> using_reentrant using_reentrant_interrupt enum_specifier
-%type <lnk> abstract_declarator abstract_declarator2 far_near_pointer far_near
+%type <lnk> abstract_declarator abstract_declarator2 unqualified_pointer
%type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr
%type <sdef> stag opt_stag
%type <asts> primary_expr
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;
}
;
struct_declarator
- : declarator
+ : declarator
| ':' constant_expr {
$$ = newSymbol (genSymName(NestLevel),NestLevel) ;
$$->bitVar = (int) floatFromVal(constExprValue($2,TRUE));
$1->hasVargs = IS_VARG($4);
$1->args = reverseVal($4) ;
+
/* nest level was incremented to take care of the parms */
NestLevel-- ;
currBlockno--;
+
+ // if this was a pointer to a function, remove the symbol args
+ // (if any)
+ if (IS_PTR($1->type) && IS_FUNC($1->etype)) {
+ cleanUpLevel(SymbolTab,NestLevel+1);
+ /* fprintf (stderr, "Removed parm symbols of %s in line %d\n",
+ $1->name, yylineno); */
+ }
+
$$ = $1;
}
| declarator2 '(' parameter_identifier_list ')'
;
pointer
- : far_near_pointer { $$ = $1 ;}
- | far_near_pointer type_specifier_list
+ : unqualified_pointer { $$ = $1 ;}
+ | unqualified_pointer type_specifier_list
{
$$ = $1 ;
DCL_TSPEC($1) = $2;
}
- | far_near_pointer pointer
+ | unqualified_pointer pointer
{
$$ = $1 ;
$$->next = $2 ;
+ DCL_TYPE($2)=GPOINTER;
}
- | far_near_pointer type_specifier_list pointer
+ | unqualified_pointer type_specifier_list pointer
{
$$ = $1 ;
if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
case S_CODE:
DCL_PTR_CONST($3) = 1;
DCL_TYPE($3) = CPOINTER ;
+ break;
case S_EEPROM:
DCL_TYPE($3) = EEPPOINTER;
break;
}
;
-far_near_pointer
- : far_near '*' {
- if ($1 == NULL) {
- $$ = newLink();
- DCL_TYPE($$) = POINTER ;
- }
- else
- $$ = $1 ;
+unqualified_pointer
+ : '*'
+ {
+ $$ = newLink();
+ DCL_TYPE($$)=UPOINTER;
}
;
-far_near
- : _XDATA { $$ = newLink() ; DCL_TYPE($$) = FPOINTER ; }
- | _CODE { $$ = newLink() ; DCL_TYPE($$) = CPOINTER ; DCL_PTR_CONST($$) = 1;}
- | _PDATA { $$ = newLink() ; DCL_TYPE($$) = PPOINTER ; }
- | _IDATA { $$ = newLink() ; DCL_TYPE($$) = IPOINTER ; }
- | _NEAR { $$ = NULL ; }
- | _GENERIC { $$ = newLink() ; DCL_TYPE($$) = GPOINTER ; }
- | _EEPROM { $$ = newLink() ; DCL_TYPE($$) = EEPPOINTER ;}
- | { $$ = newLink() ; DCL_TYPE($$) = UPOINTER ; }
- ;
-
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
| '(' ')' { $$ = NULL;}
| '(' parameter_type_list ')' { $$ = NULL;}
| abstract_declarator2 '(' ')' {
- if (getenv("DONT_IGNORE_FUNCTION_SPECIFIERS")) {
- // this was previously ignored (cvs < 1.37)
- // but $1 must be a pointer that points to a function
- sym_link *p=newLink();
- DCL_TYPE(p) = FUNCTION;
- $1->next=p;
- }
+ // $1 must be a pointer to a function
+ sym_link *p=newLink();
+ DCL_TYPE(p) = FUNCTION;
+ $1->next=p;
}
| abstract_declarator2 '(' parameter_type_list ')' {
- if (getenv("DONT_IGNORE_FUNCTION_SPECIFIERS")) {
- // this was previously ignored (cvs < 1.37)
+ if (!IS_VOID($3->type)) {
// 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;
+ $1->next=p;
}
}
| jump_statement
| INLINEASM ';' {
ast *ex = newNode(INLINEASM,NULL,NULL);
- ex->values.inlineasm = Safe_calloc(1,strlen($1)+1);
+ ex->values.inlineasm = malloc(strlen($1)+1);
strcpy(ex->values.inlineasm,$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); }
;