* src/SDCCast.c, src/SDCCast.h: fixed bug #1874922: explicit typecast
[fw/sdcc] / src / SDCCast.h
1 /*-------------------------------------------------------------------------
2   SDCCast.h - header file for parser support & all ast related routines
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #ifndef SDCCEXPR_H
26 #define SDCCEXPR_H
27
28 #include "SDCCglobl.h"
29 #include "SDCCsymt.h"
30 #include "SDCCval.h"
31 #include "SDCCset.h"
32 #include "SDCCmem.h"
33
34 typedef enum {
35   EX_OP=0,
36   EX_VALUE,
37   EX_LINK,
38   EX_OPERAND
39 } ASTTYPE;
40
41 /* expression tree   */
42 typedef struct ast
43   {
44
45     ASTTYPE type;
46     unsigned decorated:1;
47     unsigned isError:1;
48     unsigned funcName:1;
49     unsigned rvalue:1;
50     unsigned lvalue:1;
51     unsigned initMode:1;
52     unsigned reversed:1;
53     unsigned actualArgument:1;  /* actual function argument */
54     int level;                  /* level for expr */
55     int block;                  /* block number   */
56     int seqPoint;               /* sequence point */
57     /* union of values expression can have */
58     union
59       {
60         value *val;             /* value if type = EX_VALUE */
61         sym_link *lnk;          /* sym_link * if type= EX_LINK  */
62         struct operand *oprnd;  /* used only for side effecting function calls */
63         unsigned op;            /* operator if type= EX_OP  */
64       }
65     opval;
66
67     /* union for special processing */
68     union
69       {
70         char *inlineasm;        /* pointer to inline assembler code */
71         literalList *constlist; /* init list for array initializer. */
72         symbol *sym;            /* if block then -> symbols */
73         value *args;            /* if function then args    */
74         /* if switch then switch values */
75         struct
76           {
77             value *swVals;      /* switch comparison values */
78             int swDefault;      /* default if present       */
79             int swNum;          /* switch number            */
80           }
81         switchVals;
82         /* if for then for values */
83         struct
84           {
85             struct ast *initExpr;       /* init portion */
86             struct ast *condExpr;       /* conditional portion */
87             struct ast *loopExpr;       /* iteration portion   */
88             symbol *trueLabel;  /* entry point into body */
89             symbol *falseLabel; /* exit point */
90             symbol *continueLabel;      /* conditional check   */
91             symbol *condLabel;  /* conditional label   */
92           }
93         forVals;
94         unsigned literalFromCast;       /* true if this is an EX_VALUE of LITERAL
95                                          * type resulting from a typecast.
96                                          */
97         int argreg;                     /* argreg number when operand type == EX_OPERAND */
98       }
99     values;
100
101     int lineno;                 /* source file line number     */
102     char *filename;             /* filename of the source file */
103
104     sym_link *ftype;            /* start of type chain for this subtree */
105     sym_link *etype;            /* end of type chain for this subtree   */
106
107     struct ast *left;           /* pointer to left tree        */
108     struct ast *right;          /* pointer to right tree       */
109     symbol *trueLabel;          /* if statement trueLabel */
110     symbol *falseLabel;         /* if statement falseLabel */
111   }
112 ast;
113
114
115 /* easy access macros   */
116 #define IS_AST_OP(x)            ((x) && (x)->type == EX_OP)
117 #define IS_CALLOP(x)            (IS_AST_OP(x) && x->opval.op == CALL)
118 #define IS_BITOR(x)             (IS_AST_OP(x) && x->opval.op == '|')
119 #define IS_BITAND(x)            (IS_AST_OP(x) && x->opval.op == '&' && \
120                                  x->left && x->right )
121 #define IS_FOR_STMT(x)          (IS_AST_OP(x) && x->opval.op == FOR)
122 #define IS_LEFT_OP(x)           (IS_AST_OP(x) && x->opval.op == LEFT_OP)
123 #define IS_RIGHT_OP(x)          (IS_AST_OP(x) && x->opval.op == RIGHT_OP)
124 #define IS_AST_VALUE(x)         ((x) && (x)->type == EX_VALUE && (x)->opval.val)
125 #define IS_AST_LINK(x)          (x->type == EX_LINK)
126 #define IS_AST_NOT_OPER(x)      (x && IS_AST_OP(x) && x->opval.op == '!')
127 #define IS_ARRAY_OP(x)          (IS_AST_OP(x) && x->opval.op == '[')
128 #define IS_COMPARE_OP(x)        (IS_AST_OP(x)           &&              \
129                                   (x->opval.op == '>'   ||              \
130                                    x->opval.op == '<'   ||              \
131                                    x->opval.op == LE_OP ||              \
132                                    x->opval.op == GE_OP ||              \
133                                    x->opval.op == EQ_OP ||              \
134                                    x->opval.op == NE_OP ))
135 #define IS_CAST_OP(x)           (IS_AST_OP(x) && (x)->opval.op == CAST)
136 #define IS_TERNARY_OP(x)        (IS_AST_OP(x) && x->opval.op == '?')
137 #define IS_COLON_OP(x)          (IS_AST_OP(x) && x->opval.op == ':')
138 #define IS_ADDRESS_OF_OP(x)     (IS_AST_OP(x)            &&              \
139                                  x->opval.op == '&'      &&              \
140                                  x->right == NULL )
141 #define IS_AST_LIT_VALUE(x)     (IS_AST_VALUE(x) && \
142                                  IS_LITERAL((x)->opval.val->etype))
143 #define IS_AST_SYM_VALUE(x)     (IS_AST_VALUE(x) && x->opval.val->sym)
144 #define AST_FLOAT_VALUE(x)      (floatFromVal(x->opval.val))
145 #define AST_ULONG_VALUE(x)      (ulFromVal(x->opval.val))
146 #define AST_SYMBOL(x)           (x->opval.val->sym)
147 #define AST_VALUE(x)            (x->opval.val)
148 #define AST_VALUES(x,y)         (x->values.y)
149 #define AST_FOR(x,y)            x->values.forVals.y
150 #define AST_ARGREG(x)           x->values.argreg
151
152 #define IS_AST_PARAM(x)         (IS_AST_OP(x) && x->opval.op == PARAM)
153
154 #define  CAN_EVAL(x)    (     x ==  '[' || x == '.' || x == PTR_OP ||   \
155               x ==  '&' || x == '|' || x == '^'    || x == '*' || \
156               x ==  '-' || x == '+' || x == '~'    ||   \
157               x ==  '!' || x == LEFT_OP || x == RIGHT_OP ||       \
158               x ==  '/' || x == '%' || x == '>' || x == '<'    || \
159               x == LE_OP || x == GE_OP || x == EQ_OP || x == NE_OP || \
160               x == AND_OP || x == OR_OP || x == '='  )
161
162 #define  LEFT_FIRST(x) ( x  ==  AND_OP  ||      x       ==      OR_OP   )
163
164 #define SIDE_EFFECTS_CHECK(op,rVal)  if (!sideEffects)  {               \
165                                          werror(W_NO_SIDE_EFFECTS,op);  \
166                                          return rVal    ;               \
167                                      }
168 #define IS_MODIFYING_OP(x) ( x == INC_OP || x == DEC_OP || x == '=' ||  \
169                         x == AND_ASSIGN || x== OR_ASSIGN || x == XOR_ASSIGN )
170
171 #define IS_ASSIGN_OP(x) ( x == '=' || x == ADD_ASSIGN || x == SUB_ASSIGN ||\
172                           x == MUL_ASSIGN || x == DIV_ASSIGN || x == XOR_ASSIGN ||\
173                           x == AND_ASSIGN || x == OR_ASSIGN || x == INC_OP || x == DEC_OP)
174 #define IS_DEREF_OP(x) (( x->opval.op == '*' && x->right == NULL) || x->opval.op == '.')
175
176 /* forward declarations for global variables */
177 extern ast *staticAutos;
178 extern struct dbuf_s *codeOutBuf;
179 extern struct memmap *GcurMemmap;
180
181 /* forward definitions for functions   */
182 ast *newAst_VALUE (value * val);
183 ast *newAst_OP (unsigned op);
184 ast *newAst_LINK (sym_link * val);
185
186 void initAst ();
187 ast *newNode (long, ast *, ast *);
188 ast *copyAst (ast *);
189 ast *removeIncDecOps (ast *);
190 ast *removePreIncDecOps (ast *);
191 ast *removePostIncDecOps (ast *);
192 value *sizeofOp (sym_link *);
193 value *evalStmnt (ast *);
194 ast *createRMW (ast *, unsigned, ast *);
195 ast *createFunction (symbol *, ast *);
196 ast *createBlock (symbol *, ast *);
197 ast *createLabel (symbol *, ast *);
198 ast *createCase (ast *, ast *, ast *);
199 ast *createDefault (ast *, ast *, ast *);
200 ast *forLoopOptForm (ast *);
201 ast *argAst (ast *);
202 ast *resolveSymbols (ast *);
203 ast *decorateType (ast *, RESULT_TYPE);
204 ast *createWhile (symbol *, symbol *, symbol *, ast *, ast *);
205 ast *createIf (ast *, ast *, ast *);
206 ast *createDo (symbol *, symbol *, symbol *, ast *, ast *);
207 ast *createFor (symbol *, symbol *, symbol *, symbol *, ast *, ast *, ast *, ast *);
208 void eval2icode (ast *);
209 value *constExprValue (ast *, int);
210 bool constExprTree (ast *);
211 int setAstFileLine (ast *, char *, int);
212 symbol *funcOfType (char *, sym_link *, sym_link *, int, int);
213 symbol * funcOfTypeVarg (char *, char * , int , char **);
214 ast *initAggregates (symbol *, initList *, ast *);
215 bool hasSEFcalls (ast *);
216 void addSymToBlock (symbol *, ast *);
217 void freeStringSymbol(symbol *);
218 DEFSETFUNC(resetParmKey);
219 int astErrors(ast *);
220 RESULT_TYPE getResultTypeFromType (sym_link *);
221
222 // exported variables
223 extern set *operKeyReset;
224 extern int noAlloc;
225 extern int inInitMode;
226
227 #endif