Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / src / SDCCast.h
index dc1b6e65f7c71766558f2ecb5b4f54495f651ad1..17a21d1e296fc4c661d4c45172a669fe1af2ec0a 100644 (file)
@@ -7,19 +7,19 @@
    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
 #include "SDCCsymt.h"
 #include "SDCCval.h"
 #include "SDCCset.h"
+#include "SDCCmem.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;
+    ASTTYPE type;
     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   */
+    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 */
-       sym_link *lnk;          /* sym_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  */
+        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;
-       unsigned literalFromCast;       /* true if this is an EX_VALUE of LITERAL 
-                                        * type resulting from a typecast.
-                                        */
+        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 */
+    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   */
+    sym_link *ftype;            /* start of type chain for this subtree */
+    sym_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 */
+    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_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_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  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 == '.')
+#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 FILE *codeOutFile;
-extern memmap *GcurMemmap;
+extern struct dbuf_s *codeOutBuf;
+extern struct memmap *GcurMemmap;
 
 /* forward definitions for functions   */
 ast *newAst_VALUE (value * val);
 ast *newAst_OP (unsigned op);
 ast *newAst_LINK (sym_link * val);
-ast *newAst_STMNT (unsigned 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 *optimizeCompare (ast *);
+ast *createDefault (ast *, ast *, ast *);
 ast *forLoopOptForm (ast *);
 ast *argAst (ast *);
 ast *resolveSymbols (ast *);
-ast *decorateType (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 
+// exported variables
 extern set *operKeyReset;
 extern int noAlloc;
+extern int inInitMode;
 
 #endif