fix several 'three operand in far space' problems
[fw/sdcc] / src / SDCC.y
index ab463d4b8debca1c1d618ec91fcf6ae1868e5ff5..98b944db8b945ed14153918536b25597ec1dc461 100644 (file)
@@ -32,6 +32,8 @@
 #include "SDCCmem.h"
 #include "SDCCast.h"
 #include "port.h"
+#include "newalloc.h"
+#include "SDCCerr.h"
 
 extern int yyerror (char *);
 extern FILE    *yyin;
@@ -60,7 +62,7 @@ value *cenum = NULL  ;  /* current enumeration  type chain*/
     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               */
@@ -125,6 +127,23 @@ file
 external_definition
    : function_definition     { blockNo=0;}
    | declaration             { 
+                              if ($1 && $1->type
+                               && IS_FUNC($1->type))
+                              {
+                                  /* The only legal storage classes for 
+                                   * a function prototype (declaration)
+                                   * are extern and static. extern is the
+                                   * default. Thus, if this function isn't
+                                   * explicitly marked static, mark it
+                                   * extern.
+                                   */
+                                  if ($1->etype 
+                                   && IS_SPEC($1->etype)
+                                   && !SPEC_STAT($1->etype))
+                                  {
+                                       SPEC_EXTR($1->etype) = 1;
+                                  }
+                              }
                                addSymChain ($1);
                                allocVariables ($1) ;
                               cleanUpLevel (SymbolTab,1);
@@ -201,14 +220,14 @@ function_body
    ;
 
 primary_expr
-   : identifier      {  $$ = newAst(EX_VALUE,symbolVal($1));  }
-   | CONSTANT        {  $$ = newAst(EX_VALUE,$1);  }
+   : identifier      {  $$ = newAst_VALUE(symbolVal($1));  }
+   | CONSTANT        {  $$ = newAst_VALUE($1);  }
    | string_literal  
    | '(' expr ')'    {  $$ = $2 ;                   }
    ;
          
 string_literal
-    : STRING_LITERAL                   { $$ = newAst(EX_VALUE,$1); }
+    : STRING_LITERAL                   { $$ = newAst_VALUE($1); }
     ;
 
 postfix_expr
@@ -224,14 +243,14 @@ postfix_expr
                      {    
                        $3 = newSymbol($3->name,NestLevel);
                        $3->implicit = 1;
-                       $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst(EX_VALUE,symbolVal($3)));
+                       $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
 /*                     $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ;                   */
                      }
    | postfix_expr PTR_OP identifier    
                       { 
                        $3 = newSymbol($3->name,NestLevel);
                        $3->implicit = 1;                       
-                       $$ = newNode(PTR_OP,$1,newAst(EX_VALUE,symbolVal($3)));
+                       $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
                      }
    | postfix_expr INC_OP   
                       {        $$ = newNode(INC_OP,$1,NULL);}
@@ -250,7 +269,7 @@ unary_expr
    | DEC_OP unary_expr        { $$ = newNode(DEC_OP,NULL,$2);  }
    | unary_operator cast_expr { $$ = newNode($1,$2,NULL)    ;  }
    | SIZEOF unary_expr        { $$ = newNode(SIZEOF,NULL,$2);  }
-   | SIZEOF '(' type_name ')' { $$ = newAst(EX_VALUE,sizeofOp($3)); }
+   | SIZEOF '(' type_name ')' { $$ = newAst_VALUE(sizeofOp($3)); }
    ;
               
 unary_operator
@@ -264,7 +283,7 @@ unary_operator
 
 cast_expr
    : unary_expr
-   | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst(EX_LINK,$2),$4); }
+   | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); }
    ;
 
 multiplicative_expr
@@ -437,7 +456,7 @@ declaration
          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) ;
@@ -453,7 +472,7 @@ 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);
@@ -467,7 +486,7 @@ 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);
@@ -633,7 +652,7 @@ type_specifier2
    | TYPE_NAME    
          {
             symbol *sym;
-            link   *p  ;
+            sym_link   *p  ;
 
             sym = findSym(TypedefTab,NULL,$1) ;
             $$ = p = copyLinkChain(sym->type);
@@ -858,7 +877,7 @@ declarator2
    | '(' declarator ')'     { $$ = $2; }
    | declarator2 '[' ']'
          {
-            link   *p;
+            sym_link   *p;
 
             p = newLink ();
             DCL_TYPE(p) = ARRAY ;
@@ -867,7 +886,7 @@ declarator2
          }
    | declarator2 '[' constant_expr ']'
          {
-            link   *p ;
+            sym_link   *p ;
                        value *tval;
                        
             p = (tval = constExprValue($3,TRUE))->etype;
@@ -1029,7 +1048,7 @@ type_name
    | 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 ;
@@ -1096,7 +1115,7 @@ statement
    | 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;
                          }   
@@ -1298,7 +1317,7 @@ expr_opt
 jump_statement          
    : GOTO identifier ';'   { 
                               $2->islbl = 1;
-                              $$ = newAst(EX_VALUE,symbolVal($2)); 
+                              $$ = newAst_VALUE(symbolVal($2)); 
                               $$ = newNode(GOTO,$$,NULL);
                            }
    | CONTINUE ';'          {  
@@ -1308,7 +1327,7 @@ jump_statement
           $$ = NULL;
        }
        else {
-          $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(continueStack)));      
+          $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack)));      
           $$ = newNode(GOTO,$$,NULL);
           /* mark the continue label as referenced */
           STACK_PEEK(continueStack)->isref = 1;
@@ -1319,7 +1338,7 @@ jump_statement
           werror(E_BREAK_CONTEXT);
           $$ = NULL;
        } else {
-          $$ = newAst(EX_VALUE,symbolVal(STACK_PEEK(breakStack)));
+          $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack)));
           $$ = newNode(GOTO,$$,NULL);
           STACK_PEEK(breakStack)->isref = 1;
        }