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 SDCCAST_H 26 #define SDCCAST_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 { 36 EX_OP = 0, 37 EX_VALUE, 38 EX_LINK, 39 EX_OPERAND 40 } ASTTYPE; 41 42 /* expression tree */ 43 typedef struct ast 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 long level; /* level for expr */ 54 int block; /* block number */ 55 int seqPoint; /* sequence point */ 56 /* union of values expression can have */ 57 union 58 { 59 value *val; /* value if type = EX_VALUE */ 60 sym_link *lnk; /* sym_link * if type= EX_LINK */ 61 struct operand *oprnd; /* used only for side effecting function calls */ 62 unsigned op; /* operator if type= EX_OP */ 63 } 64 opval; 65 66 /* union for special processing */ 67 union 68 { 69 char *inlineasm; /* pointer to inline assembler code */ 70 literalList *constlist; /* init list for array initializer. */ 71 symbol *sym; /* if block then -> symbols */ 72 value *args; /* if function then args */ 73 /* if switch then switch values */ 74 struct 75 { 76 value *swVals; /* switch comparison values */ 77 int swDefault; /* default if present */ 78 int swNum; /* switch number */ 79 char *swSuffix; 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 struct 95 { 96 unsigned literalFromCast:1; /* true if this is an EX_VALUE of LITERAL 97 * type resulting from a typecast. 98 */ 99 unsigned removedCast:1; /* true if the explicit cast has been removed */ 100 unsigned implicitCast:1; /* true if compiler added this cast */ 101 } cast; 102 int argreg; /* argreg number when operand type == EX_OPERAND */ 103 } 104 values; 105 106 int lineno; /* source file line number */ 107 char *filename; /* filename of the source file */ 108 109 sym_link *ftype; /* start of type chain for this subtree */ 110 sym_link *etype; /* end of type chain for this subtree */ 111 112 struct ast *left; /* pointer to left tree */ 113 struct ast *right; /* pointer to right tree */ 114 symbol *trueLabel; /* if statement trueLabel */ 115 symbol *falseLabel; /* if statement falseLabel */ 116 } 117 ast; 118 119 120 /* easy access macros */ 121 #define IS_AST_OP(x) ((x) && (x)->type == EX_OP) 122 #define IS_CALLOP(x) (IS_AST_OP(x) && (x)->opval.op == CALL) 123 #define IS_BITOR(x) (IS_AST_OP(x) && (x)->opval.op == '|') 124 #define IS_BITAND(x) (IS_AST_OP(x) && (x)->opval.op == '&' && \ 125 (x)->left && (x)->right ) 126 #define IS_FOR_STMT(x) (IS_AST_OP(x) && (x)->opval.op == FOR) 127 #define IS_LEFT_OP(x) (IS_AST_OP(x) && (x)->opval.op == LEFT_OP) 128 #define IS_RIGHT_OP(x) (IS_AST_OP(x) && (x)->opval.op == RIGHT_OP) 129 #define IS_AST_VALUE(x) ((x) && (x)->type == EX_VALUE && (x)->opval.val) 130 #define IS_AST_LINK(x) ((x)->type == EX_LINK) 131 #define IS_AST_NOT_OPER(x) (x && IS_AST_OP(x) && (x)->opval.op == '!') 132 #define IS_ARRAY_OP(x) (IS_AST_OP(x) && (x)->opval.op == '[') 133 #define IS_COMPARE_OP(x) (IS_AST_OP(x) && \ 134 ((x)->opval.op == '>' || \ 135 (x)->opval.op == '<' || \ 136 (x)->opval.op == LE_OP || \ 137 (x)->opval.op == GE_OP || \ 138 (x)->opval.op == EQ_OP || \ 139 (x)->opval.op == NE_OP )) 140 #define IS_CAST_OP(x) (IS_AST_OP(x) && (x)->opval.op == CAST) 141 #define IS_TERNARY_OP(x) (IS_AST_OP(x) && (x)->opval.op == '?') 142 #define IS_COLON_OP(x) (IS_AST_OP(x) && (x)->opval.op == ':') 143 #define IS_ADDRESS_OF_OP(x) (IS_AST_OP(x) && \ 144 (x)->opval.op == '&' && \ 145 (x)->right == NULL ) 146 #define IS_AST_LIT_VALUE(x) (IS_AST_VALUE(x) && \ 147 IS_LITERAL((x)->opval.val->etype)) 148 #define IS_AST_SYM_VALUE(x) (IS_AST_VALUE(x) && (x)->opval.val->sym) 149 #define AST_FLOAT_VALUE(x) (floatFromVal((x)->opval.val)) 150 #define AST_ULONG_VALUE(x) (ulFromVal((x)->opval.val)) 151 #define AST_SYMBOL(x) ((x)->opval.val->sym) 152 #define AST_VALUE(x) ((x)->opval.val) 153 #define AST_VALUES(x,y) ((x)->values.y) 154 #define AST_FOR(x,y) ((x)->values.forVals.y) 155 #define AST_ARGREG(x) ((x)->values.argreg) 156 157 #define IS_AST_PARAM(x) (IS_AST_OP(x) && (x)->opval.op == PARAM) 158 159 #define CAN_EVAL(x) ( (x) == '[' || (x) == '.' || (x) == PTR_OP || \ 160 (x) == '&' || (x) == '|' || (x) == '^' || (x) == '*' || \ 161 (x) == '-' || (x) == '+' || (x) == '~' || \ 162 (x) == '!' || (x) == LEFT_OP || (x) == RIGHT_OP || \ 163 (x) == '/' || (x) == '%' || (x) == '>' || (x) == '<' || \ 164 (x) == LE_OP || (x) == GE_OP || (x) == EQ_OP || (x) == NE_OP || \ 165 (x) == AND_OP || (x) == OR_OP || (x) == '=' ) 166 167 #define LEFT_FIRST(x) ( x == AND_OP || x == OR_OP ) 168 169 #define SIDE_EFFECTS_CHECK(op,rVal) if (!sideEffects) { \ 170 werror(W_NO_SIDE_EFFECTS,op); \ 171 return rVal ; \ 172 } 173 #define IS_MODIFYING_OP(x) ( (x) == INC_OP || (x) == DEC_OP || (x) == '=' || \ 174 (x) == AND_ASSIGN || (x) == OR_ASSIGN || (x) == XOR_ASSIGN ) 175 176 #define IS_ASSIGN_OP(x) ( (x) == '=' || (x) == ADD_ASSIGN || (x) == SUB_ASSIGN || \ 177 (x) == MUL_ASSIGN || (x) == DIV_ASSIGN || (x) == XOR_ASSIGN || \ 178 (x) == AND_ASSIGN || (x) == OR_ASSIGN || (x) == INC_OP || (x) == DEC_OP) 179 #define IS_DEREF_OP(x) ( ( (x)->opval.op == '*' && (x)->right == NULL) || \ 180 (x)->opval.op == '.' || \ 181 (x)->opval.op == PTR_OP ) 182 183 /* forward declarations for global variables */ 184 extern ast *staticAutos; 185 extern struct dbuf_s *codeOutBuf; 186 extern struct memmap *GcurMemmap; 187 188 /* forward definitions for functions */ 189 ast *newAst_VALUE (value * val); 190 ast *newAst_OP (unsigned op); 191 ast *newAst_LINK (sym_link * val); 192 193 void initAst (); 194 ast *newNode (long, ast *, ast *); 195 ast *copyAst (ast *); 196 ast *removeIncDecOps (ast *); 197 ast *removePreIncDecOps (ast *); 198 ast *removePostIncDecOps (ast *); 199 value *sizeofOp (sym_link *); 200 value *alignofOp (sym_link *); 201 ast *offsetofOp (sym_link * type, ast * snd); 202 value *evalStmnt (ast *); 203 ast *createRMW (ast *, unsigned, ast *); 204 symbol * createFunctionDecl (symbol *); 205 ast *createFunction (symbol *, ast *); 206 ast *createBlock (symbol *, ast *); 207 ast *createLabel (symbol *, ast *); 208 ast *createCase (ast *, ast *, ast *); 209 ast *createDefault (ast *, ast *, ast *); 210 ast *forLoopOptForm (ast *); 211 ast *argAst (ast *); 212 ast *resolveSymbols (ast *); 213 void CodePtrPointsToConst (sym_link * t); 214 void checkPtrCast (sym_link * newType, sym_link * orgType, bool implicit, bool orgIsNullPtrConstant); 215 ast *decorateType (ast *, RESULT_TYPE); 216 ast *createWhile (symbol *, symbol *, symbol *, ast *, ast *); 217 ast *createIf (ast *, ast *, ast *); 218 ast *createDo (symbol *, symbol *, symbol *, ast *, ast *); 219 ast *createFor (symbol *, symbol *, symbol *, symbol *, ast *, ast *, ast *, ast *, ast *); 220 void eval2icode (ast *); 221 value *constExprValue (ast *, int); 222 bool constExprTree (ast *); 223 int setAstFileLine (ast *, char *, int); 224 symbol *funcOfType (const char *, sym_link *, sym_link *, int, int); 225 symbol *funcOfTypeVarg (const char *, const char *, int, const char **); 226 ast *initAggregates (symbol *, initList *, ast *); 227 bool astHasVolatile (ast *tree); 228 bool hasSEFcalls (ast *); 229 void addSymToBlock (symbol *, ast *); 230 void freeStringSymbol (symbol *); 231 value *stringToSymbol (value *val); 232 DEFSETFUNC (resetParmKey); 233 int astErrors (ast *); 234 RESULT_TYPE getResultTypeFromType (sym_link *); 235 236 // exported variables 237 extern set *operKeyReset; 238 extern int noAlloc; 239 extern int inInitMode; 240 241 #endif 242