fix problem with ternary operator in varargs function calls
[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
33 #define  EX_OP       0
34 #define  EX_VALUE    1
35 #define  EX_LINK     2
36 #define  EX_STMNT    3
37 #define  EX_OPERAND  4
38
39 /* expression tree   */
40 typedef struct ast
41   {
42
43     unsigned type:3;
44     unsigned decorated:1;
45     unsigned hasVargs:1;
46     unsigned isError:1;
47     unsigned funcName:1;
48     unsigned rvalue:1;
49     unsigned lvalue:1;
50     unsigned initMode:1;
51     int level;                  /* level for expr */
52     int block;                  /* block number   */
53     /* union of values expression can have */
54     union
55       {
56         value *val;             /* value if type = EX_VALUE */
57         sym_link *lnk;          /* sym_link * if type= EX_LINK  */
58         struct operand *oprnd;  /* used only for side effecting function calls */
59         unsigned stmnt;         /* statement if type=EX_STMNT */
60         unsigned op;            /* operator if type= EX_OP  */
61       }
62     opval;
63
64     /* union for special processing */
65     union
66       {
67         char *inlineasm;        /* pointer to inline assembler code */
68         symbol *sym;            /* if block then -> symbols */
69         value *args;            /* if function then args    */
70         /* if switch then switch values */
71         struct
72           {
73             value *swVals;      /* switch comparison values */
74             int swDefault;      /* default if present       */
75             int swNum;          /* switch number            */
76           }
77         switchVals;
78         /* if for then for values */
79         struct
80           {
81             struct ast *initExpr;       /* init portion */
82             struct ast *condExpr;       /* conditional portion */
83             struct ast *loopExpr;       /* iteration portion   */
84             symbol *trueLabel;  /* entry point into body */
85             symbol *falseLabel; /* exit point */
86             symbol *continueLabel;      /* conditional check   */
87             symbol *condLabel;  /* conditional label   */
88           }
89         forVals;
90         unsigned literalFromCast;       /* true if this is an EX_VALUE of LITERAL 
91                                          * type resulting from a typecast.
92                                          */
93       }
94     values;
95
96     int lineno;                 /* source file line number     */
97     char *filename;             /* filename of the source file */
98
99     sym_link *ftype;            /* start of type chain for this subtree */
100     sym_link *etype;            /* end of type chain for this subtree   */
101
102     symbol *argSym;             /* argument symbols            */
103     value *args;                /* args of a function          */
104     struct ast *left;           /* pointer to left tree        */
105     struct ast *right;          /* pointer to right tree       */
106     symbol *trueLabel;          /* if statement trueLabel */
107     symbol *falseLabel;         /* if statement falseLabel */
108   }
109 ast;
110
111
112 /* easy access macros   */
113 #define  IS_AST_OP(x)                   (x && x->type == EX_OP)
114 #define IS_CALLOP(x)   (IS_AST_OP(x) && x->opval.op == CALL)
115 #define IS_BITOR(x) (IS_AST_OP(x) && x->opval.op == '|')
116 #define IS_BITAND(x) (IS_AST_OP(x) && x->opval.op == '&' && \
117                       x->left && x->right )
118 #define IS_FOR_STMT(x) (IS_AST_OP(x) && x->opval.op == FOR)
119 #define IS_LEFT_OP(x) (IS_AST_OP(x) && x->opval.op == LEFT_OP)
120 #define IS_RIGHT_OP(x) (IS_AST_OP(x) && x->opval.op == RIGHT_OP)
121 #define  IS_AST_VALUE(x)        (x && x->type == EX_VALUE && x->opval.val)
122 #define  IS_AST_LINK(x)         (x->type == EX_LINK)
123 #define  IS_AST_NOT_OPER(x)     (x && IS_AST_OP(x) && x->opval.op == '!')
124 #define  IS_ARRAY_OP(x) (IS_AST_OP(x) && x->opval.op == '[')
125 #define  IS_COMPARE_OP(x)       (IS_AST_OP(x)           &&              \
126                                   (x->opval.op == '>'   ||              \
127                                    x->opval.op == '<'   ||              \
128                                    x->opval.op == LE_OP ||              \
129                                    x->opval.op == GE_OP ||              \
130                                    x->opval.op == EQ_OP ||              \
131                                    x->opval.op == NE_OP ))
132 #define IS_CAST_OP(x) (IS_AST_OP(x) && x->opval.op == CAST)
133 #define IS_TERNARY_OP(x) (IS_AST_OP(x) && x->opval.op == '?')
134 #define IS_COLON_OP(x) (IS_AST_OP(x) && x->opval.op == ':')
135 #define IS_ADDRESS_OF_OP(x)    (IS_AST_OP(x)            &&              \
136                                 x->opval.op == '&'      &&              \
137                                 x->right == NULL )
138 #define IS_AST_LIT_VALUE(x) (IS_AST_VALUE(x) && \
139                              IS_LITERAL(x->opval.val->etype))
140 #define IS_AST_SYM_VALUE(x)     (IS_AST_VALUE(x) && x->opval.val->sym)
141 #define AST_LIT_VALUE(x)        (floatFromVal(x->opval.val))
142 #define AST_SYMBOL(x)           (x->opval.val->sym)
143 #define AST_VALUE(x)            (x->opval.val)
144 #define AST_VALUES(x,y) (x->values.y)
145 #define AST_FOR(x,y) x->values.forVals.y
146 #define  IS_AST_PARAM(x)        (IS_AST_OP(x) && x->opval.op == PARAM)
147
148 #define  CAN_EVAL(x)    (     x ==  '[' || x == '.' || x == PTR_OP ||   \
149               x ==  '&' || x == '|' || x == '^'    || x == '*' || \
150               x ==  '-' || x == '+' || x == '~'    ||   \
151               x ==  '!' || x == LEFT_OP || x == RIGHT_OP ||       \
152               x ==  '/' || x == '%' || x == '>' || x == '<'    || \
153               x == LE_OP || x == GE_OP || x == EQ_OP || x == NE_OP || \
154               x == AND_OP || x == OR_OP || x == '='  )
155
156 #define  LEFT_FIRST(x) ( x  ==  AND_OP  ||      x       ==      OR_OP   )
157
158 #define SIDE_EFFECTS_CHECK(op,rVal)  if (!sideEffects)  {               \
159                                          werror(W_NO_SIDE_EFFECTS,op);  \
160                                          return rVal    ;               \
161                                      }
162 #define IS_MODIFYING_OP(x) ( x == INC_OP || x == DEC_OP || x == '=' ||  \
163                         x == AND_ASSIGN || x== OR_ASSIGN || x == XOR_ASSIGN )
164
165 #define IS_ASSIGN_OP(x) ( x == '=' || x == ADD_ASSIGN || x == SUB_ASSIGN ||\
166                           x == MUL_ASSIGN || x == DIV_ASSIGN || x == XOR_ASSIGN ||\
167                           x == AND_ASSIGN || x == OR_ASSIGN || x == INC_OP || x == DEC_OP)
168 #define IS_DEREF_OP(x) (( x->opval.op == '*' && x->right == NULL) || x->opval.op == '.')
169
170 /* forward declarations for global variables */
171 extern ast *staticAutos;
172 extern FILE *codeOutFile;
173 extern memmap *GcurMemmap;
174
175 /* forward definitions for functions   */
176 ast *newAst_VALUE (value * val);
177 ast *newAst_OP (unsigned op);
178 ast *newAst_LINK (sym_link * val);
179 ast *newAst_STMNT (unsigned val);
180
181 void initAst ();
182 ast *newNode (long, ast *, ast *);
183 ast *copyAst (ast *);
184 value *sizeofOp (sym_link *);
185 value *evalStmnt (ast *);
186 ast *createFunction (symbol *, ast *);
187 ast *createBlock (symbol *, ast *);
188 ast *createLabel (symbol *, ast *);
189 ast *createCase (ast *, ast *, ast *);
190 ast *createDefault (ast *, ast *);
191 ast *optimizeCompare (ast *);
192 ast *forLoopOptForm (ast *);
193 ast *argAst (ast *);
194 ast *resolveSymbols (ast *);
195 ast *decorateType (ast *);
196 ast *createWhile (symbol *, symbol *, symbol *, ast *, ast *);
197 ast *createIf (ast *, ast *, ast *);
198 ast *createDo (symbol *, symbol *, symbol *, ast *, ast *);
199 ast *createFor (symbol *, symbol *, symbol *, symbol *, ast *, ast *, ast *, ast *);
200 void eval2icode (ast *);
201 value *constExprValue (ast *, int);
202 symbol *funcOfType (char *, sym_link *, sym_link *, int, int);
203 ast *initAggregates (symbol *, initList *, ast *);
204 bool hasSEFcalls (ast *);
205 void addSymToBlock (symbol *, ast *);
206
207 // exported variables 
208 extern set *operKeyReset;
209 extern int noAlloc;
210
211 #endif