-------------------------------------------------------------------------*/
#include "common.h"
-#include "newalloc.h"
int currLineno = 0;
set *astList = NULL;
int noLineno = 0;
int noAlloc = 0;
symbol *currFunc;
-ast *createIval (ast *, sym_link *, initList *, ast *);
-ast *createIvalCharPtr (ast *, sym_link *, ast *);
+static ast *createIval (ast *, sym_link *, initList *, ast *);
+static ast *createIvalCharPtr (ast *, sym_link *, ast *);
+static ast *optimizeCompare (ast *);
ast *optimizeRRCRLC (ast *);
ast *optimizeGetHbit (ast *);
ast *backPatchLabels (ast *, symbol *, symbol *);
+void PA(ast *t);
int inInitMode = 0;
memmap *GcurMemmap=NULL; /* points to the memmap that's currently active */
FILE *codeOutFile;
/*-----------------------------------------------------------------*/
-/* newAst - creates a fresh node for an expression tree */
+/* newAst - creates a fresh node for an expression tree */
/*-----------------------------------------------------------------*/
-#if 0
-ast *
-newAst (int type, void *op)
-{
- ast *ex;
- static int oldLineno = 0;
-
- Safe_calloc (1, ex, sizeof (ast));
-
- ex->type = type;
- ex->lineno = (noLineno ? oldLineno : yylineno);
- ex->filename = currFname;
- ex->level = NestLevel;
- ex->block = currBlockno;
- ex->initMode = inInitMode;
-
- /* depending on the type */
- switch (type)
- {
- case EX_VALUE:
- ex->opval.val = (value *) op;
- break;
- case EX_OP:
- ex->opval.op = (long) op;
- break;
- case EX_LINK:
- ex->opval.lnk = (sym_link *) op;
- break;
- case EX_STMNT:
- ex->opval.stmnt = (unsigned) op;
- }
-
- return ex;
-}
-#endif
-
static ast *
newAst_ (unsigned type)
{
ast *ex;
static int oldLineno = 0;
- ex = Safe_calloc (1, sizeof (ast));
+ ex = Safe_alloc ( sizeof (ast));
ex->type = type;
ex->lineno = (noLineno ? oldLineno : yylineno);
break;
case INLINEASM:
- dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1);
- strcpy (dest->values.inlineasm, src->values.inlineasm);
+ dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
break;
case ARRAYINIT:
/* copyAst - makes a copy of a given astession */
/*-----------------------------------------------------------------*/
ast *
-copyAst (ast * src)
+copyAst (ast * src)
{
ast *dest;
if (!src)
return NULL;
- dest = Safe_calloc (1, sizeof (ast));
+ dest = Safe_alloc ( sizeof (ast));
dest->type = src->type;
dest->lineno = src->lineno;
dest->level = src->level;
dest->funcName = src->funcName;
- dest->argSym = src->argSym;
+
+ if (src->ftype)
+ dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
/* if this is a leaf */
/* if value */
/* if this is a node that has special values */
copyAstValues (dest, src);
- if (src->ftype)
- dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
-
dest->trueLabel = copySymbol (src->trueLabel);
dest->falseLabel = copySymbol (src->falseLabel);
dest->left = copyAst (src->left);
}
+/*-----------------------------------------------------------------*/
+/* removeIncDecOps: remove for side effects in *_ASSIGN's */
+/* "*s++ += 3" -> "*s++ = *s++ + 3" */
+/*-----------------------------------------------------------------*/
+ast *removeIncDecOps (ast * tree) {
+
+ // traverse the tree and remove inc/dec ops
+
+ if (!tree)
+ return NULL;
+
+ if (tree->type == EX_OP &&
+ (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
+ if (tree->left)
+ tree=tree->left;
+ else
+ tree=tree->right;
+ }
+
+ tree->left=removeIncDecOps(tree->left);
+ tree->right=removeIncDecOps(tree->right);
+
+ return tree;
+}
+
/*-----------------------------------------------------------------*/
/* hasSEFcalls - returns TRUE if tree has a function call */
/*-----------------------------------------------------------------*/
if (tree == NULL)
return tree;
+#if 0
/* print the line */
/* if not block & function */
if (tree->type == EX_OP &&
filename = tree->filename;
lineno = tree->lineno;
}
+#endif
/* make sure we resolve the true & false labels for ifx */
if (tree->type == EX_OP && tree->opval.op == IFX)
/* mark it as returning an int */
if (tree->funcName)
{
- tree->opval.val->sym->type = newLink ();
+ tree->opval.val->sym->type = newLink (DECLARATOR);
DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
tree->opval.val->sym->type->next =
tree->opval.val->sym->etype = newIntLink ();
/*-----------------------------------------------------------------*/
/* setAstLineno - walks a ast tree & sets the line number */
/*-----------------------------------------------------------------*/
-int
-setAstLineno (ast * tree, int lineno)
+int setAstLineno (ast * tree, int lineno)
{
if (!tree)
return 0;
return 0;
}
-#if 0
-/* this functions seems to be superfluous?! kmh */
-
-/*-----------------------------------------------------------------*/
-/* resolveFromTable - will return the symbal table value */
-/*-----------------------------------------------------------------*/
-value *
-resolveFromTable (value * val)
-{
- symbol *csym;
-
- if (!val->sym)
- return val;
-
- csym = findSymWithLevel (SymbolTab, val->sym);
-
- /* if found in the symbol table & they r not the same */
- if (csym && val->sym != csym &&
- csym->level == val->sym->level &&
- csym->_isparm &&
- !csym->ismyparm)
- {
-
- val->sym = csym;
- val->type = csym->type;
- val->etype = csym->etype;
- }
-
- return val;
-}
-#endif
-
/*-----------------------------------------------------------------*/
/* funcOfType :- function of type with name */
/*-----------------------------------------------------------------*/
/* create the symbol */
sym = newSymbol (name, 0);
+ /* setup return value */
+ sym->type = newLink (DECLARATOR);
+ DCL_TYPE (sym->type) = FUNCTION;
+ sym->type->next = copyLinkChain (type);
+ sym->etype = getSpec (sym->type);
+ FUNC_ISREENT(sym->type) = rent ? 1 : 0;
+
/* if arguments required */
if (nArgs)
{
-
value *args;
- args = sym->args = newValue ();
+ args = FUNC_ARGS(sym->type) = newValue ();
while (nArgs--)
{
args->type = copyLinkChain (argType);
args->etype = getSpec (args->type);
+ SPEC_EXTR(args->etype)=1;
if (!nArgs)
break;
args = args->next = newValue ();
}
}
- /* setup return value */
- sym->type = newLink ();
- DCL_TYPE (sym->type) = FUNCTION;
- sym->type->next = copyLinkChain (type);
- sym->etype = getSpec (sym->type);
- SPEC_RENT (sym->etype) = rent;
-
/* save it */
addSymChain (sym);
sym->cdef = 1;
}
+/*-----------------------------------------------------------------*/
+/* funcOfTypeVarg :- function of type with name and argtype */
+/*-----------------------------------------------------------------*/
+symbol *
+funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
+{
+
+ symbol *sym;
+ int i ;
+ /* create the symbol */
+ sym = newSymbol (name, 0);
+
+ /* setup return value */
+ sym->type = newLink (DECLARATOR);
+ DCL_TYPE (sym->type) = FUNCTION;
+ sym->type->next = typeFromStr(rtype);
+ sym->etype = getSpec (sym->type);
+
+ /* if arguments required */
+ if (nArgs) {
+ value *args;
+ args = FUNC_ARGS(sym->type) = newValue ();
+
+ for ( i = 0 ; i < nArgs ; i++ ) {
+ args->type = typeFromStr(atypes[i]);
+ args->etype = getSpec (args->type);
+ SPEC_EXTR(args->etype)=1;
+ if ((i + 1) == nArgs) break;
+ args = args->next = newValue ();
+ }
+ }
+
+ /* save it */
+ addSymChain (sym);
+ sym->cdef = 1;
+ allocVariables (sym);
+ return sym;
+
+}
+
/*-----------------------------------------------------------------*/
/* reverseParms - will reverse a parameter tree */
/*-----------------------------------------------------------------*/
-void
+static void
reverseParms (ast * ptree)
{
ast *ttree;
/*-----------------------------------------------------------------*/
int
processParms (ast * func,
- value * defParm,
+ value *defParm,
ast * actParm,
- int *parmNumber,
+ int *parmNumber, // unused, although updated
bool rightmost)
{
- sym_link *fetype = func->etype;
-
/* if none of them exist */
if (!defParm && !actParm)
return 0;
if (defParm) {
if (getenv("DEBUG_SANITY")) {
- fprintf (stderr, "addSym: %s ", defParm->name);
+ fprintf (stderr, "processParms: %s ", defParm->name);
}
/* make sure the type is complete and sane */
checkTypeSanity(defParm->etype, defParm->name);
/* if the function is being called via a pointer & */
/* it has not been defined a reentrant then we cannot */
/* have parameters */
- if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto)
+ if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
{
werror (W_NONRENT_ARGS);
return 1;
/* if defined parameters ended but actual parameters */
/* exist and this is not defined as a variable arg */
- /* also check if statckAuto option is specified */
- if ((!defParm) && actParm && (!func->hasVargs) &&
- !options.stackAuto && !IS_RENT (fetype))
+ if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
{
werror (E_TOO_MANY_PARMS);
return 1;
return 1;
}
+ if (IS_VOID(actParm->ftype)) {
+ werror (E_VOID_VALUE_USED);
+ return 1;
+ }
+
/* If this is a varargs function... */
- if (!defParm && actParm && func->hasVargs)
+ if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
{
ast *newType = NULL;
sym_link *ftype;
return 0;
}
- /* The ternary ('?') operator is weird: the ftype of the
- * operator is the type of the condition, but it will return a
- * (possibly) different type.
- */
- if (IS_TERNARY_OP(actParm))
- {
- assert(IS_COLON_OP(actParm->right));
- assert(actParm->right->left);
- ftype = actParm->right->left->ftype;
- }
- else
- {
- ftype = actParm->ftype;
- }
+ ftype = actParm->ftype;
/* If it's a small integer, upcast to int. */
if (IS_INTEGRAL (ftype)
&& (getSize (ftype) < (unsigned) INTSIZE))
{
- newType = newAst_LINK(INTTYPE);
+ if (IS_AST_OP(actParm) &&
+ (actParm->opval.op == LEFT_OP ||
+ actParm->opval.op == '*' ||
+ actParm->opval.op == '+' ||
+ actParm->opval.op == '-') &&
+ actParm->right) {
+ // we should cast an operand instead of the result
+ actParm->decorated = 0;
+ actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
+ actParm->left);
+ actParm = decorateType(actParm);
+ } else {
+ newType = newAst_LINK(INTTYPE);
+ }
}
if (IS_PTR(ftype) && !IS_GENPTR(ftype))
{
newType = newAst_LINK (copyLinkChain(ftype));
- DCL_TYPE (newType->opval.lnk) = GPOINTER;
+ DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
}
if (IS_AGGREGATE (ftype))
{
newType = newAst_LINK (copyLinkChain (ftype));
- DCL_TYPE (newType->opval.lnk) = GPOINTER;
+ DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
}
if (newType)
{
/* cast required; change this op to a cast. */
- ast *parmCopy = resolveSymbols (copyAst (actParm));
+ ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
actParm->type = EX_OP;
actParm->opval.op = CAST;
}
/* if defined parameters ended but actual has not & */
- /* stackAuto */
+ /* reentrant */
if (!defParm && actParm &&
- (options.stackAuto || IS_RENT (fetype)))
+ (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
return 0;
resolveSymbols (actParm);
}
}
-
/* the parameter type must be at least castable */
if (compareType (defParm->type, actParm->ftype) == 0) {
- werror (W_INCOMPAT_CAST);
- fprintf (stderr, "type --> '");
- printTypeChain (actParm->ftype, stderr);
- fprintf (stderr, "' ");
- fprintf (stderr, "assigned to type --> '");
- printTypeChain (defParm->type, stderr);
- fprintf (stderr, "'\n");
+ werror (E_INCOMPAT_TYPES);
+ printFromToType (actParm->ftype, defParm->type);
+ return 1;
}
/* if the parameter is castable then add the cast */
if (compareType (defParm->type, actParm->ftype) < 0)
{
- ast *pTree = resolveSymbols (copyAst (actParm));
+ ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
/* now change the current one to a cast */
actParm->type = EX_OP;
actParm->right = pTree;
actParm->etype = defParm->etype;
actParm->ftype = defParm->type;
+ actParm->decorated=0; /* force typechecking */
+ decorateType (actParm);
}
-/* actParm->argSym = resolveFromTable(defParm)->sym ; */
-
- actParm->argSym = defParm->sym;
/* make a copy and change the regparm type to the defined parm */
actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
+ SPEC_ARGREG (actParm->etype) = SPEC_ARGREG (defParm->etype);
(*parmNumber)++;
return 0;
}
/*-----------------------------------------------------------------*/
/* createIvalType - generates ival for basic types */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
createIvalType (ast * sym, sym_link * type, initList * ilist)
{
ast *iExpr;
/*-----------------------------------------------------------------*/
/* createIvalStruct - generates initial value for structures */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
createIvalStruct (ast * sym, sym_link * type, initList * ilist)
{
ast *rast = NULL;
+ ast *lAst;
symbol *sflds;
initList *iloop;
for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
{
- ast *lAst;
-
/* if we have come to end */
if (!iloop)
break;
lAst = decorateType (resolveSymbols (lAst));
rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
}
+
+ if (iloop) {
+ werror (W_EXCESS_INITIALIZERS, "struct",
+ sym->opval.val->sym->name, sym->opval.val->sym->lineDef);
+ }
+
return rast;
}
/*-----------------------------------------------------------------*/
/* createIvalArray - generates code for array initialization */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
createIvalArray (ast * sym, sym_link * type, initList * ilist)
{
ast *rast = NULL;
char *name=sym->opval.val->sym->name;
int lineno=sym->opval.val->sym->lineDef;
- werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
+ werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
}
}
else
// there has to be a better way
char *name=sym->opval.val->sym->name;
int lineno=sym->opval.val->sym->lineDef;
- werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno);
+ werror (W_EXCESS_INITIALIZERS, "array", name, lineno);
break;
}
/*-----------------------------------------------------------------*/
/* createIvalCharPtr - generates initial values for char pointers */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
{
ast *rast = NULL;
newNode ('[', sym,
newAst_VALUE (valueFromLit ((float) i))),
newAst_VALUE (valueFromLit (*s))));
+
+ // now WE don't need iexpr's symbol anymore
+ freeStringSymbol(AST_SYMBOL(iexpr));
+
return decorateType (resolveSymbols (rast));
}
/*-----------------------------------------------------------------*/
/* createIvalPtr - generates initial value for pointers */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
createIvalPtr (ast * sym, sym_link * type, initList * ilist)
{
ast *rast;
/*-----------------------------------------------------------------*/
/* createIval - generates code for initial value */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
{
ast *rast = NULL;
/*-----------------------------------------------------------------*/
/* initAggregates - initialises aggregate variables with initv */
/*-----------------------------------------------------------------*/
-
-/* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *);
-
ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
- ast *ast;
- symbol *newSym;
-
- if (getenv("TRY_THE_NEW_INITIALIZER")) {
-
- if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) {
- fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless "
- "with -mmcs51 and --model-large");
- exit(404);
- }
-
- if (SPEC_OCLS(sym->etype)==xdata &&
- getSize(sym->type) > 16) { // else it isn't worth it: do it the old way
-
- // copy this symbol
- newSym=copySymbol (sym);
- SPEC_OCLS(newSym->etype)=code;
- sprintf (newSym->name, "%s_init__", sym->name);
- sprintf (newSym->rname,"%s_init__", sym->rname);
- addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
-
- // emit it in the static segment
- addSet(&statsg->syms, newSym);
-
- // now memcpy() the entire array from cseg
- ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE
- newAst_VALUE (symbolVal (sym)),
- newAst_VALUE (symbolVal (newSym)));
- return decorateType(resolveSymbols(ast));
- }
- }
-
return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
}
/* gatherAutoInit - creates assignment expressions for initial */
/* values */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
gatherAutoInit (symbol * autoChain)
{
ast *init = NULL;
{
symbol *newSym;
- // this can only be a constant
- if (!inInitMode && !IS_LITERAL(sym->ival->init.node->etype)) {
- werror (E_CONST_EXPECTED);
- }
-
/* insert the symbol into the symbol table */
/* with level = 0 & name = rname */
newSym = copySymbol (sym);
addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
/* now lift the code to main */
- if (IS_AGGREGATE (sym->type))
+ if (IS_AGGREGATE (sym->type)) {
work = initAggregates (sym, sym->ival, NULL);
- else
+ } else {
+ if (getNelements(sym->type, sym->ival)>1) {
+ werror (W_EXCESS_INITIALIZERS, "scalar",
+ sym->name, sym->lineDef);
+ }
work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
list2expr (sym->ival));
+ }
setAstLineno (work, sym->lineDef);
/* if there is an initial value */
if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
{
- if (IS_AGGREGATE (sym->type))
+ initList *ilist=sym->ival;
+
+ while (ilist->type == INIT_DEEP) {
+ ilist = ilist->init.deep;
+ }
+
+ /* update lineno for error msg */
+ lineno=sym->lineDef;
+ setAstLineno (ilist->init.node, lineno);
+
+ if (IS_AGGREGATE (sym->type)) {
work = initAggregates (sym, sym->ival, NULL);
- else
+ } else {
+ if (getNelements(sym->type, sym->ival)>1) {
+ werror (W_EXCESS_INITIALIZERS, "scalar",
+ sym->name, sym->lineDef);
+ }
work = newNode ('=', newAst_VALUE (symbolVal (sym)),
list2expr (sym->ival));
-
+ }
+
+ // just to be sure
setAstLineno (work, sym->lineDef);
+
sym->ival = NULL;
if (init)
init = newNode (NULLOP, init, work);
return init;
}
+/*-----------------------------------------------------------------*/
+/* freeStringSymbol - delete a literal string if no more usage */
+/*-----------------------------------------------------------------*/
+void freeStringSymbol(symbol *sym) {
+ /* make sure this is a literal string */
+ assert (sym->isstrlit);
+ if (--sym->isstrlit == 0) { // lower the usage count
+ memmap *segment=SPEC_OCLS(sym->etype);
+ if (segment) {
+ deleteSetItem(&segment->syms, sym);
+ }
+ }
+}
+
/*-----------------------------------------------------------------*/
/* stringToSymbol - creates a symbol from a literal string */
/*-----------------------------------------------------------------*/
char name[SDCC_NAME_MAX + 1];
static int charLbl = 0;
symbol *sym;
+ set *sp;
+
+ // have we heard this before?
+ for (sp=statsg->syms; sp; sp=sp->next) {
+ sym=sp->item;
+ if (sym->isstrlit &&
+ !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
+ // yes, this is old news. Don't publish it again.
+ sym->isstrlit++; // but raise the usage count
+ return symbolVal(sym);
+ }
+ }
- sprintf (name, "_str_%d", charLbl++);
+ SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
sym = newSymbol (name, 0); /* make it @ level 0 */
- strcpy (sym->rname, name);
+ strncpyz (sym->rname, name, SDCC_NAME_MAX);
/* copy the type from the value passed */
sym->type = copyLinkChain (val->type);
ast *autoInit;
if (action == ALLOCATE)
- {
+ {
*stack += allocVariables (tree->values.sym);
autoInit = gatherAutoInit (tree->values.sym);
-
+
/* if there are auto inits then do them */
if (autoInit)
tree->left = newNode (NULLOP, autoInit, tree->left);
- }
+ }
else /* action is deallocate */
deallocLocal (tree->values.sym);
}
return tree;
}
+/*-------------------------------------------------------------*/
+/* constExprTree - returns TRUE if this tree is a constant */
+/* expression */
+/*-------------------------------------------------------------*/
+bool constExprTree (ast *cexpr) {
+
+ if (!cexpr) {
+ return TRUE;
+ }
+
+ cexpr = decorateType (resolveSymbols (cexpr));
+
+ switch (cexpr->type)
+ {
+ case EX_VALUE:
+ if (IS_AST_LIT_VALUE(cexpr)) {
+ // this is a literal
+ return TRUE;
+ }
+ if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
+ // a function's address will never change
+ return TRUE;
+ }
+ if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
+ // an array's address will never change
+ return TRUE;
+ }
+ if (IS_AST_SYM_VALUE(cexpr) &&
+ IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
+ // a symbol in code space will never change
+ // This is only for the 'char *s="hallo"' case and will have to leave
+ return TRUE;
+ }
+ return FALSE;
+ case EX_LINK:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "unexpected link in expression tree\n");
+ return FALSE;
+ case EX_OP:
+ if (cexpr->opval.op==ARRAYINIT) {
+ // this is a list of literals
+ return TRUE;
+ }
+ if (cexpr->opval.op=='=') {
+ return constExprTree(cexpr->right);
+ }
+ if (cexpr->opval.op==CAST) {
+ // cast ignored, maybe we should throw a warning here?
+ return constExprTree(cexpr->right);
+ }
+ if (cexpr->opval.op=='&') {
+ return TRUE;
+ }
+ if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
+ return FALSE;
+ }
+ if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
/*-----------------------------------------------------------------*/
/* constExprValue - returns the value of a constant expression */
/* or NULL if it is not a constant expression */
val->sym = cexpr->opval.val->sym;
val->sym->type = copyLinkChain (cexpr->ftype);
val->sym->etype = getSpec (val->sym->type);
- strcpy (val->name, cexpr->opval.val->sym->rname);
+ strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
return val;
}
/* if we are casting a literal value then */
if (IS_AST_OP (cexpr) &&
cexpr->opval.op == CAST &&
- IS_LITERAL (cexpr->left->ftype))
+ IS_LITERAL (cexpr->right->ftype))
return valCastLiteral (cexpr->ftype,
- floatFromVal (cexpr->left->opval.val));
+ floatFromVal (cexpr->right->opval.val));
if (IS_AST_VALUE (cexpr))
return cexpr->opval.val;
/* if we reach the end or a leaf then true */
if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
return TRUE;
-
-
+
/* if anything else is "volatile" */
if (IS_VOLATILE (TETYPE (pbody)))
return FALSE;
{
/*------------------------------------------------------------------*/
case '[':
+ // if the loopvar is used as an index
+ if (astHasSymbol(pbody->right, sym)) {
+ return FALSE;
+ }
return isConformingBody (pbody->right, sym, body);
/*------------------------------------------------------------------*/
if (astHasVolatile (pbody->left))
return FALSE;
- if (IS_AST_SYM_VALUE (pbody->left) &&
- isSymbolEqual (AST_SYMBOL (pbody->left), sym))
- return FALSE;
+ if (IS_AST_SYM_VALUE (pbody->left)) {
+ // if the loopvar has an assignment
+ if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
+ return FALSE;
+ // if the loopvar is used in another (maybe conditional) block
+ if (astHasSymbol (pbody->right, sym) &&
+ (pbody->level > body->level)) {
+ return FALSE;
+ }
+ }
if (astHasVolatile (pbody->left))
return FALSE;
/* function call */
/*----------------------------*/
case CALL:
+ /* if local & not passed as paramater then ok */
+ if (sym->level && !astHasSymbol(pbody->right,sym))
+ return TRUE;
return FALSE;
/*------------------------------------------------------------------*/
rloop = newNode (NULLOP,
createIf (newAst_VALUE (symbolVal (sym)),
newNode (GOTO,
- newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
+ newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
NULL), NULL),
newNode ('=',
newAst_VALUE (symbolVal (sym)),
end));
-
+
replLoopSym (loop->left, sym);
-
+ setAstLineno (rloop, init->lineno);
+
rloop = newNode (NULLOP,
newNode ('=',
newAst_VALUE (symbolVal (sym)),
loop->left,
newNode (NULLOP,
newNode (SUB_ASSIGN,
- newAst_VALUE (symbolVal (sym)),
- newAst_VALUE (constVal ("1"))),
+ newAst_VALUE (symbolVal (sym)),
+ newAst_VALUE (constVal ("1"))),
rloop))));
-
+
+ rloop->lineno=init->lineno;
return decorateType (rloop);
-
-}
-
-//#define DEMAND_INTEGER_PROMOTION
-
-#ifdef DEMAND_INTEGER_PROMOTION
-
-/*-----------------------------------------------------------------*/
-/* walk a tree looking for the leaves. Add a typecast to the given */
-/* type to each value leaf node. */
-/*-----------------------------------------------------------------*/
-void
-pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr)
-{
- if (!node || IS_CALLOP(node))
- {
- /* WTF? We should never get here. */
- return;
- }
-
- if (!node->left && !node->right)
- {
- /* We're at a leaf; if it's a value, apply the typecast */
- if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node)))
- {
- *parentPtr = decorateType (newNode (CAST,
- newAst_LINK (copyLinkChain (type)),
- node));
- }
- }
- else
- {
- if (node->left)
- {
- pushTypeCastToLeaves (type, node->left, &(node->left));
- }
- if (node->right)
- {
- pushTypeCastToLeaves (type, node->right, &(node->right));
- }
- }
-}
-
-#endif
-
-/*-----------------------------------------------------------------*/
-/* Given an assignment operation in a tree, determine if the LHS */
-/* (the result) has a different (integer) type than the RHS. */
-/* If so, walk the RHS and add a typecast to the type of the LHS */
-/* to all leaf nodes. */
-/*-----------------------------------------------------------------*/
-void
-propAsgType (ast * tree)
-{
-#ifdef DEMAND_INTEGER_PROMOTION
- if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
- {
- /* Nothing to do here... */
- return;
- }
-
- if (getSize (LTYPE (tree)) > getSize (RTYPE (tree)))
- {
- pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right));
- }
-#else
- (void) tree;
-#endif
+
}
/*-----------------------------------------------------------------*/
tree->decorated = 1;
+#if 0
/* print the line */
/* if not block & function */
if (tree->type == EX_OP &&
filename = tree->filename;
lineno = tree->lineno;
}
+#endif
/* if any child is an error | this one is an error do nothing */
if (tree->isError ||
/*----------------------------*/
/* leaf has been reached */
/*----------------------------*/
+ lineno=tree->lineno;
/* if this is of type value */
/* just get the type */
if (tree->type == EX_VALUE)
/* otherwise just copy the type information */
COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
- if (funcInChain (tree->opval.val->type))
- {
- tree->hasVargs = tree->opval.val->sym->hasVargs;
- tree->args = copyValueChain (tree->opval.val->sym->args);
- }
return tree;
}
/* and mark it as referenced */
tree->opval.val->sym->isref = 1;
- /* if this is of type function or function pointer */
- if (funcInChain (tree->opval.val->type))
- {
- tree->hasVargs = tree->opval.val->sym->hasVargs;
- tree->args = copyValueChain (tree->opval.val->sym->args);
-
- }
}
}
}
ast *dtl, *dtr;
dtl = decorateType (tree->left);
- dtr = decorateType (tree->right);
+ /* delay right side for '?' operator since conditional macro expansions might
+ rely on this */
+ dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
/* this is to take care of situations
when the tree gets rewritten */
tree->left = dtl;
if (dtr != tree->right)
tree->right = dtr;
+
+ if (IS_AST_OP(tree) &&
+ (tree->opval.op == CAST || tree->opval.op == '=') &&
+ (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
+ (getSize(RTYPE(tree)) < INTSIZE)) {
+ // this is a cast/assign to a bigger type
+ if (IS_AST_OP(tree->right) &&
+ IS_INTEGRAL(tree->right->ftype) &&
+ (tree->right->opval.op == LEFT_OP ||
+ tree->right->opval.op == '*' ||
+ tree->right->opval.op == '+' ||
+ tree->right->opval.op == '-') &&
+ tree->right->right) {
+ // we should cast an operand instead of the result
+ tree->right->decorated = 0;
+ tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
+ tree->right->left);
+ tree->right = decorateType(tree->right);
+ }
+ }
}
/* depending on type of operator do */
switch (tree->opval.op)
{
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* array node */
- /*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* array node */
+ /*----------------------------*/
case '[':
/* determine which is the array & which the index */
RRVAL (tree) = 1;
COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
if (IS_PTR(LTYPE(tree))) {
- SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
+ SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
}
return tree;
}
TTYPE (tree) = structElemType (LTYPE (tree),
(tree->right->type == EX_VALUE ?
- tree->right->opval.val : NULL), &tree->args);
+ tree->right->opval.val : NULL));
TETYPE (tree) = getSpec (TTYPE (tree));
return tree;
/*----------------------------*/
case PTR_OP:
/* if not pointer to a structure */
- if (!IS_PTR (LTYPE (tree)))
+ if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
{
werror (E_PTR_REQD);
goto errorTreeReturn;
TTYPE (tree) = structElemType (LTYPE (tree)->next,
(tree->right->type == EX_VALUE ?
- tree->right->opval.val : NULL), &tree->args);
+ tree->right->opval.val : NULL));
TETYPE (tree) = getSpec (TTYPE (tree));
+
+ /* adjust the storage class */
+ switch (DCL_TYPE(tree->left->ftype)) {
+ case POINTER:
+ break;
+ case FPOINTER:
+ SPEC_SCLS(TETYPE(tree)) = S_XDATA;
+ break;
+ case CPOINTER:
+ SPEC_SCLS(TETYPE(tree)) = S_CODE;
+ break;
+ case GPOINTER:
+ break;
+ case PPOINTER:
+ SPEC_SCLS(TETYPE(tree)) = S_XSTACK;
+ break;
+ case IPOINTER:
+ SPEC_SCLS(TETYPE(tree)) = S_IDATA;
+ break;
+ case EEPPOINTER:
+ SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
+ break;
+ case UPOINTER:
+ case ARRAY:
+ case FUNCTION:
+ break;
+ }
+
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* ++/-- operation */
-/*----------------------------*/
+ /*----------------------------*/
case INC_OP: /* incerement operator unary so left only */
case DEC_OP:
{
sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
- if (!tree->initMode && IS_CONSTANT (TETYPE (tree)))
- werror (E_CODE_WRITE, "++/--");
+ if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
+ werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
if (tree->right)
RLVAL (tree) = 1;
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* bitwise and */
-/*----------------------------*/
+ /*----------------------------*/
case '&': /* can be unary */
/* if right is NULL then unary operation */
if (tree->right) /* not an unary operation */
return decorateType (otree);
}
-#if 0
- // we can't do this because of "(int & 0xff) << 3"
-
- /* if right or left is literal then result of that type */
- if (IS_LITERAL (RTYPE (tree)))
- {
-
- TTYPE (tree) = copyLinkChain (RTYPE (tree));
- TETYPE (tree) = getSpec (TTYPE (tree));
- SPEC_SCLS (TETYPE (tree)) = S_AUTO;
- }
- else
- {
- if (IS_LITERAL (LTYPE (tree)))
- {
- TTYPE (tree) = copyLinkChain (LTYPE (tree));
- TETYPE (tree) = getSpec (TTYPE (tree));
- SPEC_SCLS (TETYPE (tree)) = S_AUTO;
-
- }
- else
- {
- TTYPE (tree) =
- computeType (LTYPE (tree), RTYPE (tree));
- TETYPE (tree) = getSpec (TTYPE (tree));
- }
- }
-#else
TTYPE (tree) =
computeType (LTYPE (tree), RTYPE (tree));
TETYPE (tree) = getSpec (TTYPE (tree));
-#endif
+
LRVAL (tree) = RRVAL (tree) = 1;
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* address of */
-/*----------------------------*/
- p = newLink ();
- p->class = DECLARATOR;
+ /*----------------------------*/
+ p = newLink (DECLARATOR);
/* if bit field then error */
if (IS_BITVAR (tree->left->etype))
{
- werror (E_ILLEGAL_ADDR, "addrress of bit variable");
+ werror (E_ILLEGAL_ADDR, "address of bit variable");
goto errorTreeReturn;
}
if (IS_FUNC (LTYPE (tree)))
{
- werror (E_ILLEGAL_ADDR, "address of function");
+ // this ought to be ignored
+ return (tree->left);
+ }
+
+ if (IS_LITERAL(LTYPE(tree)))
+ {
+ werror (E_ILLEGAL_ADDR, "address of literal");
goto errorTreeReturn;
}
- if (LRVAL (tree))
+ if (LRVAL (tree))
{
werror (E_LVALUE_REQUIRED, "address of");
goto errorTreeReturn;
DCL_TYPE (p) = IPOINTER;
else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
DCL_TYPE (p) = EEPPOINTER;
+ else if (SPEC_OCLS(tree->left->etype))
+ DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
else
- DCL_TYPE (p) = POINTER;
+ DCL_TYPE (p) = POINTER;
if (IS_AST_SYM_VALUE (tree->left))
{
p->next = LTYPE (tree);
TTYPE (tree) = p;
TETYPE (tree) = getSpec (TTYPE (tree));
- DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
- DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
+ DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
+ DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
LLVAL (tree) = 1;
TLVAL (tree) = 1;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* bitwise or */
-/*----------------------------*/
+ /*----------------------------*/
case '|':
/* if the rewrite succeeds then don't go any furthur */
{
ast *wtree = optimizeRRCRLC (tree);
if (wtree != tree)
return decorateType (wtree);
+ // fall through
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* bitwise xor */
-/*----------------------------*/
+ /*----------------------------*/
case '^':
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
{
computeType (LTYPE (tree),
RTYPE (tree)));
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* division */
-/*----------------------------*/
+ /*----------------------------*/
case '/':
if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
{
RTYPE (tree)));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* modulus */
-/*----------------------------*/
+ /*----------------------------*/
case '%':
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
{
RTYPE (tree)));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
-/* address dereference */
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* address dereference */
+ /*----------------------------*/
case '*': /* can be unary : if right is null then unary operation */
if (!tree->right)
{
werror (E_LVALUE_REQUIRED, "pointer deref");
goto errorTreeReturn;
}
- TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
- LTYPE (tree)->next : NULL);
- TETYPE (tree) = getSpec (TTYPE (tree));
- tree->args = tree->left->args;
- tree->hasVargs = tree->left->hasVargs;
+ TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
+ TETYPE (tree) = getSpec (TTYPE (tree));
SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* multiplication */
-/*----------------------------*/
+ /*----------------------------*/
if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
{
werror (E_INVALID_OP, "multiplication");
}
LRVAL (tree) = RRVAL (tree) = 1;
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ computeType (LTYPE (tree),
+ RTYPE (tree)));
+
/* promote result to int if left & right are char
this will facilitate hardware multiplies 8bit x 8bit = 16bit */
if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree)));
SPEC_NOUN(TETYPE(tree)) = V_INT;
- } else {
- TETYPE (tree) = getSpec (TTYPE (tree) =
- computeType (LTYPE (tree),
- RTYPE (tree)));
}
+
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* unary '+' operator */
-/*----------------------------*/
+ /*----------------------------*/
case '+':
/* if unary plus */
if (!tree->right)
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* addition */
-/*----------------------------*/
+ /*----------------------------*/
/* this is not a unary operation */
/* if both pointers then problem */
LRVAL (tree) = RRVAL (tree) = 1;
/* if the left is a pointer */
- if (IS_PTR (LTYPE (tree)))
+ if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
TETYPE (tree) = getSpec (TTYPE (tree) =
LTYPE (tree));
else
RTYPE (tree)));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* unary '-' */
-/*----------------------------*/
+ /*----------------------------*/
case '-': /* can be unary */
/* if right is null then unary */
if (!tree->right)
return tree;
}
LRVAL (tree) = 1;
- TTYPE (tree) = LTYPE (tree);
+ TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* subtraction */
-/*----------------------------*/
+ /*----------------------------*/
if (!(IS_PTR (LTYPE (tree)) ||
IS_ARRAY (LTYPE (tree)) ||
LRVAL (tree) = RRVAL (tree) = 1;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* compliment */
-/*----------------------------*/
+ /*----------------------------*/
case '~':
/* can be only integral type */
if (!IS_INTEGRAL (LTYPE (tree)))
COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* not */
-/*----------------------------*/
+ /*----------------------------*/
case '!':
/* can be pointer */
if (!IS_ARITHMETIC (LTYPE (tree)) &&
TTYPE (tree) = TETYPE (tree) = newCharLink ();
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* shift */
-/*----------------------------*/
+ /*----------------------------*/
case RRC:
case RLC:
TTYPE (tree) = LTYPE (tree);
tree->opval.val->type);
return tree;
}
+
/* if only the right side is a literal & we are
shifting more than size of the left operand then zero */
if (IS_LITERAL (RTYPE (tree)) &&
((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
(getSize (LTYPE (tree)) * 8))
{
- werror (W_SHIFT_CHANGED,
- (tree->opval.op == LEFT_OP ? "left" : "right"));
- tree->type = EX_VALUE;
- tree->left = tree->right = NULL;
- tree->opval.val = constVal ("0");
- TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
- return tree;
+ if (tree->opval.op==LEFT_OP ||
+ (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
+ lineno=tree->lineno;
+ werror (W_SHIFT_CHANGED,
+ (tree->opval.op == LEFT_OP ? "left" : "right"));
+ tree->type = EX_VALUE;
+ tree->left = tree->right = NULL;
+ tree->opval.val = constVal ("0");
+ TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
+ return tree;
+ }
}
LRVAL (tree) = RRVAL (tree) = 1;
if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
/* make sure the type is complete and sane */
checkTypeSanity(LETYPE(tree), "(cast)");
-#if 1
+#if 0
/* if the right is a literal replace the tree */
if (IS_LITERAL (RETYPE (tree))) {
if (!IS_PTR (LTYPE (tree))) {
((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
sym_link *rest = LTYPE(tree)->next;
werror(W_LITERAL_GENERIC);
- TTYPE(tree) = newLink();
+ TTYPE(tree) = newLink(DECLARATOR);
DCL_TYPE(TTYPE(tree)) = FPOINTER;
TTYPE(tree)->next = rest;
tree->left->opval.lnk = TTYPE(tree);
LRVAL (tree) = 1;
}
#else
+#if 0 // this is already checked, now this could be explicit
+ /* if pointer to struct then check names */
+ if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
+ IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
+ strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
+ {
+ werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
+ SPEC_STRUCT(LETYPE(tree))->tag);
+ }
+#endif
/* if the right is a literal replace the tree */
if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
tree->type = EX_VALUE;
TTYPE (tree) = LTYPE (tree);
LRVAL (tree) = 1;
}
-#endif
-
+#endif
TETYPE (tree) = getSpec (TTYPE (tree));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* logical &&, || */
-/*----------------------------*/
+ /*----------------------------*/
case AND_OP:
case OR_OP:
/* each must me arithmetic type or be a pointer */
TTYPE (tree) = TETYPE (tree) = newCharLink ();
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* comparison operators */
-/*----------------------------*/
+ /*----------------------------*/
case '>':
case '<':
case LE_OP:
/* if they are pointers they must be castable */
if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
{
+ if (tree->opval.op==EQ_OP &&
+ !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
+ // we cannot cast a gptr to a !gptr: switch the leaves
+ struct ast *s=tree->left;
+ tree->left=tree->right;
+ tree->right=s;
+ }
if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
{
werror (E_COMPARE_OP);
- fprintf (stderr, "comparing type ");
+ fprintf (stderr, "comparring type ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, "to type ");
printTypeChain (RTYPE (tree), stderr);
goto errorTreeReturn;
}
}
+ /* if unsigned value < 0 then always false */
+ /* if (unsigned value) > 0 then (unsigned value) */
+ if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
+ ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
+ if (tree->opval.op == '<') {
+ return tree->right;
+ }
+ if (tree->opval.op == '>') {
+ return tree->left;
+ }
+ }
/* if they are both literal then */
/* rewrite the tree */
if (IS_LITERAL (RTYPE (tree)) &&
TTYPE (tree) = TETYPE (tree) = newCharLink ();
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* sizeof */
-/*----------------------------*/
+ /*----------------------------*/
case SIZEOF: /* evaluate wihout code generation */
/* change the type to a integer */
tree->type = EX_VALUE;
- sprintf (buffer, "%d", (getSize (tree->right->ftype)));
+ SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
tree->opval.val = constVal (buffer);
tree->right = tree->left = NULL;
TETYPE (tree) = getSpec (TTYPE (tree) =
tree->opval.val->type);
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* typeof */
+ /*----------------------------*/
+ case TYPEOF:
+ /* return typeof enum value */
+ tree->type = EX_VALUE;
+ {
+ int typeofv = 0;
+ if (IS_SPEC(tree->right->ftype)) {
+ switch (SPEC_NOUN(tree->right->ftype)) {
+ case V_INT:
+ if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
+ else typeofv = TYPEOF_INT;
+ break;
+ case V_FLOAT:
+ typeofv = TYPEOF_FLOAT;
+ break;
+ case V_CHAR:
+ typeofv = TYPEOF_CHAR;
+ break;
+ case V_VOID:
+ typeofv = TYPEOF_VOID;
+ break;
+ case V_STRUCT:
+ typeofv = TYPEOF_STRUCT;
+ break;
+ case V_BIT:
+ typeofv = TYPEOF_BIT;
+ break;
+ case V_SBIT:
+ typeofv = TYPEOF_SBIT;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (DCL_TYPE(tree->right->ftype)) {
+ case POINTER:
+ typeofv = TYPEOF_POINTER;
+ break;
+ case FPOINTER:
+ typeofv = TYPEOF_FPOINTER;
+ break;
+ case CPOINTER:
+ typeofv = TYPEOF_CPOINTER;
+ break;
+ case GPOINTER:
+ typeofv = TYPEOF_GPOINTER;
+ break;
+ case PPOINTER:
+ typeofv = TYPEOF_PPOINTER;
+ break;
+ case IPOINTER:
+ typeofv = TYPEOF_IPOINTER;
+ break;
+ case ARRAY:
+ typeofv = TYPEOF_ARRAY;
+ break;
+ case FUNCTION:
+ typeofv = TYPEOF_FUNCTION;
+ break;
+ default:
+ break;
+ }
+ }
+ SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
+ tree->opval.val = constVal (buffer);
+ tree->right = tree->left = NULL;
+ TETYPE (tree) = getSpec (TTYPE (tree) =
+ tree->opval.val->type);
+ }
+ return tree;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* conditional operator '?' */
-/*----------------------------*/
+ /*----------------------------*/
case '?':
/* the type is value of the colon operator (on the right) */
assert(IS_COLON_OP(tree->right));
- TTYPE (tree) = RTYPE(tree); // #HACK LTYPE(tree).
- TETYPE (tree) = getSpec (TTYPE (tree));
+ /* if already known then replace the tree : optimizer will do it
+ but faster to do it here */
+ if (IS_LITERAL (LTYPE(tree))) {
+ if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
+ return decorateType(tree->right->left) ;
+ } else {
+ return decorateType(tree->right->right) ;
+ }
+ } else {
+ tree->right = decorateType(tree->right);
+ TTYPE (tree) = RTYPE(tree);
+ TETYPE (tree) = getSpec (TTYPE (tree));
+ }
return tree;
case ':':
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+#if 0 // assignment operators are converted by the parser
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* assignment operators */
-/*----------------------------*/
+ /*----------------------------*/
case MUL_ASSIGN:
case DIV_ASSIGN:
/* for these it must be both must be integral */
RRVAL (tree) = 1;
TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
- if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
- werror (E_CODE_WRITE, " ");
+ if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
+ werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "*= or /=");
+ werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
goto errorTreeReturn;
}
LLVAL (tree) = 1;
- propAsgType (tree);
-
return tree;
case AND_ASSIGN:
TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
- werror (E_CODE_WRITE, " ");
+ werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
if (LRVAL (tree))
{
}
LLVAL (tree) = 1;
- propAsgType (tree);
-
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* -= operator */
-/*----------------------------*/
+ /*----------------------------*/
case SUB_ASSIGN:
if (!(IS_PTR (LTYPE (tree)) ||
IS_ARITHMETIC (LTYPE (tree))))
RTYPE (tree)));
if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
- werror (E_CODE_WRITE, " ");
+ werror (E_CODE_WRITE, "-=");
if (LRVAL (tree))
{
}
LLVAL (tree) = 1;
- propAsgType (tree);
-
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* += operator */
-/*----------------------------*/
+ /*----------------------------*/
case ADD_ASSIGN:
/* this is not a unary operation */
/* if both pointers then problem */
RTYPE (tree)));
if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
- werror (E_CODE_WRITE, " ");
+ werror (E_CODE_WRITE, "+=");
if (LRVAL (tree))
{
tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
tree->opval.op = '=';
- propAsgType (tree);
-
return tree;
+#endif
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* straight assignemnt */
-/*----------------------------*/
+ /*----------------------------*/
case '=':
/* cannot be an aggregate */
if (IS_AGGREGATE (LTYPE (tree)))
if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
{
werror (E_TYPE_MISMATCH, "assignment", " ");
- fprintf (stderr, "type --> '");
- printTypeChain (RTYPE (tree), stderr);
- fprintf (stderr, "' ");
- fprintf (stderr, "assigned to type --> '");
- printTypeChain (LTYPE (tree), stderr);
- fprintf (stderr, "'\n");
- goto errorTreeReturn;
+ printFromToType(RTYPE(tree),LTYPE(tree));
+ //goto errorTreeReturn;
}
/* if the left side of the tree is of type void
if (IS_VOID (LTYPE (tree)))
{
werror (E_CAST_ZERO);
- fprintf (stderr, "type --> '");
- printTypeChain (RTYPE (tree), stderr);
- fprintf (stderr, "' ");
- fprintf (stderr, "assigned to type --> '");
- printTypeChain (LTYPE (tree), stderr);
- fprintf (stderr, "'\n");
- }
-
- /* extra checks for pointer types */
- if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) &&
- !IS_GENPTR (LTYPE (tree)))
- {
- if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree)))
- werror (W_PTR_ASSIGN);
+ printFromToType(RTYPE(tree), LTYPE(tree));
}
TETYPE (tree) = getSpec (TTYPE (tree) =
RRVAL (tree) = 1;
LLVAL (tree) = 1;
if (!tree->initMode ) {
- if (IS_CONSTANT (LETYPE (tree))) {
- werror (E_CODE_WRITE, " ");
- }
+ if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
+ werror (E_CODE_WRITE, "=");
}
if (LRVAL (tree))
{
goto errorTreeReturn;
}
- propAsgType (tree);
-
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* comma operator */
-/*----------------------------*/
+ /*----------------------------*/
case ',':
TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* function call */
-/*----------------------------*/
+ /*----------------------------*/
case CALL:
parmNumber = 1;
if (processParms (tree->left,
- tree->left->args,
- tree->right, &parmNumber, TRUE))
+ FUNC_ARGS(tree->left->ftype),
+ tree->right, &parmNumber, TRUE)) {
goto errorTreeReturn;
+ }
- if (options.stackAuto || IS_RENT (LETYPE (tree)))
+ if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) &&
+ !IFFUNC_ISBUILTIN(LTYPE(tree)))
{
- tree->left->args = reverseVal (tree->left->args);
+ //FUNC_ARGS(tree->left->ftype) =
+ //reverseVal (FUNC_ARGS(tree->left->ftype));
reverseParms (tree->right);
}
- tree->args = tree->left->args;
TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* return statement */
-/*----------------------------*/
+ /*----------------------------*/
case RETURN:
if (!tree->right)
goto voidcheck;
if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
{
werror (W_RETURN_MISMATCH);
+ printFromToType (RTYPE(tree), currFunc->type->next);
goto errorTreeReturn;
}
/* if there is going to be a casing required then add it */
if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
{
-#if 0 && defined DEMAND_INTEGER_PROMOTION
- if (IS_INTEGRAL (currFunc->type->next))
- {
- pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
- }
- else
-#endif
- {
- tree->right =
- decorateType (newNode (CAST,
- newAst_LINK (copyLinkChain (currFunc->type->next)),
- tree->right));
- }
+ tree->right =
+ decorateType (newNode (CAST,
+ newAst_LINK (copyLinkChain (currFunc->type->next)),
+ tree->right));
}
RRVAL (tree) = 1;
TTYPE (tree) = TETYPE (tree) = NULL;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* switch statement */
-/*----------------------------*/
+ /*----------------------------*/
case SWITCH:
/* the switch value must be an integer */
if (!IS_INTEGRAL (LTYPE (tree)))
TTYPE (tree) = TETYPE (tree) = NULL;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* ifx Statement */
-/*----------------------------*/
+ /*----------------------------*/
case IFX:
tree->left = backPatchLabels (tree->left,
tree->trueLabel,
TTYPE (tree) = TETYPE (tree) = NULL;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* for Statement */
-/*----------------------------*/
+ /*----------------------------*/
case FOR:
decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
checkTypeSanity(type, "(sizeof)");
/* get the size and convert it to character */
- sprintf (buff, "%d", getSize (type));
+ SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
/* now convert into value */
return constVal (buff);
static int localLbl = 0;
symbol *localLabel;
- sprintf (buffer, "_and_%d", localLbl++);
+ SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
localLabel = newSymbol (buffer, NestLevel);
tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
static int localLbl = 0;
symbol *localLabel;
- sprintf (buffer, "_or_%d", localLbl++);
+ SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
localLabel = newSymbol (buffer, NestLevel);
tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
ast *ex;
/* if the block has nothing */
- if (!body)
+ if (!body && !decl)
return NULL;
ex = newNode (BLOCK, NULL, body);
ex->values.sym = decl;
-
+
ex->right = ex->right;
ex->level++;
ex->lineno = 0;
label = newSymbol (label->name, label->level);
/* change the name before putting it in add _ */
- sprintf (name, "%s", label->name);
+ SNPRINTF(name, sizeof(name), "%s", label->name);
/* put the label in the LabelSymbol table */
/* but first check if a label of the same */
}
/* create the case label */
- sprintf (caseLbl, "_case_%d_%d",
+ SNPRINTF(caseLbl, sizeof(caseLbl),
+ "_case_%d_%d",
swStat->values.switchVals.swNum,
(int) floatFromVal (caseVal->opval.val));
swStat->values.switchVals.swDefault = 1;
/* create the label */
- sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
+ SNPRINTF (defLbl, sizeof(defLbl),
+ "_default_%d", swStat->values.switchVals.swNum);
return createLabel (newSymbol (defLbl, 0), stmnt);
}
symbol *ifTrue, *ifFalse, *ifEnd;
/* if neither exists */
- if (!elseBody && !ifBody)
- return condAst;
+ if (!elseBody && !ifBody) {
+ // if there are no side effects (i++, j() etc)
+ if (!hasSEFcalls(condAst)) {
+ return condAst;
+ }
+ }
/* create the labels */
- sprintf (buffer, "_iffalse_%d", Lblnum);
+ SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
ifFalse = newSymbol (buffer, NestLevel);
/* if no else body then end == false */
if (!elseBody)
ifEnd = ifFalse;
else
{
- sprintf (buffer, "_ifend_%d", Lblnum);
+ SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
ifEnd = newSymbol (buffer, NestLevel);
}
- sprintf (buffer, "_iftrue_%d", Lblnum);
+ SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
ifTrue = newSymbol (buffer, NestLevel);
Lblnum++;
/*-----------------------------------------------------------------*/
/* optimizeCompare - otimizes compares for bit variables */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
optimizeCompare (ast * root)
{
ast *optExpr = NULL;
sym_link *fetype;
iCode *piCode = NULL;
+ if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
+ fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
+
/* if check function return 0 then some problem */
- if (checkFunction (name) == 0)
+ if (checkFunction (name, NULL) == 0)
return NULL;
/* create a dummy block if none exists */
}
name->lastLine = yylineno;
currFunc = name;
- processFuncArgs (currFunc, 0);
/* set the stack pointer */
/* PENDING: check this for the mcs51 */
stackPtr = -port->stack.direction * port->stack.call_overhead;
- if (IS_ISR (name->etype))
+ if (IFFUNC_ISISR (name->type))
stackPtr -= port->stack.direction * port->stack.isr_overhead;
- if (IS_RENT (name->etype) || options.stackAuto)
+ if (IFFUNC_ISREENT (name->type) || options.stackAuto)
stackPtr -= port->stack.direction * port->stack.reent_overhead;
xstackPtr = -port->stack.direction * port->stack.call_overhead;
fetype = getSpec (name->type); /* get the specifier for the function */
/* if this is a reentrant function then */
- if (IS_RENT (fetype))
+ if (IFFUNC_ISREENT (name->type))
reentrant++;
- allocParms (name->args); /* allocate the parameters */
+ allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
/* do processing for parameters that are passed in registers */
- processRegParms (name->args, body);
+ processRegParms (FUNC_ARGS(name->type), body);
/* set the stack pointer */
stackPtr = 0;
name->stack = SPEC_STAK (fetype) = stack;
/* name needs to be mangled */
- sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
+ SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
body = resolveSymbols (body); /* resolve the symbols */
body = decorateType (body); /* propagateType & do semantic checks */
- ex = newAst_VALUE (symbolVal (name)); /* create name */
+ ex = newAst_VALUE (symbolVal (name)); /* create name */
ex = newNode (FUNCTION, ex, body);
- ex->values.args = name->args;
-
+ ex->values.args = FUNC_ARGS(name->type);
+ ex->decorated=1;
+ if (options.dump_tree) PA(ex);
if (fatalError)
{
werror (E_FUNC_NO_CODE, name->name);
/* dealloc the block variables */
processBlockVars (body, &stack, DEALLOCATE);
+ outputDebugStackSymbols();
/* deallocate paramaters */
- deallocParms (name->args);
+ deallocParms (FUNC_ARGS(name->type));
- if (IS_RENT (fetype))
+ if (IFFUNC_ISREENT (name->type))
reentrant--;
/* we are done freeup memory & cleanup */
noLineno--;
- labelKey = 1;
+ if (port->reset_labelKey) labelKey = 1;
name->key = 0;
- name->fbody = 1;
+ FUNC_HASBODY(name->type) = 1;
addSet (&operKeyReset, name);
applyToSet (operKeyReset, resetParmKey);
- if (options.debug)
- cdbStructBlock (1, cdbFile);
+ if (options.debug)
+ cdbStructBlock(1);
cleanUpLevel (LabelTab, 0);
cleanUpBlock (StructTab, 1);
}
-#define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
+#define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
/*-----------------------------------------------------------------*/
/* ast_print : prints the ast (for debugging purposes) */
/*-----------------------------------------------------------------*/
}
if (tree->opval.op == FUNCTION) {
- fprintf(outfile,"FUNCTION (%p) type (",tree);
+ int arg=0;
+ value *args=FUNC_ARGS(tree->left->opval.val->type);
+ fprintf(outfile,"FUNCTION (%s=%p) type (",
+ tree->left->opval.val->name, tree);
printTypeChain (tree->ftype,outfile);
+ fprintf(outfile,") args (");
+ do {
+ if (arg) {
+ fprintf (outfile, ", ");
+ }
+ printTypeChain (args ? args->type : NULL, outfile);
+ arg++;
+ args= args ? args->next : NULL;
+ } while (args);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent);
+ ast_print(tree->right,outfile,indent);
return ;
}
if (tree->opval.op == BLOCK) {
symbol *decls = tree->values.sym;
+ INDENT(indent,outfile);
fprintf(outfile,"{\n");
while (decls) {
- INDENT(indent+4,outfile);
- fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
+ decls->name, decls);
printTypeChain(decls->type,outfile);
fprintf(outfile,")\n");
decls = decls->next;
}
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->right,outfile,indent+2);
+ INDENT(indent,outfile);
fprintf(outfile,"}\n");
return;
}
if (tree->opval.op == NULLOP) {
- fprintf(outfile,"\n");
ast_print(tree->left,outfile,indent);
- fprintf(outfile,"\n");
ast_print(tree->right,outfile,indent);
return ;
}
} else {
fprintf(outfile,"SYMBOL ");
}
- fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
+ fprintf(outfile,"(%s=%p)",
+ tree->opval.val->sym->name,tree);
}
if (tree->ftype) {
fprintf(outfile," type (");
fprintf(outfile,"ARRAY_OP (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
/*------------------------------------------------------------------*/
fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
fprintf(outfile,"INC_OP (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
case DEC_OP:
fprintf(outfile,"DEC_OP (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
fprintf(outfile,"& (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
} else {
fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
}
return ;
/*----------------------------*/
fprintf(outfile,"OR (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"XOR (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
fprintf(outfile,"DIV (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"MOD (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
fprintf(outfile,"DEREF (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
}
/*------------------------------------------------------------------*/
fprintf(outfile,"MULT (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
fprintf(outfile,"UPLUS (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
} else {
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"ADD (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
}
return;
/*------------------------------------------------------------------*/
fprintf(outfile,"UMINUS (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
} else {
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"SUB (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
}
return;
/*------------------------------------------------------------------*/
fprintf(outfile,"COMPL (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"NOT (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"RRC (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
case RLC:
fprintf(outfile,"RLC (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
case GETHBIT:
fprintf(outfile,"GETHBIT (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
case LEFT_OP:
fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
case RIGHT_OP:
fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
/* casting */
/*----------------------------*/
case CAST: /* change the type */
- fprintf(outfile,"CAST (%p) type (",tree);
+ fprintf(outfile,"CAST (%p) from type (",tree);
+ printTypeChain(tree->right->ftype,outfile);
+ fprintf(outfile,") to type (");
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->right,outfile,indent+2);
return ;
case AND_OP:
fprintf(outfile,"ANDAND (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
case OR_OP:
fprintf(outfile,"OROR (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
fprintf(outfile,"GT(>) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
case '<':
fprintf(outfile,"LT(<) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
case LE_OP:
fprintf(outfile,"LE(<=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
case GE_OP:
fprintf(outfile,"GE(>=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
case EQ_OP:
fprintf(outfile,"EQ(==) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
case NE_OP:
fprintf(outfile,"NE(!=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
/*------------------------------------------------------------------*/
/*----------------------------*/
/* sizeof */
fprintf(outfile,"QUEST(?) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
case ':':
fprintf(outfile,"COLON(:) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
fprintf(outfile,"MULASS(*=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
case DIV_ASSIGN:
fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
case AND_ASSIGN:
fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
case OR_ASSIGN:
- fprintf(outfile,"ORASS(*=) (%p) type (",tree);
+ fprintf(outfile,"ORASS(|=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
case XOR_ASSIGN:
- fprintf(outfile,"XORASS(*=) (%p) type (",tree);
+ fprintf(outfile,"XORASS(^=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
case RIGHT_ASSIGN:
fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
case LEFT_ASSIGN:
- fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
+ fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"COMMA(,) (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
/*------------------------------------------------------------------*/
/*----------------------------*/
fprintf(outfile,"CALL (%p) type (",tree);
printTypeChain(tree->ftype,outfile);
fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+4);
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
return;
case PARAM:
- fprintf(outfile,"PARM ");
- ast_print(tree->left,outfile,indent+4);
- if (tree->right && !IS_AST_PARAM(tree->right)) {
- fprintf(outfile,"PARM ");
- ast_print(tree->right,outfile,indent+4);
+ fprintf(outfile,"PARMS\n");
+ ast_print(tree->left,outfile,indent+2);
+ if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
+ ast_print(tree->right,outfile,indent+2);
}
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
case RETURN:
fprintf(outfile,"RETURN (%p) type (",tree);
- printTypeChain(tree->right->ftype,outfile);
+ if (tree->right) {
+ printTypeChain(tree->right->ftype,outfile);
+ }
fprintf(outfile,")\n");
- ast_print(tree->right,outfile,indent+4);
+ ast_print(tree->right,outfile,indent+2);
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
/* label statement */
/*----------------------------*/
case LABEL :
- fprintf(outfile,"LABEL (%p)",tree);
- ast_print(tree->left,outfile,indent+4);
+ fprintf(outfile,"LABEL (%p)\n",tree);
+ ast_print(tree->left,outfile,indent+2);
ast_print(tree->right,outfile,indent);
return;
/*------------------------------------------------------------------*/
fprintf(outfile,"SWITCH (%p) ",tree);
ast_print(tree->left,outfile,0);
for (val = tree->values.switchVals.swVals; val ; val = val->next) {
- INDENT(indent+4,outfile);
+ INDENT(indent+2,outfile);
fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
(int) floatFromVal(val),
tree->values.switchVals.swNum,
/* ifx Statement */
/*----------------------------*/
case IFX:
- ast_print(tree->left,outfile,indent);
- INDENT(indent,outfile);
fprintf(outfile,"IF (%p) \n",tree);
+ ast_print(tree->left,outfile,indent+2);
if (tree->trueLabel) {
- INDENT(indent,outfile);
- fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
}
if (tree->falseLabel) {
- INDENT(indent,outfile);
+ INDENT(indent+2,outfile);
fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
}
- ast_print(tree->right,outfile,indent);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+ /*----------------------------*/
+ /* goto Statement */
+ /*----------------------------*/
+ case GOTO:
+ fprintf(outfile,"GOTO (%p) \n",tree);
+ ast_print(tree->left,outfile,indent+2);
+ fprintf(outfile,"\n");
return ;
/*------------------------------------------------------------------*/
/*----------------------------*/
case FOR:
fprintf(outfile,"FOR (%p) \n",tree);
if (AST_FOR( tree, initExpr)) {
- INDENT(indent+4,outfile);
+ INDENT(indent+2,outfile);
fprintf(outfile,"INIT EXPR ");
- ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
+ ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
}
if (AST_FOR( tree, condExpr)) {
- INDENT(indent+4,outfile);
+ INDENT(indent+2,outfile);
fprintf(outfile,"COND EXPR ");
- ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
+ ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
}
if (AST_FOR( tree, loopExpr)) {
- INDENT(indent+4,outfile);
+ INDENT(indent+2,outfile);
fprintf(outfile,"LOOP EXPR ");
- ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
+ ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
}
fprintf(outfile,"FOR LOOP BODY \n");
- ast_print(tree->left,outfile,indent+4);
+ ast_print(tree->left,outfile,indent+2);
return ;
default:
return ;
void PA(ast *t)
{
- ast_print(t,stdout,1);
+ ast_print(t,stdout,0);
}