Add LIBS to linker command line (needed on Solaris)
[fw/sdcc] / src / SDCC.y
index cfc15ea5b9685ca9aca9756b81d96a634d3c42c2..2127c4e6fae0536afe7621a9a3eb4c4859c6e566 100644 (file)
@@ -66,7 +66,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
     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            */
 }
 
@@ -82,7 +82,8 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
 %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
@@ -166,7 +167,7 @@ function_definition
 
 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
@@ -184,6 +185,10 @@ using_reentrant_interrupt
                         $$->class = SPECIFIER   ;
                         SPEC_CRTCL($$) = 1;
                      }
+   |  NAKED          {  $$ = newLink ();
+                        $$->class = SPECIFIER   ;
+                        SPEC_NAKED($$) = 1;
+                     }
    |  NONBANKED      {$$ = newLink ();
                         $$->class = SPECIFIER   ;
                         SPEC_NONBANKED($$) = 1;
@@ -475,11 +480,11 @@ declaration_specifiers
        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          { 
@@ -489,11 +494,11 @@ declaration_specifiers
        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);
    }
    ;
 
@@ -560,8 +565,7 @@ type_specifier2
    | SHORT  {
                $$=newLink();
                $$->class = SPECIFIER   ;
-               SPEC_LONG($$) = 0      ;
-              SPEC_SHORT($$) = 1        ;
+              $$->select.s._short = 1 ;
             }
    | INT    {
                $$=newLink();
@@ -571,18 +575,17 @@ type_specifier2
    | 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();
@@ -592,7 +595,6 @@ type_specifier2
    | CONST  {
                $$=newLink();
               $$->class = SPECIFIER ;
-              SPEC_SCLS($$) = S_CONSTANT ;
               SPEC_CONST($$) = 1;
             }
    | VOLATILE  {
@@ -653,7 +655,6 @@ type_specifier2
          {
             symbol *sym;
             sym_link   *p  ;
-
             sym = findSym(TypedefTab,NULL,$1) ;
             $$ = p = copyLinkChain(sym->type);
            SPEC_TYPEDEF(getSpec(p)) = 0;
@@ -708,24 +709,23 @@ struct_or_union
    ;
 
 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
@@ -751,10 +751,11 @@ struct_declaration
               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;
        }
@@ -797,7 +798,7 @@ enum_specifier
                                                    (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);
@@ -821,6 +822,8 @@ enum_specifier
 
 enumerator_list
    : enumerator
+   | enumerator_list ',' {
+                         }
    | enumerator_list ',' enumerator {
                                        $3->next = $1 ;
                                        $$ = $3  ;
@@ -918,7 +921,7 @@ declarator2
          {        
           werror(E_OLD_STYLE,$1->name) ;         
           
-          /* assume it returns an it */
+          /* assume it returns an int */
           $1->type = $1->etype = newIntLink();
           $$ = $1 ;
          }
@@ -995,7 +998,7 @@ far_near
 
 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
@@ -1115,7 +1118,7 @@ statement
    | jump_statement
    | INLINEASM  ';'      {
                             ast *ex = newNode(INLINEASM,NULL,NULL);
-                           ex->values.inlineasm = Safe_calloc(strlen($1)+1);
+                           ex->values.inlineasm = Safe_calloc(1,strlen($1)+1);
                            strcpy(ex->values.inlineasm,$1);                        
                            $$ = ex;
                          }