Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / src / SDCCast.h
index 8c2ca1622d9ca8efde0b375167c532a21a45ca35..17a21d1e296fc4c661d4c45172a669fe1af2ec0a 100644 (file)
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
+#ifndef SDCCEXPR_H
+#define SDCCEXPR_H
+
 #include "SDCCglobl.h"
 #include "SDCCsymt.h"
 #include "SDCCval.h"
+#include "SDCCset.h"
+#include "SDCCmem.h"
 
-#ifndef SDCCEXPR_H
-#define SDCCEXPR_H
-
-#define  EX_OP       0
-#define  EX_VALUE    1
-#define  EX_LINK     2
-#define  EX_STMNT    3
-#define  EX_OPERAND  4
+typedef enum {
+  EX_OP=0,
+  EX_VALUE,
+  EX_LINK,
+  EX_OPERAND
+} ASTTYPE;
 
 /* expression tree   */
-typedef  struct   ast {
-
-    unsigned  type     :3       ;  
-    unsigned  decorated   :1     ;
-    unsigned  hasVargs    :1     ;
-    unsigned  isError     :1     ;
-    unsigned  funcName    :1     ;
-    unsigned  rvalue      :1     ;
-    unsigned  lvalue      :1     ;
-    unsigned  initMode    :1     ;
-    int       level       ;  /* level for expr */
-    int       block       ;  /* block number   */
+typedef struct ast
+  {
+
+    ASTTYPE type;
+    unsigned decorated:1;
+    unsigned isError:1;
+    unsigned funcName:1;
+    unsigned rvalue:1;
+    unsigned lvalue:1;
+    unsigned initMode:1;
+    unsigned reversed:1;
+    int level;                  /* level for expr */
+    int block;                  /* block number   */
+    int seqPoint;               /* sequence point */
     /* union of values expression can have */
-    union {
-       value *val        ;  /* value if type = EX_VALUE */
-       link  *lnk        ;  /* link * if type= EX_LINK  */
-       struct operand *oprnd; /* used only for side effecting function calls */
-       unsigned stmnt    ;  /* statement if type=EX_STMNT */
-       unsigned op       ;  /* operator if type= EX_OP  */
-    } opval ;
-    
+    union
+      {
+        value *val;             /* value if type = EX_VALUE */
+        sym_link *lnk;          /* sym_link * if type= EX_LINK  */
+        struct operand *oprnd;  /* used only for side effecting function calls */
+        unsigned op;            /* operator if type= EX_OP  */
+      }
+    opval;
+
     /* union for special processing */
-    union {
-       char     *inlineasm  ;  /* pointer to inline assembler code */
-       symbol   *sym        ;  /* if block then -> symbols */      
-       value    *args       ;  /* if function then args    */
-       /* if switch then switch values */
-       struct {
-           value    *swVals     ;  /* switch comparison values */
-           int      swDefault   ;  /* default if present       */
-           int      swNum       ;  /* switch number            */
-       } switchVals   ;
-       /* if for then for values */
-       struct {
-           struct ast *initExpr ;    /* init portion */
-           struct ast *condExpr ;    /* conditional portion */
-           struct ast *loopExpr ;    /* iteration portion   */
-           symbol   *trueLabel;      /* entry point into body */
-           symbol   *falseLabel;     /* exit point */
-           symbol   *continueLabel;  /* conditional check   */
-           symbol   *condLabel;      /* conditional label   */
-       } forVals ;
-    } values ;
-    
-    int   lineno         ;  /* source file line number     */   
-    char  *filename      ;  /* filename of the source file */
-    
-    link  *ftype         ;  /* start of type chain for this subtree */
-    link  *etype         ;  /* end of type chain for this subtree   */
-    
-    symbol  *argSym      ;  /* argument symbols            */
-    value   *args        ;  /* args of a function          */
-    struct  ast   *left ;  /* pointer to left tree        */
-    struct  ast   *right;  /* pointer to right tree       */
-    symbol   *trueLabel  ;  /* if statement trueLabel */
-    symbol   *falseLabel ;  /* if statement falseLabel */
-} ast ;
+    union
+      {
+        char *inlineasm;        /* pointer to inline assembler code */
+        literalList *constlist; /* init list for array initializer. */
+        symbol *sym;            /* if block then -> symbols */
+        value *args;            /* if function then args    */
+        /* if switch then switch values */
+        struct
+          {
+            value *swVals;      /* switch comparison values */
+            int swDefault;      /* default if present       */
+            int swNum;          /* switch number            */
+          }
+        switchVals;
+        /* if for then for values */
+        struct
+          {
+            struct ast *initExpr;       /* init portion */
+            struct ast *condExpr;       /* conditional portion */
+            struct ast *loopExpr;       /* iteration portion   */
+            symbol *trueLabel;          /* entry point into body */
+            symbol *falseLabel;         /* exit point */
+            symbol *continueLabel;      /* conditional check   */
+            symbol *condLabel;          /* conditional label   */
+          }
+        forVals;
+        struct
+          {
+            unsigned literalFromCast:1; /* true if this is an EX_VALUE of LITERAL
+                                         * type resulting from a typecast.
+                                         */
+            unsigned removedCast:1;     /* true if the explicit cast has been removed */
+          };
+        int argreg;                     /* argreg number when operand type == EX_OPERAND */
+      }
+    values;
+
+    int lineno;                 /* source file line number     */
+    char *filename;             /* filename of the source file */
+
+    sym_link *ftype;            /* start of type chain for this subtree */
+    sym_link *etype;            /* end of type chain for this subtree   */
+
+    struct ast *left;           /* pointer to left tree        */
+    struct ast *right;          /* pointer to right tree       */
+    symbol *trueLabel;          /* if statement trueLabel */
+    symbol *falseLabel;         /* if statement falseLabel */
+  }
+ast;
 
 
 /* easy access macros   */
-#define  IS_AST_OP(x)                  (x && x->type == EX_OP)
-#define IS_BITOR(x) (IS_AST_OP(x) && x->opval.op == '|')
-#define IS_BITAND(x) (IS_AST_OP(x) && x->opval.op == '&' && \
-                     x->left && x->right )
-#define IS_FOR_STMT(x) (IS_AST_OP(x) && x->opval.op == FOR)
-#define IS_LEFT_OP(x) (IS_AST_OP(x) && x->opval.op == LEFT_OP)
-#define IS_RIGHT_OP(x) (IS_AST_OP(x) && x->opval.op == RIGHT_OP)
-#define  IS_AST_VALUE(x)       (x && x->type == EX_VALUE && x->opval.val)
-#define  IS_AST_LINK(x)                (x->type == EX_LINK)   
-#define  IS_AST_NOT_OPER(x)    (x && IS_AST_OP(x) && x->opval.op == '!')
-#define  IS_COMPARE_OP(x)      (IS_AST_OP(x)           &&              \
-                                 (x->opval.op == '>'   ||              \
-                                  x->opval.op == '<'   ||              \
-                                  x->opval.op == LE_OP ||              \
-                                  x->opval.op == GE_OP ||              \
-                                  x->opval.op == EQ_OP ||              \
-                                  x->opval.op == NE_OP ))
-#define IS_CAST_OP(x) (IS_AST_OP(x) && x->opval.op == CAST)
-#define IS_ADDRESS_OF_OP(x)    (IS_AST_OP(x)            &&              \
-                               x->opval.op == '&'      &&              \
-                               x->right == NULL )
-#define IS_AST_LIT_VALUE(x) (IS_AST_VALUE(x) && \
-                             IS_LITERAL(x->opval.val->etype))
-#define IS_AST_SYM_VALUE(x)     (IS_AST_VALUE(x) && x->opval.val->sym)
-#define AST_LIT_VALUE(x)        (floatFromVal(x->opval.val))
-#define AST_SYMBOL(x)           (x->opval.val->sym)
-#define AST_VALUE(x)            (x->opval.val)
-#define AST_VALUES(x,y)        (x->values.y)
-#define AST_FOR(x,y) x->values.forVals.y
-
-#define  CAN_EVAL(x)   (     x ==  '[' || x == '.' || x == PTR_OP ||   \
-             x ==  '&' || x == '|' || x == '^'    || x == '*' || \
-             x ==  '-' || x == '+' || x == '~'    ||   \
-             x ==  '!' || x == LEFT_OP || x == RIGHT_OP ||       \
-             x ==  '/' || x == '%' || x == '>' || x == '<'    || \
-              x        == LE_OP || x == GE_OP || x == EQ_OP || x == NE_OP || \
-             x == AND_OP || x == OR_OP || x == '='  )
-
-#define         LEFT_FIRST(x) ( x  ==  AND_OP  ||      x       ==      OR_OP   )
-
-#define SIDE_EFFECTS_CHECK(op,rVal)  if (!sideEffects) {               \
-                                        werror(W_NO_SIDE_EFFECTS,op);  \
-                                        return rVal    ;               \
-                                    }
-#define IS_MODIFYING_OP(x) ( x == INC_OP || x == DEC_OP || x == '=' ||  \
-                       x == AND_ASSIGN || x== OR_ASSIGN || x == XOR_ASSIGN )
-
-#define IS_ASSIGN_OP(x) ( x == '=' || x == ADD_ASSIGN || x == SUB_ASSIGN ||\
-                         x == MUL_ASSIGN || x == DIV_ASSIGN || x == XOR_ASSIGN ||\
-                         x == AND_ASSIGN || x == OR_ASSIGN)
-#define IS_DEREF_OP(x) (( x->opval.op == '*' && x->right == NULL) || x->opval.op == '.')
-
-/* forward declrations for global variables */
-extern ast     *staticAutos    ;
+#define IS_AST_OP(x)            ((x) && (x)->type == EX_OP)
+#define IS_CALLOP(x)            (IS_AST_OP(x) && (x)->opval.op == CALL)
+#define IS_BITOR(x)             (IS_AST_OP(x) && (x)->opval.op == '|')
+#define IS_BITAND(x)            (IS_AST_OP(x) && (x)->opval.op == '&' && \
+                                 (x)->left && (x)->right )
+#define IS_FOR_STMT(x)          (IS_AST_OP(x) && (x)->opval.op == FOR)
+#define IS_LEFT_OP(x)           (IS_AST_OP(x) && (x)->opval.op == LEFT_OP)
+#define IS_RIGHT_OP(x)          (IS_AST_OP(x) && (x)->opval.op == RIGHT_OP)
+#define IS_AST_VALUE(x)         ((x) && (x)->type == EX_VALUE && (x)->opval.val)
+#define IS_AST_LINK(x)          ((x)->type == EX_LINK)
+#define IS_AST_NOT_OPER(x)      (x && IS_AST_OP(x) && (x)->opval.op == '!')
+#define IS_ARRAY_OP(x)          (IS_AST_OP(x) && (x)->opval.op == '[')
+#define IS_COMPARE_OP(x)        (IS_AST_OP(x)           &&              \
+                                  ((x)->opval.op == '>'   ||            \
+                                   (x)->opval.op == '<'   ||            \
+                                   (x)->opval.op == LE_OP ||            \
+                                   (x)->opval.op == GE_OP ||            \
+                                   (x)->opval.op == EQ_OP ||            \
+                                   (x)->opval.op == NE_OP ))
+#define IS_CAST_OP(x)           (IS_AST_OP(x) && (x)->opval.op == CAST)
+#define IS_TERNARY_OP(x)        (IS_AST_OP(x) && (x)->opval.op == '?')
+#define IS_COLON_OP(x)          (IS_AST_OP(x) && (x)->opval.op == ':')
+#define IS_ADDRESS_OF_OP(x)     (IS_AST_OP(x)            &&             \
+                                 (x)->opval.op == '&'      &&           \
+                                 (x)->right == NULL )
+#define IS_AST_LIT_VALUE(x)     (IS_AST_VALUE(x) && \
+                                 IS_LITERAL((x)->opval.val->etype))
+#define IS_AST_SYM_VALUE(x)     (IS_AST_VALUE(x) && (x)->opval.val->sym)
+#define AST_FLOAT_VALUE(x)      (floatFromVal((x)->opval.val))
+#define AST_ULONG_VALUE(x)      (ulFromVal((x)->opval.val))
+#define AST_SYMBOL(x)           ((x)->opval.val->sym)
+#define AST_VALUE(x)            ((x)->opval.val)
+#define AST_VALUES(x,y)         ((x)->values.y)
+#define AST_FOR(x,y)            ((x)->values.forVals.y)
+#define AST_ARGREG(x)           ((x)->values.argreg)
+
+#define IS_AST_PARAM(x)         (IS_AST_OP(x) && (x)->opval.op == PARAM)
+
+#define  CAN_EVAL(x)    (      (x) == '['     || (x) == '.'      || (x) == PTR_OP || \
+              (x) ==  '&'   || (x) == '|'     || (x) == '^'      || (x) == '*'    || \
+              (x) ==  '-'   || (x) == '+'     || (x) == '~'      ||                  \
+              (x) ==  '!'   || (x) == LEFT_OP || (x) == RIGHT_OP ||                  \
+              (x) ==  '/'   || (x) == '%'     || (x) == '>'      || (x) == '<'    || \
+              (x) == LE_OP  || (x) == GE_OP   || (x) == EQ_OP    || (x) == NE_OP  || \
+              (x) == AND_OP || (x) == OR_OP   || (x) == '='  )
+
+#define  LEFT_FIRST(x) ( x  ==  AND_OP  ||      x       ==      OR_OP   )
+
+#define SIDE_EFFECTS_CHECK(op,rVal)  if (!sideEffects)  {               \
+                                         werror(W_NO_SIDE_EFFECTS,op);  \
+                                         return rVal    ;               \
+                                     }
+#define IS_MODIFYING_OP(x) ( (x) == INC_OP || (x) == DEC_OP || (x) == '=' ||  \
+                        (x) == AND_ASSIGN || x== OR_ASSIGN || (x) == XOR_ASSIGN )
+
+#define IS_ASSIGN_OP(x) ( (x) == '=' || (x) == ADD_ASSIGN || (x) == SUB_ASSIGN ||\
+                          (x) == MUL_ASSIGN || (x) == DIV_ASSIGN || (x) == XOR_ASSIGN ||\
+                          (x) == AND_ASSIGN || (x) == OR_ASSIGN || (x) == INC_OP || (x) == DEC_OP)
+#define IS_DEREF_OP(x) (( (x)->opval.op == '*' && (x)->right == NULL) || (x)->opval.op == '.')
+
+/* forward declarations for global variables */
+extern ast *staticAutos;
+extern struct dbuf_s *codeOutBuf;
+extern struct memmap *GcurMemmap;
 
 /* forward definitions for functions   */
-ast     *newAst       (int  ,  void  *        );
-void      initAst      (                       );
-ast     *newNode       (int  ,ast *  ,ast *  );
-ast     *copyAst      (ast *                 );
-value    *sizeofOp      (link *                 );
-value    *evalStmnt     (ast *                 );
-ast     *createFunction(symbol  *,ast   *     );
-ast     *createBlock   (symbol  *,ast   *     );
-ast     *createLabel   (symbol  *,ast   *     );
-ast     *createCase    (ast    *,ast   *,ast   *);
-ast     *createDefault (ast    *,ast   *     );
-ast     *optimizeCompare (ast   *                              );
-ast     *forLoopOptForm( ast    *                              );
-ast     *argAst                ( ast    *                              );
-ast     *resolveSymbols (ast *) ;
-ast     *decorateType   (ast *) ;
-ast     *createWhile    (symbol *, symbol *, symbol *, ast *, ast *);
-ast     *createIf       (ast *, ast *, ast *);
-ast     *createDo       (symbol *,symbol *,symbol *,ast *,ast *);
-ast     *createFor      (symbol *,symbol *,symbol *,symbol *,ast *,ast *,ast *, ast *);
-void     eval2icode     (ast *);
-value   *constExprValue (ast *,int);
-symbol  *funcOfType     (char *,link *,link *,int,int);
-ast     *initAggregates ( symbol *,initList *, ast *);
-bool     hasSEFcalls    ( ast *);
-void     addSymToBlock (symbol *, ast *) ;
-
-#endif 
+ast *newAst_VALUE (value * val);
+ast *newAst_OP (unsigned op);
+ast *newAst_LINK (sym_link * val);
+
+void initAst ();
+ast *newNode (long, ast *, ast *);
+ast *copyAst (ast *);
+ast *removeIncDecOps (ast *);
+ast *removePreIncDecOps (ast *);
+ast *removePostIncDecOps (ast *);
+value *sizeofOp (sym_link *);
+value *evalStmnt (ast *);
+ast *createRMW (ast *, unsigned, ast *);
+ast *createFunction (symbol *, ast *);
+ast *createBlock (symbol *, ast *);
+ast *createLabel (symbol *, ast *);
+ast *createCase (ast *, ast *, ast *);
+ast *createDefault (ast *, ast *, ast *);
+ast *forLoopOptForm (ast *);
+ast *argAst (ast *);
+ast *resolveSymbols (ast *);
+ast *decorateType (ast *, RESULT_TYPE);
+ast *createWhile (symbol *, symbol *, symbol *, ast *, ast *);
+ast *createIf (ast *, ast *, ast *);
+ast *createDo (symbol *, symbol *, symbol *, ast *, ast *);
+ast *createFor (symbol *, symbol *, symbol *, symbol *, ast *, ast *, ast *, ast *);
+void eval2icode (ast *);
+value *constExprValue (ast *, int);
+bool constExprTree (ast *);
+int setAstFileLine (ast *, char *, int);
+symbol *funcOfType (char *, sym_link *, sym_link *, int, int);
+symbol * funcOfTypeVarg (char *, char * , int , char **);
+ast *initAggregates (symbol *, initList *, ast *);
+bool hasSEFcalls (ast *);
+void addSymToBlock (symbol *, ast *);
+void freeStringSymbol(symbol *);
+DEFSETFUNC(resetParmKey);
+int astErrors(ast *);
+RESULT_TYPE getResultTypeFromType (sym_link *);
+
+// exported variables
+extern set *operKeyReset;
+extern int noAlloc;
+extern int inInitMode;
+
+#endif