fixed the recent bug that disabled the local structure initialisation.
[fw/sdcc] / src / SDCC.y
index 2127c4e6fae0536afe7621a9a3eb4c4859c6e566..c986486087d90b7750307d6c5c1dbb1154c41bec 100644 (file)
@@ -58,6 +58,8 @@ STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3)
 value *cenum = NULL  ;  /* current enumeration  type chain*/
 
 %}
+%expect 6
+
 %union {
     symbol     *sym ;      /* symbol table pointer       */
     structdef  *sdef;      /* structure definition       */
@@ -81,14 +83,14 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %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
 %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
@@ -101,7 +103,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %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
@@ -747,6 +749,9 @@ 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);
@@ -928,18 +933,18 @@ declarator2
    ;
 
 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 ;
         }
-   | far_near_pointer type_specifier_list pointer
+   | unqualified_pointer type_specifier_list pointer
          {
             $$ = $1 ;               
             if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) {
@@ -961,6 +966,7 @@ pointer
                 case S_CODE:
                     DCL_PTR_CONST($3) = 1;
                     DCL_TYPE($3) = CPOINTER ;
+                    break;
                 case S_EEPROM:
                     DCL_TYPE($3) = EEPPOINTER;
                     break;
@@ -974,28 +980,14 @@ pointer
         }
    ;
 
-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"); }
@@ -1094,9 +1086,23 @@ abstract_declarator2
                                     }
    | '(' ')'                        { $$ = NULL;}
    | '(' parameter_type_list ')'    { $$ = NULL;}   
-   | abstract_declarator2 '(' ')'
-   | abstract_declarator2 '(' parameter_type_list ')'
-   ;
+   | abstract_declarator2 '(' ')' {
+     // $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 (!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;
+     }
+   }
 
 initializer
    : assignment_expr                { $$ = newiList(INIT_NODE,$1); }