set *operKeyReset = NULL;
ast *staticAutos = NULL;
int labelKey = 1;
+static struct {
+ int count; /* number of inline functions inserted */
+ symbol * retsym; /* variable for inlined function return value */
+ symbol * retlab; /* label ending inlined function (virtual return) */
+} inlineState;
#define LRVAL(x) x->left->rvalue
#define RRVAL(x) x->right->rvalue
newAst_ (unsigned type)
{
ast *ex;
- static int oldLineno = 0;
ex = Safe_alloc ( sizeof (ast));
ex->type = type;
- ex->lineno = (noLineno ? oldLineno : mylineno);
- ex->filename = currFname;
+ ex->lineno = (noLineno ? 0 : lexLineno);
+ ex->filename = lexFilename;
ex->level = NestLevel;
ex->block = currBlockno;
ex->initMode = inInitMode;
dest = Safe_alloc ( sizeof (ast));
dest->type = src->type;
+ dest->filename = src->filename;
dest->lineno = src->lineno;
dest->level = src->level;
dest->funcName = src->funcName;
tempvar = newNode('=', newAst_VALUE(symbolVal(sym)), *treeptr);
*treeptr = newAst_VALUE(symbolVal(sym));
-
+
addSymChain(&sym);
return tempvar;
if (IS_AST_OP(target)) {
/* if this is a dereference, put the referenced item in the temporary */
- if (IS_DEREF_OP(target) || target->opval.op == PTR_OP) {
+ if (IS_DEREF_OP(target) || target->opval.op == PTR_OP) {
/* create a new temporary containing the item being dereferenced */
if (hasSEFcalls(target->left))
tempvar1 = replaceAstWithTemporary(&(target->left));
} else if (target->opval.op == '[') {
/* Array access is similar, but we have to avoid side effects in
- both values [WIML: Why not transform a[b] to *(a+b) in parser?] */
+ both values [WIML: Why not transform a[b] to *(a+b) in parser?] */
if (hasSEFcalls(target->left))
- tempvar1 = replaceAstWithTemporary(&(target->left));
+ tempvar1 = replaceAstWithTemporary(&(target->left));
if (hasSEFcalls(target->right))
- tempvar2 = replaceAstWithTemporary(&(target->right));
+ tempvar2 = replaceAstWithTemporary(&(target->right));
+ } else if ((target->opval.op == INC_OP) || (target->opval.op == DEC_OP)) {
+ /* illegal pre/post-increment/decrement */
+ werrorfl (target->filename, target->lineno, E_LVALUE_REQUIRED, "=");
} else {
/* we would have to handle '.', but it is not generated any more */
wassertl(target->opval.op != '.', "obsolete opcode in tree");
result = newNode(',', tempvar1, result);
return result;
-
+
}
/*-----------------------------------------------------------------*/
symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
- /* if found in the symbol table & they r not the same */
+ /* if found in the symbol table & they are not the same */
if (csym && tree->opval.val->sym != csym)
{
tree->opval.val->sym = csym;
}
/* if not found in the symbol table */
- /* mark it as undefined assume it is */
- /* an integer in data space */
+ /* mark it as undefined & assume it */
+ /* is an integer in data space */
if (!csym && !tree->opval.val->sym->implicit)
{
return tree;
}
-/*-----------------------------------------------------------------*/
-/* setAstLineno - walks a ast tree & sets the line number */
-/*-----------------------------------------------------------------*/
-int setAstLineno (ast * tree, int lineno)
+/*------------------------------------------------------------------------*/
+/* setAstFileLine - walks a ast tree & sets the file name and line number */
+/*------------------------------------------------------------------------*/
+int setAstFileLine (ast * tree, char *filename, int lineno)
{
if (!tree)
return 0;
+ tree->filename = filename;
tree->lineno = lineno;
- setAstLineno (tree->left, lineno);
- setAstLineno (tree->right, lineno);
+ setAstFileLine (tree->left, filename, lineno);
+ setAstFileLine (tree->right, filename, lineno);
return 0;
}
else
functype = func->ftype;
- /* if the function is being called via a pointer & */
- /* it has not been defined a reentrant then we cannot */
- /* have parameters */
+ /* if the function is being called via a pointer & */
+ /* it has not been defined reentrant then we cannot */
+ /* have parameters */
/* PIC16 port can... */
if (!TARGET_IS_PIC16)
{
if (func->type != EX_VALUE && !IFFUNC_ISREENT (functype) && !options.stackAuto)
{
- werror (W_NONRENT_ARGS);
+ werror (E_NONRENT_ARGS);
fatalError++;
return 1;
}
ast *newType = NULL;
sym_link *ftype;
- if (IS_CAST_OP (*actParm)
- || (IS_AST_LIT_VALUE (*actParm) && (*actParm)->values.literalFromCast))
+ /* don't perform integer promotion of explicitly typecasted variable arguments
+ * if sdcc extensions are enabled */
+ if (options.std_sdcc &&
+ (IS_CAST_OP (*actParm) ||
+ (IS_AST_SYM_VALUE (*actParm) && AST_VALUES (*actParm, removedCast)) ||
+ (IS_AST_LIT_VALUE (*actParm) && AST_VALUES (*actParm, literalFromCast))))
{
/* Parameter was explicitly typecast; don't touch it. */
return 0;
/* cast required; change this op to a cast. */
(*actParm)->decorated = 0;
*actParm = newNode (CAST, newType, *actParm);
+ (*actParm)->filename = (*actParm)->right->filename;
(*actParm)->lineno = (*actParm)->right->lineno;
decorateType (*actParm, RESULT_TYPE_NONE);
(*actParm)->etype = getSpec ((*actParm)->ftype = copyLinkChain ((*actParm)->ftype));
SPEC_REGPARM ((*actParm)->etype) = SPEC_REGPARM (defParm->etype);
SPEC_ARGREG ((*actParm)->etype) = SPEC_ARGREG (defParm->etype);
+
+ /* if the function is being called via a pointer & */
+ /* this parameter is not passed in registers */
+ /* then the function must be defined reentrant */
+ if (IS_FUNCPTR (func->ftype) && !SPEC_REGPARM ((*actParm)->etype) &&
+ !IFFUNC_ISREENT (functype) && !options.stackAuto)
+ {
+ werror (E_NONRENT_ARGS);
+ fatalError++;
+ return 1;
+ }
+
(*parmNumber)++;
return 0;
}
}
- if (iloop) {
- werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
- W_EXCESS_INITIALIZERS, "struct",
- sym->opval.val->sym->name);
+ if (iloop)
+ {
+ if (IS_AST_VALUE (sym))
+ werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
+ W_EXCESS_INITIALIZERS, "struct",
+ sym->opval.val->sym->name);
+ else
+ werrorfl (sym->filename, sym->lineno, E_INIT_COUNT);
}
return rast;
if (lcnt && size > lcnt)
{
// Array size was specified, and we have more initializers than needed.
- char *name=sym->opval.val->sym->name;
- int lineno=sym->opval.val->sym->lineDef;
- char *filename=sym->opval.val->sym->fileDef;
-
- werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
+ werrorfl (sym->opval.val->sym->fileDef, sym->opval.val->sym->lineDef,
+ W_EXCESS_INITIALIZERS, "array", sym->opval.val->sym->name);
}
}
else
{
// is this a better way? at least it won't crash
char *name = (IS_AST_SYM_VALUE(sym)) ? AST_SYMBOL(sym)->name : "";
- int lineno = iloop->lineno;
- char *filename = iloop->filename;
- werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
+ werrorfl (iloop->filename, iloop->lineno, W_EXCESS_INITIALIZERS, "array", name);
break;
}
&& IS_ARRAY (iexpr->ftype)))
return newNode ('=', sym, iexpr);
- /* left side is an array so we have to assign each */
- /* element */
+ /* left side is an array so we have to assign each element */
if ((IS_LITERAL (iexpr->etype) ||
SPEC_SCLS (iexpr->etype) == S_CODE)
&& IS_ARRAY (iexpr->ftype))
/*-----------------------------------------------------------------*/
/* gatherAutoInit - creates assignment expressions for initial */
-/* values */
+/* values */
/*-----------------------------------------------------------------*/
static ast *
gatherAutoInit (symbol * autoChain)
list2expr (sym->ival));
}
- setAstLineno (work, sym->lineDef);
+ setAstFileLine (work, sym->fileDef, sym->lineDef);
sym->ival = NULL;
if (staticAutos)
}
/* update lineno for error msg */
- lineno=sym->lineDef;
- setAstLineno (ilist->init.node, lineno);
+ filename = sym->fileDef;
+ lineno = sym->lineDef;
+ setAstFileLine (ilist->init.node, sym->fileDef, sym->lineDef);
if (IS_AGGREGATE (sym->type)) {
work = initAggregates (sym, sym->ival, NULL);
}
// just to be sure
- setAstLineno (work, sym->lineDef);
+ setAstFileLine (work, sym->fileDef, sym->lineDef);
sym->ival = NULL;
if (init)
unsigned int size;
// have we heard this before?
- for (sp=statsg->syms; sp; sp=sp->next) {
- sym=sp->item;
- size = getSize (sym->type);
- if (sym->isstrlit && size == getSize (val->type) &&
- !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
- // yes, this is old news. Don't publish it again.
- sym->isstrlit++; // but raise the usage count
- return symbolVal(sym);
+ for (sp = statsg->syms; sp; sp = sp->next)
+ {
+ sym = sp->item;
+ size = getSize (sym->type);
+ if (sym->isstrlit && size == getSize (val->type) &&
+ !memcmp (SPEC_CVAL (sym->etype).v_char, SPEC_CVAL (val->etype).v_char, size))
+ {
+ // yes, this is old news. Don't publish it again.
+ sym->isstrlit++; // but raise the usage count
+ return symbolVal (sym);
+ }
}
- }
SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
sym = newSymbol (name, 0); /* make it @ level 0 */
cexpr->opval.op == CAST &&
IS_LITERAL (cexpr->right->ftype))
{
- return valCastLiteral (cexpr->ftype,
- floatFromVal (cexpr->right->opval.val));
+ return valCastLiteral (cexpr->ftype,
+ floatFromVal (cexpr->right->opval.val));
}
if (IS_AST_VALUE (cexpr))
{
- return cexpr->opval.val;
+ return cexpr->opval.val;
}
if (check)
{
return cexpr->opval.val;
}
- return NULL;
+ return NULL;
}
/*-----------------------------------------------------------------*/
return isLabelInAst (label, tree->right) &&
isLabelInAst (label, tree->left);
-
}
/*-----------------------------------------------------------------*/
{
*end = newNode ('+', condExpr->left->right,
- newAst_VALUE (constVal ("1")));
+ newAst_VALUE (constCharVal (1)));
break;
}
return FALSE;
if (IS_AST_SYM_VALUE (loopExpr->left) &&
isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
IS_AST_LIT_VALUE (loopExpr->right) &&
- (int) AST_LIT_VALUE (loopExpr->right) != 1)
+ AST_ULONG_VALUE (loopExpr->right) != 1)
return TRUE;
}
}
body->type = EX_OP;
body->opval.op = '-';
body->left = newAst_VALUE (symbolVal (sym));
- body->right = newAst_VALUE (constVal ("1"));
+ body->right = newAst_VALUE (constCharVal (1));
}
end));
replLoopSym (loop->left, sym);
- setAstLineno (rloop, init->lineno);
+ setAstFileLine (rloop, init->filename, init->lineno);
rloop = newNode (NULLOP,
newNode ('=',
newNode (NULLOP,
newNode (SUB_ASSIGN,
newAst_VALUE (symbolVal (sym)),
- newAst_VALUE (constVal ("1"))),
+ newAst_VALUE (constCharVal (1))),
rloop))));
rloop->lineno=init->lineno;
if (tree->right &&
IS_AST_OP(tree->right) &&
tree->right->right &&
- (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
+ (tree->right->opval.op == (unsigned)ops[0] || tree->right->opval.op == (unsigned)ops[1]))
{
if (IS_LITERAL (RTYPE (tree->right)) !=
IS_LITERAL (LTYPE (tree->right)))
if (tree->left &&
IS_AST_OP(tree->left) &&
tree->left->right &&
- (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
+ (tree->left->opval.op == (unsigned)ops[0] || tree->left->opval.op == (unsigned)ops[1]))
{
if (IS_LITERAL (RTYPE (tree->left)) !=
IS_LITERAL (LTYPE (tree->left)))
}
if (IS_CHAR (type))
return RESULT_TYPE_CHAR;
- if ( IS_INT (type)
- && !IS_LONG (type))
+ if (IS_INT (type) && !IS_LONG (type))
return RESULT_TYPE_INT;
return RESULT_TYPE_OTHER;
}
}
tree->decorated = 0;
tree = newNode (CAST, newAst_LINK (newLink), tree);
+ tree->filename = tree->right->filename;
tree->lineno = tree->right->lineno;
/* keep unsigned type during cast to smaller type,
but not when promoting from char to int */
{
case AND_OP:
case OR_OP:
- return resultType;
+ case '!':
case '=':
case '?':
case ':':
case '|':
case '^':
case '~':
+ case LEFT_OP:
+ case LABEL:
+ return resultType;
case '*':
case '+':
case '-':
- case LABEL:
+ if ((IS_AST_VALUE (tree->left) && !IS_INTEGRAL (tree->left->opval.val->etype)) ||
+ (IS_AST_VALUE (tree->right) && !IS_INTEGRAL (tree->right->opval.val->etype)))
+ return RESULT_TYPE_NONE;
return resultType;
case '&':
if (!tree->right)
compute type of RHS, and set the symbol's type to match */
if (assignee->type == NULL && assignee->infertype) {
ast *dtr = decorateType (resolveSymbols(tree->right), RESULT_TYPE_NONE);
-
+
if (dtr != tree->right)
tree->right = dtr;
/*----------------------------*/
/* leaf has been reached */
/*----------------------------*/
- lineno=tree->lineno;
+ filename = tree->filename;
+ lineno = tree->lineno;
/* if this is of type value */
/* just get the type */
if (tree->type == EX_VALUE)
/* if the undefined flag is set then give error message */
if (tree->opval.val->sym->undefined)
{
- werror (E_ID_UNDEF, tree->opval.val->sym->name);
+ werrorfl (tree->filename, tree->lineno, E_ID_UNDEF, tree->opval.val->sym->name);
/* assume int */
TTYPE (tree) = TETYPE (tree) =
tree->opval.val->type = tree->opval.val->sym->type =
upon tree->opval.op, if resultType can be propagated */
resultTypeProp = resultTypePropagate (tree, resultType);
- if (tree->opval.op == '?')
+ if ((tree->opval.op == '?') && (resultTypeProp != RESULT_TYPE_BIT))
dtl = decorateType (tree->left, RESULT_TYPE_IFX);
else
dtl = decorateType (tree->left, resultTypeProp);
there is resultType available */
dtr = tree->right;
break;
+ case SIZEOF:
+ /* don't allocate string if it is a sizeof argument */
+ ++noAlloc;
+ dtr = decorateType (tree->right, resultTypeProp);
+ --noAlloc;
+ break;
default:
dtr = decorateType (tree->right, resultTypeProp);
break;
/* first check if this is a array or a pointer */
if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
{
- werror (E_NEED_ARRAY_PTR, "[]");
+ werrorfl (tree->filename, tree->lineno, E_NEED_ARRAY_PTR, "[]");
goto errorTreeReturn;
}
/* check if the type of the idx */
if (!IS_INTEGRAL (RTYPE (tree)))
{
- werror (E_IDX_NOT_INT);
+ werrorfl (tree->filename, tree->lineno, E_IDX_NOT_INT);
goto errorTreeReturn;
}
/* if the left is an rvalue then error */
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "array access");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "array access");
goto errorTreeReturn;
}
if (IS_LITERAL (RTYPE (tree)))
{
- int arrayIndex = (int) floatFromVal (valFromType (RETYPE (tree)));
+ int arrayIndex = (int) ulFromVal (valFromType (RETYPE (tree)));
int arraySize = DCL_ELEM (LTYPE (tree));
if (arraySize && arrayIndex >= arraySize)
{
- werror (W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
+ werrorfl (tree->filename, tree->lineno, W_IDX_OUT_OF_BOUNDS, arrayIndex, arraySize);
}
}
/* if this is not a structure */
if (!IS_STRUCT (LTYPE (tree)))
{
- werror (E_STRUCT_UNION, ".");
+ werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, ".");
goto errorTreeReturn;
}
TTYPE (tree) = structElemType (LTYPE (tree),
/* if not pointer to a structure */
if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
{
- werror (E_PTR_REQD);
+ werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
goto errorTreeReturn;
}
if (!IS_STRUCT (LTYPE (tree)->next))
{
- werror (E_STRUCT_UNION, "->");
+ werrorfl (tree->filename, tree->lineno, E_STRUCT_UNION, "->");
goto errorTreeReturn;
}
sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
- werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
+ werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
if (tree->right)
RLVAL (tree) = 1;
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
{
- werror (E_BITWISE_OP);
- werror (W_CONTINUE, "left & right types are ");
+ werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
+ werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, ",");
printTypeChain (RTYPE (tree), stderr);
/* if bit field then error */
if (IS_BITVAR (tree->left->etype))
{
- werror (E_ILLEGAL_ADDR, "address of bit variable");
+ werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of bit variable");
goto errorTreeReturn;
}
if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
{
- werror (E_ILLEGAL_ADDR, "address of register variable");
+ werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of register variable");
goto errorTreeReturn;
}
if (IS_LITERAL(LTYPE(tree)))
{
- werror (E_ILLEGAL_ADDR, "address of literal");
+ werrorfl (tree->filename, tree->lineno, E_ILLEGAL_ADDR, "address of literal");
goto errorTreeReturn;
}
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "address of");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "address of");
goto errorTreeReturn;
}
if (!LETYPE (tree))
case '^':
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
{
- werror (E_BITWISE_OP);
- werror (W_CONTINUE, "left & right types are ");
+ werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
+ werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, ",");
printTypeChain (RTYPE (tree), stderr);
case '/':
if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
{
- werror (E_INVALID_OP, "divide");
+ werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "divide");
goto errorTreeReturn;
}
/* if they are both literal then */
/* rearrange the tree */
if (IS_LITERAL (RTYPE (tree))
/* avoid infinite loop */
- && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 1)
+ && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 1)
{
ast *parent;
ast *litTree = searchLitOp (tree, &parent, "/");
litTree->right = newNode ('*',
litTree->right,
copyAst (tree->right));
+ litTree->right->filename = tree->filename;
litTree->right->lineno = tree->lineno;
- tree->right->opval.val = constVal ("1");
+ tree->right->opval.val = constCharVal (1);
decorateType (parent, resultType);
}
else
case '%':
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
{
- werror (E_BITWISE_OP);
- werror (W_CONTINUE, "left & right types are ");
+ werrorfl (tree->filename, tree->lineno, E_BITWISE_OP);
+ werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, ",");
printTypeChain (RTYPE (tree), stderr);
{
if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
{
- werror (E_PTR_REQD);
+ werrorfl (tree->filename, tree->lineno, E_PTR_REQD);
goto errorTreeReturn;
}
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "pointer deref");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "pointer deref");
goto errorTreeReturn;
}
if (IS_ADDRESS_OF_OP(tree->left))
/*----------------------------*/
if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
{
- werror (E_INVALID_OP, "multiplication");
+ werrorfl (tree->filename, tree->lineno, E_INVALID_OP, "multiplication");
goto errorTreeReturn;
}
}
LRVAL (tree) = RRVAL (tree) = 1;
- tree->left = addCast (tree->left, resultType, FALSE);
- tree->right = addCast (tree->right, resultType, FALSE);
+ tree->left = addCast (tree->left, resultTypeProp, FALSE);
+ tree->right = addCast (tree->right, resultTypeProp, FALSE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
{
if (!IS_ARITHMETIC (LTYPE (tree)))
{
- werror (E_UNARY_OP, '+');
+ werrorfl (tree->filename, tree->lineno, E_UNARY_OP, '+');
goto errorTreeReturn;
}
if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
{
- werror (E_PTR_PLUS_PTR);
+ werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
goto errorTreeReturn;
}
if (!IS_ARITHMETIC (LTYPE (tree)) &&
!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
{
- werror (E_PLUS_INVALID, "+");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
goto errorTreeReturn;
}
if (!IS_ARITHMETIC (RTYPE (tree)) &&
!IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
{
- werror (E_PLUS_INVALID, "+");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+");
goto errorTreeReturn;
}
/* if they are both literal then */
if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
{
tree->type = EX_VALUE;
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
tree->opval.val = valPlus (valFromType (LETYPE (tree)),
valFromType (RETYPE (tree)));
tree->right = tree->left = NULL;
LTYPE (tree));
else
{
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
RTYPE (tree),
if (!IS_ARITHMETIC (LTYPE (tree)))
{
- werror (E_UNARY_OP, tree->opval.op);
+ werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
goto errorTreeReturn;
}
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
return tree;
}
- tree->left = addCast (tree->left, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
NULL,
IS_ARRAY (LTYPE (tree)) ||
IS_ARITHMETIC (LTYPE (tree))))
{
- werror (E_PLUS_INVALID, "-");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
goto errorTreeReturn;
}
IS_ARRAY (RTYPE (tree)) ||
IS_ARITHMETIC (RTYPE (tree))))
{
- werror (E_PLUS_INVALID, "-");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
goto errorTreeReturn;
}
!(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
IS_INTEGRAL (RTYPE (tree))))
{
- werror (E_PLUS_INVALID, "-");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-");
goto errorTreeReturn;
}
if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
{
tree->type = EX_VALUE;
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
tree->opval.val = valMinus (valFromType (LETYPE (tree)),
valFromType (RETYPE (tree)));
tree->right = tree->left = NULL;
{
tree->type = EX_VALUE;
tree->left = tree->right = NULL;
- tree->opval.val = constVal ("0");
+ tree->opval.val = constCharVal (0);
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
return tree;
}
LTYPE (tree));
else
{
- tree->left = addCast (tree->left, resultType, TRUE);
- tree->right = addCast (tree->right, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
+ tree->right = addCast (tree->right, resultTypeProp, TRUE);
TETYPE (tree) = getSpec (TTYPE (tree) =
computeType (LTYPE (tree),
/* rearrange the tree */
if (IS_LITERAL (RTYPE (tree))
/* avoid infinite loop */
- && (TYPE_TARGET_ULONG) floatFromVal (tree->right->opval.val) != 0)
+ && (TYPE_TARGET_ULONG) ulFromVal (tree->right->opval.val) != 0)
{
ast *litTree, *litParent;
litTree = searchLitOp (tree, &litParent, "+-");
/* can be only integral type */
if (!IS_INTEGRAL (LTYPE (tree)))
{
- werror (E_UNARY_OP, tree->opval.op);
+ werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
goto errorTreeReturn;
}
tree->opval.val = valComplement (valFromType (LETYPE (tree)));
tree->left = NULL;
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
- return addCast (tree, resultType, TRUE);
+ return addCast (tree, resultTypeProp, TRUE);
}
if (resultType == RESULT_TYPE_BIT &&
bit -> int -> ~int -> bit
uchar -> int -> ~int -> bit
*/
- werror(W_COMPLEMENT);
+ werrorfl (tree->filename, tree->lineno, W_COMPLEMENT);
/* optimize bit-result, even if we optimize a buggy source */
tree->type = EX_VALUE;
- tree->opval.val = constVal ("1");
+ tree->opval.val = constCharVal (1);
}
else
- tree->left = addCast (tree->left, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
LRVAL (tree) = 1;
COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
return tree;
!IS_PTR (LTYPE (tree)) &&
!IS_ARRAY (LTYPE (tree)))
{
- werror (E_UNARY_OP, tree->opval.op);
+ werrorfl (tree->filename, tree->lineno, E_UNARY_OP, tree->opval.op);
goto errorTreeReturn;
}
/* if left is another '!' */
- if (tree->left->opval.op == '!')
+ if (IS_AST_NOT_OPER (tree->left))
{
+ if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
+ {
+ /* replace double '!!X' by 'X' */
+ return tree->left->left;
+ }
/* remove double '!!X' by 'X ? 1 : 0' */
tree->opval.op = '?';
tree->left = tree->left->left;
tree->right = newNode (':',
- newAst_VALUE (constVal ("1")),
- newAst_VALUE (constVal ("0")));
+ newAst_VALUE (constCharVal (1)),
+ newAst_VALUE (constCharVal (0)));
+ tree->right->filename = tree->filename;
tree->right->lineno = tree->lineno;
tree->decorated = 0;
return decorateType (tree, resultType);
case RIGHT_OP:
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
{
- werror (E_SHIFT_OP_INVALID);
- werror (W_CONTINUE, "left & right types are ");
+ werrorfl (tree->filename, tree->lineno, E_SHIFT_OP_INVALID);
+ werrorfl (tree->filename, tree->lineno, W_CONTINUE, "left & right types are ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, ",");
printTypeChain (RTYPE (tree), stderr);
/* make smaller type only if it's a LEFT_OP */
if (tree->opval.op == LEFT_OP)
- tree->left = addCast (tree->left, resultType, TRUE);
+ tree->left = addCast (tree->left, resultTypeProp, TRUE);
/* if they are both literal then */
/* rewrite the 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)) &&
- ((TYPE_TARGET_ULONG) floatFromVal (valFromType (RETYPE (tree)))) >=
+ ((TYPE_TARGET_ULONG) ulFromVal (valFromType (RETYPE (tree)))) >=
(getSize (TETYPE (tree)) * 8))
{
if (tree->opval.op==LEFT_OP ||
(tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
{
- lineno=tree->lineno;
- werror (W_SHIFT_CHANGED,
+ werrorfl (tree->filename, tree->lineno, W_SHIFT_CHANGED,
(tree->opval.op == LEFT_OP ? "left" : "right"));
tree->type = EX_VALUE;
tree->left = tree->right = NULL;
- tree->opval.val = constVal ("0");
+ tree->opval.val = constCharVal (0);
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
return tree;
}
/* cannot cast to an aggregate type */
if (IS_AGGREGATE (LTYPE (tree)))
{
- werror (E_CAST_ILLEGAL);
+ werrorfl (tree->filename, tree->lineno, E_CAST_ILLEGAL);
goto errorTreeReturn;
}
changePointer(LTYPE(tree));
checkTypeSanity(LETYPE(tree), "(cast)");
- /* if 'from' and 'to' are the same remove the superfluous cast, */
- /* this helps other optimizations */
+
+ /* if 'from' and 'to' are the same remove the superfluous cast,
+ * this helps other optimizations */
if (compareTypeExact (LTYPE(tree), RTYPE(tree), -1) == 1)
{
+ /* mark that the explicit cast has been removed,
+ * for proper processing (no integer promotion) of explicitly typecasted variable arguments */
+ tree->right->values.removedCast = 1;
return tree->right;
}
TTYPE (tree) = tree->opval.val->type;
tree->values.literalFromCast = 1;
} else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
- ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
+ ((int) ulFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */ {
sym_link *rest = LTYPE(tree)->next;
- werror(W_LITERAL_GENERIC);
+ werrorfl (tree->filename, tree->lineno, W_LITERAL_GENERIC);
TTYPE(tree) = newLink(DECLARATOR);
DCL_TYPE(TTYPE(tree)) = FPOINTER;
TTYPE(tree)->next = rest;
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,
+ werrorfl (tree->filename, tree->lineno, W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
SPEC_STRUCT(LETYPE(tree))->tag);
}
#endif
allocGlobal (sym);
newTree->left = newAst_VALUE(symbolVal(sym));
+ newTree->left->filename = tree->filename;
newTree->left->lineno = tree->lineno;
LTYPE (newTree) = sym->type;
LETYPE (newTree) = sym->etype;
!IS_ARRAY (LTYPE (tree)) &&
!IS_INTEGRAL (LTYPE (tree)))
{
- werror (E_COMPARE_OP);
+ werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
goto errorTreeReturn;
}
!IS_ARRAY (RTYPE (tree)) &&
!IS_INTEGRAL (RTYPE (tree)))
{
- werror (E_COMPARE_OP);
+ werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
goto errorTreeReturn;
}
/* if they are both literal then */
}
if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
{
- werror (E_COMPARE_OP);
+ werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
fprintf (stderr, "comparing type ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, "to type ");
if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
{
- werror (E_COMPARE_OP);
+ werrorfl (tree->filename, tree->lineno, E_COMPARE_OP);
fprintf (stderr, "comparing type ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, "to type ");
case CCR_ALWAYS_TRUE:
case CCR_ALWAYS_FALSE:
if (!options.lessPedantic)
- werror (W_COMP_RANGE,
+ werrorfl (tree->filename, tree->lineno, W_COMP_RANGE,
ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
- return decorateType (newAst_VALUE (constVal (
- ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
- resultType);
+ return decorateType (newAst_VALUE (constCharVal ((unsigned char)(ccr_result == CCR_ALWAYS_TRUE))), resultType);
case CCR_OK:
default:
break;
if (tree->opval.op == '>' &&
SPEC_USIGN(LETYPE(tree)) &&
IS_LITERAL(RTYPE(tree)) &&
- ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
+ ((int) ulFromVal (valFromType (RETYPE (tree)))) == 0)
{
- if (resultType == RESULT_TYPE_IFX)
+ if ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT))
{
/* the parent is an ifx: */
/* if (unsigned value) */
/* (unsigned value) ? 1 : 0 */
tree->opval.op = '?';
tree->right = newNode (':',
- newAst_VALUE (constVal ("1")),
+ newAst_VALUE (constCharVal (1)),
tree->right); /* val 0 */
+ tree->right->filename = tree->filename;
tree->right->lineno = tree->lineno;
+ tree->right->left->filename = tree->filename;
tree->right->left->lineno = tree->lineno;
tree->decorated = 0;
return decorateType (tree, resultType);
if (IS_LITERAL(RTYPE(tree)) &&
floatFromVal (valFromType (RETYPE (tree))) == 0 &&
tree->opval.op == EQ_OP &&
- resultType == RESULT_TYPE_IFX)
+ (resultType == RESULT_TYPE_IFX || resultType == RESULT_TYPE_BIT))
{
tree->opval.op = '!';
tree->right = NULL;
if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
/* the value range of a 'unsigned char' is 0...255;
if the actual value is < 128 it can be changed to signed */
- (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
+ (int) ulFromVal (valFromType (RETYPE (tree))) < 128)
{
/* now we've got 2 'signed char'! */
SPEC_USIGN (RETYPE (tree)) = 0;
}
/* same test for the left operand: */
else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
- (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
+ (int) ulFromVal (valFromType (LETYPE (tree))) < 128)
{
SPEC_USIGN (LETYPE (tree)) = 0;
}
else
{
- werror (W_CMP_SU_CHAR);
+ werrorfl (tree->filename, tree->lineno, W_CMP_SU_CHAR);
tree->left = addCast (tree->left , RESULT_TYPE_INT, TRUE);
tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
}
}
LRVAL (tree) = RRVAL (tree) = 1;
- TTYPE (tree) = TETYPE (tree) = newBoolLink ();
+ TTYPE (tree) = TETYPE (tree) = (resultType == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
/* condition transformations */
{
tree->opval.op = transformedOp;
tree->decorated = 0;
tree = newNode ('!', tree, NULL);
+ tree->filename = tree->left->filename;
tree->lineno = tree->left->lineno;
return decorateType (tree, resultType);
}
/* change the type to a integer */
{
int size = getSize (tree->right->ftype);
+
SNPRINTF(buffer, sizeof(buffer), "%d", size);
if (!size && !IS_VOID(tree->right->ftype))
werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
tree->right = tree->left = NULL;
TETYPE (tree) = getSpec (TTYPE (tree) =
tree->opval.val->type);
+
return tree;
/*------------------------------------------------------------------*/
case '?':
/* the type is value of the colon operator (on the right) */
assert (IS_COLON_OP (tree->right));
- /* if already known then replace the tree : optimizer will do it
- but faster to do it here */
+
+ /* If already known then replace the tree : optimizer will do it
+ but faster to do it here. If done before decorating tree->right
+ this can save generating unused const strings. */
if (IS_LITERAL (LTYPE (tree)))
{
- if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
+ if (((int) ulFromVal (valFromType (LETYPE (tree)))) != 0)
return decorateType (tree->right->left, resultTypeProp);
else
return decorateType (tree->right->right, resultTypeProp);
}
- else
+
+ tree->right = decorateType (tree->right, resultTypeProp);
+
+ if (IS_AST_LIT_VALUE (tree->right->left) && IS_AST_LIT_VALUE (tree->right->right) &&
+ ((resultType == RESULT_TYPE_IFX) || (resultType == RESULT_TYPE_BIT)))
{
- tree->right = decorateType (tree->right, resultTypeProp);
- TTYPE (tree) = RTYPE (tree);
- TETYPE (tree) = getSpec (TTYPE (tree));
+ double valTrue = AST_FLOAT_VALUE (tree->right->left);
+ double valFalse = AST_FLOAT_VALUE (tree->right->right);
+
+ if ((valTrue != 0) && (valFalse == 0))
+ {
+ /* assign cond to result */
+ tree->left->decorated = 0;
+ return decorateType (tree->left, resultTypeProp);
+ }
+ else if ((valTrue == 0) && (valFalse != 0))
+ {
+ /* assign !cond to result */
+ tree->opval.op = '!';
+ tree->decorated = 0;
+ tree->right = NULL;
+ return decorateType (tree, resultTypeProp);
+ }
+ else
+ {
+ /* they have the same boolean value, make them equal */
+ tree->right->left = tree->right->right;
+ }
}
+
+ /* if they are equal then replace the tree */
+ if (isAstEqual (tree->right->left, tree->right->right))
+ {
+ return tree->right->left;
+ }
+
+ TTYPE (tree) = RTYPE (tree);
+ TETYPE (tree) = getSpec (TTYPE (tree));
return tree;
case ':':
if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
(compareType (RTYPE (tree), LTYPE (tree)) == 0))
{
- werror (E_TYPE_MISMATCH, "conditional operator", " ");
+ werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "conditional operator", " ");
goto errorTreeReturn;
}
if (!IS_ARITHMETIC (LTYPE (tree)) ||
!IS_ARITHMETIC (RTYPE (tree)))
{
- werror (E_OPS_INTEGRAL);
+ werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
goto errorTreeReturn;
}
RRVAL (tree) = 1;
TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
- werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
+ werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
goto errorTreeReturn;
}
LLVAL (tree) = 1;
if (!IS_INTEGRAL (LTYPE (tree)) ||
!IS_INTEGRAL (RTYPE (tree)))
{
- werror (E_OPS_INTEGRAL);
+ werrorfl (tree->filename, tree->lineno, E_OPS_INTEGRAL);
goto errorTreeReturn;
}
RRVAL (tree) = 1;
TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
- werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
+ werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
goto errorTreeReturn;
}
LLVAL (tree) = 1;
if (!(IS_PTR (LTYPE (tree)) ||
IS_ARITHMETIC (LTYPE (tree))))
{
- werror (E_PLUS_INVALID, "-=");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
goto errorTreeReturn;
}
if (!(IS_PTR (RTYPE (tree)) ||
IS_ARITHMETIC (RTYPE (tree))))
{
- werror (E_PLUS_INVALID, "-=");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "-=");
goto errorTreeReturn;
}
RRVAL (tree) = 1;
tree->opval.op));
if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
- werror (E_CODE_WRITE, "-=");
+ werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "-=");
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "-=");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "-=");
goto errorTreeReturn;
}
LLVAL (tree) = 1;
/* if both pointers then problem */
if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
{
- werror (E_PTR_PLUS_PTR);
+ werrorfl (tree->filename, tree->lineno, E_PTR_PLUS_PTR);
goto errorTreeReturn;
}
if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
{
- werror (E_PLUS_INVALID, "+=");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
goto errorTreeReturn;
}
if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
{
- werror (E_PLUS_INVALID, "+=");
+ werrorfl (tree->filename, tree->lineno, E_PLUS_INVALID, "+=");
goto errorTreeReturn;
}
RRVAL (tree) = 1;
tree->opval.op));
if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
- werror (E_CODE_WRITE, "+=");
+ werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "+=");
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "+=");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "+=");
goto errorTreeReturn;
}
/* cannot be an aggregate */
if (IS_AGGREGATE (LTYPE (tree)))
{
- werror (E_AGGR_ASSIGN);
+ werrorfl (tree->filename, tree->lineno, E_AGGR_ASSIGN);
goto errorTreeReturn;
}
/* they should either match or be castable */
if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
{
- werror (E_TYPE_MISMATCH, "assignment", " ");
+ werrorfl (tree->filename, tree->lineno, E_TYPE_MISMATCH, "assignment", " ");
printFromToType(RTYPE(tree),LTYPE(tree));
}
then report error */
if (IS_VOID (LTYPE (tree)))
{
- werror (E_CAST_ZERO);
+ werrorfl (tree->filename, tree->lineno, E_CAST_ZERO);
printFromToType(RTYPE(tree), LTYPE(tree));
}
LLVAL (tree) = 1;
if (!tree->initMode ) {
if (IS_CONSTANT(LTYPE(tree)))
- werror (E_CODE_WRITE, "=");
+ werrorfl (tree->filename, tree->lineno, E_CODE_WRITE, "=");
}
if (LRVAL (tree))
{
- werror (E_LVALUE_REQUIRED, "=");
+ werrorfl (tree->filename, tree->lineno, E_LVALUE_REQUIRED, "=");
goto errorTreeReturn;
}
if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
{
- werror (W_VOID_FUNC, currFunc->name);
+ werrorfl (tree->filename, tree->lineno, W_VOID_FUNC, currFunc->name);
goto errorTreeReturn;
}
tree->left), RESULT_TYPE_NONE);
}
case PARAM:
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ werrorfl (tree->filename, tree->lineno, E_INTERNAL_ERROR, __FILE__, __LINE__,
"node PARAM shouldn't be processed here");
/* but in processParams() */
return tree;
ex->values.sym = decl;
ex->level++;
+ ex->filename = NULL;
ex->lineno = 0;
return ex;
}
label->islbl = 1;
label->key = labelKey++;
rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
+ rValue->filename = NULL;
rValue->lineno = 0;
return rValue;
{
/* also order the cases according to value */
value *pval = NULL;
- int cVal = (int) floatFromVal (caseVal->opval.val);
- while (val && (int) floatFromVal (val) < cVal)
+ int cVal = (int) ulFromVal (caseVal->opval.val);
+ while (val && (int) ulFromVal (val) < cVal)
{
pval = val;
val = val->next;
{
pval->next = caseVal->opval.val;
}
- else if ((int) floatFromVal (val) == cVal)
+ else if ((int) ulFromVal (val) == cVal)
{
werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
"case");
SNPRINTF(caseLbl, sizeof(caseLbl),
"_case_%d_%d",
swStat->values.switchVals.swNum,
- (int) floatFromVal (caseVal->opval.val));
+ (int) ulFromVal (caseVal->opval.val));
rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
+ rexpr->filename = 0;
rexpr->lineno = 0;
return rexpr;
}
/* put the continue label */
condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
condExpr = createLabel (continueLabel, condExpr);
+ condExpr->filename = NULL;
condExpr->lineno = 0;
/* put the body label in front of the body */
whileBody = createLabel (trueLabel, whileBody);
+ whileBody->filename = NULL;
whileBody->lineno = 0;
/* put a jump to continue at the end of the body */
/* and put break label at the end of the body */
if (!IS_AST_LIT_VALUE (tree->right))
return -1;
- return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
+ return powof2 (AST_ULONG_VALUE (tree->right));
}
/*-----------------------------------------------------------------*/
ast *
optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
{
- int i, j;
+ unsigned int i, j;
ast * expr;
expr = isShiftRightLitVal_BitAndLitVal(tree);
if (expr)
{
- if ((AST_LIT_VALUE (tree->right) != 1) ||
- ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
+ if ((AST_ULONG_VALUE (tree->right) != 1) ||
+ ((i = AST_ULONG_VALUE (tree->left->right)) !=
(j = (getSize (TTYPE (expr)) * 8 - 1))))
expr = NULL;
}
expr = isShiftRightLitVal_BitAndLitVal(tree);
if (expr)
{
- if (AST_LIT_VALUE (tree->right) != 1)
+ if (AST_ULONG_VALUE (tree->right) != 1)
expr = NULL;
count = tree->left->right;
}
expr = isShiftRightLitVal_BitAndLitVal(tree);
if (expr)
{
- i = (unsigned int) AST_LIT_VALUE (tree->left->right);
+ i = AST_ULONG_VALUE (tree->left->right);
count = tree->left->right;
- if (AST_LIT_VALUE (tree->right) != 0xFF)
+ if (AST_ULONG_VALUE (tree->right) != 0xFF)
expr = NULL;
}
if (!expr && resultType == RESULT_TYPE_CHAR)
/* if this is a right shift over a multiple of 8 */
if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
{
- i = (unsigned int) AST_LIT_VALUE (tree->right);
+ i = AST_ULONG_VALUE (tree->right);
count = tree->right;
expr = tree->left;
}
expr = isShiftRightLitVal_BitAndLitVal(tree);
if (expr)
{
- i = (unsigned int) AST_LIT_VALUE (tree->left->right);
+ i = AST_ULONG_VALUE (tree->left->right);
count = tree->left->right;
- if (AST_LIT_VALUE (tree->right) != 0xFFFF)
+ if (AST_ULONG_VALUE (tree->right) != 0xFFFF)
expr = NULL;
}
if (!expr && resultType == RESULT_TYPE_INT)
/* if this is a right shift over a multiple of 8 */
if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
{
- i = (unsigned int) AST_LIT_VALUE (tree->right);
+ i = AST_ULONG_VALUE (tree->right);
count = tree->right;
expr = tree->left;
}
root->right->left))
goto tryNext0;
- if (AST_LIT_VALUE (root->left->right) != 1)
+ if (AST_ULONG_VALUE (root->left->right) != 1)
goto tryNext0;
- if (AST_LIT_VALUE (root->right->right) !=
+ if (AST_ULONG_VALUE (root->right->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
goto tryNext0;
root->right->left))
goto tryNext1;
- if (AST_LIT_VALUE (root->right->right) != 1)
+ if (AST_ULONG_VALUE (root->right->right) != 1)
goto tryNext1;
- if (AST_LIT_VALUE (root->left->right) !=
+ if (AST_ULONG_VALUE (root->left->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
goto tryNext1;
root->right->left))
goto tryNext2;
- if (AST_LIT_VALUE (root->left->right) != 1)
+ if (AST_ULONG_VALUE (root->left->right) != 1)
goto tryNext2;
- if (AST_LIT_VALUE (root->right->right) !=
+ if (AST_ULONG_VALUE (root->right->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
goto tryNext2;
root->right->left))
return root;
- if (AST_LIT_VALUE (root->right->right) != 1)
+ if (AST_ULONG_VALUE (root->right->right) != 1)
return root;
- if (AST_LIT_VALUE (root->left->right) !=
+ if (AST_ULONG_VALUE (root->left->right) !=
(getSize (TTYPE (root->left->left)) * 8 - 1))
return root;
root->right->left))
return root;
- if (AST_LIT_VALUE (root->left->right) !=
+ if (AST_ULONG_VALUE (root->left->right) !=
(getSize (TTYPE (root->left->left)) * 4))
return root;
- if (AST_LIT_VALUE (root->right->right) !=
+ if (AST_ULONG_VALUE (root->right->right) !=
(getSize (TTYPE (root->left->left)) * 4))
return root;
case '>':
case '<':
case NE_OP:
- optExpr = newAst_VALUE (constVal ("0"));
+ optExpr = newAst_VALUE (constCharVal (0));
break;
case GE_OP:
case LE_OP:
case EQ_OP:
- optExpr = newAst_VALUE (constVal ("1"));
+ optExpr = newAst_VALUE (constCharVal (1));
break;
}
root->right->opval.val : NULL);
/* if left is a BITVAR in BITSPACE */
- /* and right is a LITERAL then opt- */
- /* imize else do nothing */
+ /* and right is a LITERAL then */
+ /* optimize else do nothing */
if (vleft && vright &&
IS_BITVAR (vleft->etype) &&
IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
{
/* if right side > 1 then comparison may never succeed */
- if ((litValue = (int) floatFromVal (vright)) > 1)
+ if ((litValue = (int) ulFromVal (vright)) > 1)
{
werror (W_BAD_COMPARE);
goto noOptimize;
noOptimize:
return root;
}
+
/*-----------------------------------------------------------------*/
/* addSymToBlock : adds the symbol to the first block we find */
/*-----------------------------------------------------------------*/
return 1;
}
+
+
+/*------------------------------------------------------------------*/
+/* fixupInlineLabel - change a label in an inlined function so that */
+/* it is always unique no matter how many times */
+/* the function is inlined. */
+/*------------------------------------------------------------------*/
+static void
+fixupInlineLabel (symbol * sym)
+{
+ char name[SDCC_NAME_MAX + 1];
+
+ SNPRINTF(name, sizeof(name), "%s_%d", sym->name, inlineState.count);
+ strcpy (sym->name, name);
+}
+
+
+/*------------------------------------------------------------------*/
+/* copyAstLoc - copy location information (file, line, block, etc.) */
+/* from one ast node to another */
+/*------------------------------------------------------------------*/
+static void
+copyAstLoc (ast * dest, ast * src)
+{
+ dest->filename = src->filename;
+ dest->lineno = src->lineno;
+ dest->level = src->level;
+ dest->block = src->block;
+ dest->seqPoint = src->seqPoint;
+
+}
+
+
+/*-----------------------------------------------------------------*/
+/* fixupInline - perform various fixups on an inline function tree */
+/* to take into account that it is no longer a */
+/* stand-alone function. */
+/*-----------------------------------------------------------------*/
+static void
+fixupInline (ast * tree, int level)
+{
+ tree->block = currBlockno;
+
+ if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
+ {
+ symbol * decls;
+
+ currBlockno++;
+ level++;
+
+ /* Add any declared variables back into the symbol table */
+ decls = tree->values.sym;
+ while (decls)
+ {
+ decls->level = level;
+ decls->block = currBlockno;
+ addSym (SymbolTab, decls, decls->name, decls->level, decls->block, 0);
+ decls = decls->next;
+ }
+ }
+
+ tree->level = level;
+
+ /* Update symbols */
+ if (IS_AST_VALUE (tree) &&
+ tree->opval.val->sym)
+ {
+ symbol * sym = tree->opval.val->sym;
+
+ sym->level = level;
+ sym->block = currBlockno;
+
+ sym->reqv = NULL;
+ SYM_SPIL_LOC (sym) = NULL;
+ sym->key = 0;
+
+ /* If the symbol is a label, we need to renumber it */
+ if (sym->islbl)
+ fixupInlineLabel (sym);
+ }
+
+ /* Update IFX target labels */
+ if (tree->type == EX_OP && tree->opval.op == IFX)
+ {
+ if (tree->trueLabel)
+ fixupInlineLabel (tree->trueLabel);
+ if (tree->falseLabel)
+ fixupInlineLabel (tree->falseLabel);
+ }
+
+ /* Replace RETURN with optional assignment and a GOTO to the end */
+ /* of the inlined function */
+ if (tree->type == EX_OP && tree->opval.op == RETURN)
+ {
+ ast * assignTree = NULL;
+ ast * gotoTree;
+
+ if (inlineState.retsym && tree->right)
+ {
+ assignTree = newNode ('=',
+ newAst_VALUE (symbolVal (inlineState.retsym)),
+ tree->right);
+ copyAstLoc (assignTree, tree);
+ }
+
+ gotoTree = newNode (GOTO,
+ newAst_VALUE (symbolVal (inlineState.retlab)),
+ NULL);
+ copyAstLoc (gotoTree, tree);
+
+ tree->opval.op = NULLOP;
+ tree->left = assignTree;
+ tree->right = gotoTree;
+ }
+
+ /* Update any children */
+ if (tree->left)
+ fixupInline (tree->left, level);
+ if (tree->right)
+ fixupInline (tree->right, level);
+
+ if (IS_AST_OP (tree) && (tree->opval.op == LABEL))
+ {
+ symbol * label = tree->left->opval.val->sym;
+
+ label->key = labelKey++;
+ /* Add this label back into the symbol table */
+ addSym (LabelTab, label, label->name, label->level, 0, 0);
+ }
+
+
+ if (IS_AST_OP (tree) && (tree->opval.op == BLOCK))
+ {
+ level--;
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* inlineAddDecl - add a variable declaration to an ast block. It */
+/* is also added to the symbol table if addSymTab */
+/* is nonzero. */
+/*-----------------------------------------------------------------*/
+static void
+inlineAddDecl (symbol * sym, ast * block, int addSymTab)
+{
+ sym->reqv = NULL;
+ SYM_SPIL_LOC (sym) = NULL;
+ sym->key = 0;
+ if (block != NULL)
+ {
+ symbol **decl = &(block->values.sym);
+
+ sym->level = block->level;
+ sym->block = block->block;
+
+ while (*decl)
+ {
+ if (strcmp ((*decl)->name, sym->name) == 0)
+ return;
+ decl = &( (*decl)->next );
+ }
+
+ *decl = sym;
+
+ if (addSymTab)
+ addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 0);
+
+ }
+}
+
+
+/*-----------------------------------------------------------------*/
+/* inlineTempVar - create a temporary variable for inlining */
+/*-----------------------------------------------------------------*/
+static symbol *
+inlineTempVar (sym_link * type, int level)
+{
+ symbol * sym;
+
+ sym = newSymbol (genSymName(level), level );
+ sym->type = copyLinkChain (type);
+ sym->etype = getSpec(sym->type);
+ SPEC_SCLS (sym->etype) = S_AUTO;
+ SPEC_OCLS (sym->etype) = NULL;
+ SPEC_EXTR (sym->etype) = 0;
+ SPEC_STAT (sym->etype) = 0;
+ if IS_SPEC (sym->type)
+ SPEC_VOLATILE (sym->type) = 0;
+ else
+ DCL_PTR_VOLATILE (sym->type) = 0;
+ SPEC_ABSA (sym->etype) = 0;
+
+ return sym;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* inlineFindParmRecurse - recursive function for inlineFindParm */
+/*-----------------------------------------------------------------*/
+static ast *
+inlineFindParmRecurse (ast * parms, int *index)
+{
+ if (!parms)
+ return NULL;
+
+ if (parms->type == EX_OP && parms->opval.op == PARAM)
+ {
+ ast * p;
+
+ p=inlineFindParmRecurse (parms->left, index);
+ if (p)
+ return p;
+ p=inlineFindParmRecurse (parms->right, index);
+ if (p)
+ return p;
+ }
+ if (!*index)
+ return parms;
+ (*index)--;
+ return NULL;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* inlineFindParm - search an ast tree of parameters to find one */
+/* at a particular index (0=first parameter). */
+/* Returns NULL if not found. */
+/*-----------------------------------------------------------------*/
+static ast *
+inlineFindParm (ast * parms, int index)
+{
+ return inlineFindParmRecurse (parms, &index);
+}
+
+/*-----------------------------------------------------------------*/
+/* inlineFindMaxBlockno - find maximum block number in an ast tree */
+/*-----------------------------------------------------------------*/
+static int
+inlineFindMaxBlockno (ast * tree, int maxBlockno)
+{
+ int tempBlockno;
+
+ if (!tree)
+ return maxBlockno;
+
+ tempBlockno = inlineFindMaxBlockno (tree->left, maxBlockno);
+ if (tempBlockno > maxBlockno)
+ maxBlockno = tempBlockno;
+
+ tempBlockno = inlineFindMaxBlockno (tree->right, maxBlockno);
+ if (tempBlockno > maxBlockno)
+ maxBlockno = tempBlockno;
+
+ if (tree->block > maxBlockno)
+ maxBlockno = tree->block;
+ return maxBlockno;
+}
+
+
+
+
+/*-----------------------------------------------------------------*/
+/* expandInlineFuncs - replace calls to inline functions with the */
+/* function itself */
+/*-----------------------------------------------------------------*/
+static void
+expandInlineFuncs (ast * tree, ast * block)
+{
+ if (IS_AST_OP (tree) && (tree->opval.op == CALL) && tree->left
+ && IS_AST_VALUE (tree->left) && tree->left->opval.val->sym)
+ {
+ symbol * func = tree->left->opval.val->sym;
+ symbol * csym;
+
+ /* The symbol is probably not bound yet, so find the real one */
+ csym = findSymWithLevel (SymbolTab, func);
+ if (csym)
+ func = csym;
+
+ /* Is this an inline function that we can inline? */
+ if (IFFUNC_ISINLINE (func->type) && func->funcTree)
+ {
+ symbol * retsym = NULL;
+ symbol * retlab;
+ ast * inlinetree;
+ ast * inlinetree2;
+ ast * temptree;
+ value * args;
+ int argIndex;
+
+ /* Generate a label for the inlined function to branch to */
+ /* in case it contains a return statement */
+ retlab = newSymbol (genSymName(tree->level+1), tree->level+1 );
+ retlab->isitmp = 1;
+ retlab->islbl = 1;
+ inlineState.retlab = retlab;
+
+ /* Build the subtree for the inlined function in the form: */
+ /* { //inlinetree block */
+ /* { //inlinetree2 block */
+ /* inline_function_code; */
+ /* retlab: */
+ /* } */
+ /* } */
+ temptree = newNode (LABEL, newAst_VALUE (symbolVal (retlab)), NULL);
+ copyAstLoc (temptree, tree);
+ temptree = newNode (NULLOP, copyAst (func->funcTree), temptree);
+ copyAstLoc (temptree, tree);
+ temptree = newNode (BLOCK, NULL, temptree);
+ copyAstLoc (temptree, tree);
+ inlinetree2 = temptree;
+ inlinetree = newNode (BLOCK, NULL, inlinetree2);
+ copyAstLoc (inlinetree, tree);
+
+ /* To pass parameters to the inlined function, we need some */
+ /* intermediate variables. This avoids scoping problems */
+ /* when the parameter declaration names are used differently */
+ /* during the function call. For example, a function */
+ /* declared as func(int x, int y) but called as func(y,x). */
+ /* { //inlinetree block */
+ /* type1 temparg1; */
+ /* ... */
+ /* typen tempargn; */
+ /* temparg1 = argument1; */
+ /* ... */
+ /* tempargn = argumentn; */
+ /* { //inlinetree2 block */
+ /* type1 param1; */
+ /* ... */
+ /* typen paramn; */
+ /* param1 = temparg1; */
+ /* ... */
+ /* paramn = tempargn; */
+ /* inline_function_code; */
+ /* retlab: */
+ /* } */
+ /* } */
+ args = FUNC_ARGS (func->type);
+ argIndex = 0;
+ while (args)
+ {
+ symbol * temparg;
+ ast * assigntree;
+ symbol * parm;
+ ast * passedarg = inlineFindParm (tree->right, argIndex);
+
+ if (!passedarg)
+ {
+ werror(E_TOO_FEW_PARMS);
+ break;
+ }
+
+ temparg = inlineTempVar (args->sym->type, tree->level+1);
+ inlineAddDecl (temparg, inlinetree, FALSE);
+
+ assigntree = newNode ('=',
+ newAst_VALUE (symbolVal (temparg)),
+ passedarg);
+ inlinetree->right = newNode (NULLOP,
+ assigntree,
+ inlinetree->right);
+
+ parm = copySymbol (args->sym);
+ inlineAddDecl (parm, inlinetree2, FALSE);
+ parm->_isparm = 0;
+
+ assigntree = newNode ('=',
+ newAst_VALUE (symbolVal (parm)),
+ newAst_VALUE (symbolVal (temparg)));
+ inlinetree2->right = newNode (NULLOP,
+ assigntree,
+ inlinetree2->right);
+
+
+ args = args->next;
+ argIndex++;
+ }
+
+ /* Handle the return type */
+ if (!IS_VOID (func->type->next))
+ {
+ /* Create a temporary symbol to hold the return value and */
+ /* join it with the inlined function using the comma */
+ /* operator. The fixupInline function will take care of */
+ /* changing return statements into assignments to retsym. */
+ /* (parameter passing and return label omitted for clarity) */
+ /* rettype retsym; */
+ /* ... */
+ /* {{inline_function_code}}, retsym */
+
+ retsym = inlineTempVar (func->type->next, tree->level);
+ inlineAddDecl (retsym, block, TRUE);
+
+ tree->opval.op = ',';
+ tree->left = inlinetree;
+ tree->right = newAst_VALUE (symbolVal (retsym));
+ }
+ else
+ {
+ tree->opval.op = NULLOP;
+ tree->left = NULL;
+ tree->right = inlinetree;
+ }
+ inlineState.retsym = retsym;
+
+ /* Renumber the various internal counters on the inlined */
+ /* function's tree nodes and symbols. Add the inlined */
+ /* function's local variables to the appropriate scope(s). */
+ /* Convert inlined return statements to an assignment to */
+ /* retsym (if needed) and a goto retlab. */
+ fixupInline (inlinetree, inlinetree->level);
+ inlineState.count++;
+ }
+
+ }
+
+ /* Recursively continue to search for functions to inline. */
+ if (IS_AST_OP (tree))
+ {
+ if (tree->opval.op == BLOCK)
+ block = tree;
+
+ if (tree->left)
+ expandInlineFuncs (tree->left, block);
+ if (tree->right)
+ expandInlineFuncs (tree->right, block);
+ }
+}
+
+
/*-----------------------------------------------------------------*/
/* createFunction - This is the key node that calls the iCode for */
/* generating the code for a function. Note code */
int stack = 0;
sym_link *fetype;
iCode *piCode = NULL;
+ int savedBlockno;
if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
addSymChain (&name);
allocVariables (name);
}
- name->lastLine = mylineno;
+ name->lastLine = lexLineno;
currFunc = name;
/* set the stack pointer */
if (IFFUNC_ISREENT (name->type))
reentrant++;
+ inlineState.count = 0;
+ savedBlockno = currBlockno;
+ currBlockno = inlineFindMaxBlockno (body, 0);
+ expandInlineFuncs (body, NULL);
+ currBlockno = savedBlockno;
+
+ if (FUNC_ISINLINE (name->type))
+ name->funcTree = copyAst (body);
+
allocParms (FUNC_ARGS(name->type)); /* allocate the parameters */
/* do processing for parameters that are passed in registers */
ex = newNode (FUNCTION, ex, body);
ex->values.args = FUNC_ARGS(name->type);
ex->decorated=1;
- if (options.dump_tree) PA(ex);
+ if (options.dump_tree)
+ PA(ex);
if (fatalError)
- {
- werror (E_FUNC_NO_CODE, name->name);
- goto skipall;
- }
+ goto skipall;
+
+ /* Do not generate code for inline functions unless extern also. */
+#if 0
+ if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype))
+ goto skipall;
+#else
+ /* Temporary hack: always generate code for static inline functions. */
+ /* Ideally static inline functions should only be generated if needed. */
+ if (FUNC_ISINLINE (name->type) && !IS_EXTERN (fetype) && !IS_STATIC (fetype))
+ goto skipall;
+#endif
/* create the node & generate intermediate code */
GcurMemmap = code;
codeOutBuf = &code->oBuf;
piCode = iCodeFromAst (ex);
+ name->generated = 1;
if (fatalError)
- {
- werror (E_FUNC_NO_CODE, name->name);
- goto skipall;
- }
+ goto skipall;
eBBlockFromiCode (piCode);
}
-#define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
+#define INDENT(x,f) { int i ; fprintf (f, "%s:%d:", tree->filename, tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
/*-----------------------------------------------------------------*/
/* ast_print : prints the ast (for debugging purposes) */
/*-----------------------------------------------------------------*/
void ast_print (ast * tree, FILE *outfile, int indent)
{
- if (!tree) return ;
-
- /* can print only decorated trees */
- if (!tree->decorated) return;
-
- /* if any child is an error | this one is an error do nothing */
- if (tree->isError ||
- (tree->left && tree->left->isError) ||
- (tree->right && tree->right->isError)) {
- fprintf(outfile,"ERROR_NODE(%p)\n",tree);
- }
-
-
- /* print the line */
- /* if not block & function */
- if (tree->type == EX_OP &&
- (tree->opval.op != FUNCTION &&
- tree->opval.op != BLOCK &&
- tree->opval.op != NULLOP)) {
- }
-
- if (tree->opval.op == FUNCTION) {
- 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->left->opval.val->type->next,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);
- 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+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+2);
- INDENT(indent,outfile);
- fprintf(outfile,"}\n");
- return;
- }
- if (tree->opval.op == NULLOP) {
- ast_print(tree->left,outfile,indent);
- ast_print(tree->right,outfile,indent);
- return ;
- }
- INDENT(indent,outfile);
+ if (!tree) return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* leaf has been reached */
- /*----------------------------*/
- /* if this is of type value */
- /* just get the type */
- if (tree->type == EX_VALUE) {
-
- if (IS_LITERAL (tree->opval.val->etype)) {
- fprintf(outfile,"CONSTANT (%p) value = ", tree);
- if (SPEC_USIGN (tree->opval.val->etype))
- fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
- else
- fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
- fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
- floatFromVal(tree->opval.val));
- } else if (tree->opval.val->sym) {
- /* if the undefined flag is set then give error message */
- if (tree->opval.val->sym->undefined) {
- fprintf(outfile,"UNDEFINED SYMBOL ");
- } else {
- fprintf(outfile,"SYMBOL ");
- }
- fprintf(outfile,"(%s=%p @ %p)",
- tree->opval.val->sym->name, tree, tree->opval.val->sym);
- }
- if (tree->ftype) {
- fprintf(outfile," type (");
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- } else {
- fprintf(outfile,"\n");
- }
- return ;
- }
-
- /* if type link for the case of cast */
- if (tree->type == EX_LINK) {
- fprintf(outfile,"TYPENODE (%p) type = (",tree);
- printTypeChain(tree->opval.lnk,outfile);
- fprintf(outfile,")\n");
- return ;
- }
-
-
- /* depending on type of operator do */
-
- switch (tree->opval.op) {
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* array node */
- /*----------------------------*/
- case '[':
- fprintf(outfile,"ARRAY_OP (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* struct/union */
- /*----------------------------*/
- case '.':
- fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* struct/union pointer */
- /*----------------------------*/
- case PTR_OP:
- fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* ++/-- operation */
- /*----------------------------*/
- case INC_OP:
- if (tree->left)
- fprintf(outfile,"post-");
- else
- fprintf(outfile,"pre-");
- fprintf(outfile,"INC_OP (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2); /* postincrement case */
- ast_print(tree->right,outfile,indent+2); /* preincrement case */
- return ;
-
- case DEC_OP:
- if (tree->left)
- fprintf(outfile,"post-");
- else
- fprintf(outfile,"pre-");
- fprintf(outfile,"DEC_OP (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2); /* postdecrement case */
- ast_print(tree->right,outfile,indent+2); /* predecrement case */
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* bitwise and */
- /*----------------------------*/
- case '&':
- if (tree->right) {
- fprintf(outfile,"& (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+2);
- ast_print(tree->right,outfile,indent+2);
- }
- return ;
- /*----------------------------*/
- /* bitwise or */
- /*----------------------------*/
- case '|':
- fprintf(outfile,"OR (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* bitwise xor */
- /*----------------------------*/
- case '^':
- fprintf(outfile,"XOR (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* division */
- /*----------------------------*/
- case '/':
- fprintf(outfile,"DIV (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* modulus */
- /*----------------------------*/
- case '%':
- fprintf(outfile,"MOD (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* address dereference */
- /*----------------------------*/
- case '*': /* can be unary : if right is null then unary operation */
- if (!tree->right) {
- fprintf(outfile,"DEREF (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- return ;
- }
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* multiplication */
- /*----------------------------*/
- fprintf(outfile,"MULT (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
-
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* unary '+' operator */
- /*----------------------------*/
- case '+':
- /* if unary plus */
- if (!tree->right) {
- fprintf(outfile,"UPLUS (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- } else {
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* addition */
- /*----------------------------*/
- fprintf(outfile,"ADD (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- }
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* unary '-' */
- /*----------------------------*/
- case '-': /* can be unary */
- if (!tree->right) {
- fprintf(outfile,"UMINUS (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- } else {
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* subtraction */
- /*----------------------------*/
- fprintf(outfile,"SUB (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- }
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* complement */
- /*----------------------------*/
- case '~':
- fprintf(outfile,"COMPL (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* not */
- /*----------------------------*/
- case '!':
- fprintf(outfile,"NOT (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* shift */
- /*----------------------------*/
- case RRC:
- fprintf(outfile,"RRC (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+2);
- return ;
- case SWAP:
- fprintf(outfile,"SWAP (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+2);
- return ;
- case GETABIT:
- fprintf(outfile,"GETABIT (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
- case GETBYTE:
- fprintf(outfile,"GETBYTE (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
- case GETWORD:
- fprintf(outfile,"GETWORD (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,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+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+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* casting */
- /*----------------------------*/
- case CAST: /* change the type */
- 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+2);
- return ;
-
- case AND_OP:
- fprintf(outfile,"ANDAND (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* comparison operators */
- /*----------------------------*/
- case '>':
- fprintf(outfile,"GT(>) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+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+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+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+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+2);
- ast_print(tree->right,outfile,indent+2);
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* sizeof */
- /*----------------------------*/
- case SIZEOF: /* evaluate wihout code generation */
- fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* conditional operator '?' */
- /*----------------------------*/
- case '?':
- fprintf(outfile,"QUEST(?) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+2);
- ast_print(tree->right,outfile,indent+2);
- return ;
-
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* assignment operators */
- /*----------------------------*/
- case MUL_ASSIGN:
- fprintf(outfile,"MULASS(*=) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+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+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- case OR_ASSIGN:
- fprintf(outfile,"ORASS(|=) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- case XOR_ASSIGN:
- fprintf(outfile,"XORASS(^=) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- 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+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- case LEFT_ASSIGN:
- fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* -= operator */
- /*----------------------------*/
- case SUB_ASSIGN:
- fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* += operator */
- /*----------------------------*/
- case ADD_ASSIGN:
- fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* straight assignemnt */
- /*----------------------------*/
- case '=':
- fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* comma operator */
- /*----------------------------*/
- case ',':
- fprintf(outfile,"COMMA(,) (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* function call */
- /*----------------------------*/
- case CALL:
- case PCALL:
- fprintf(outfile,"CALL (%p) type (",tree);
- printTypeChain(tree->ftype,outfile);
- fprintf(outfile,")\n");
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent+2);
- return;
- case PARAM:
- 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 ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* return statement */
- /*----------------------------*/
- case RETURN:
- fprintf(outfile,"RETURN (%p) type (",tree);
- if (tree->right) {
- printTypeChain(tree->right->ftype,outfile);
- }
- fprintf(outfile,")\n");
- ast_print(tree->right,outfile,indent+2);
- return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* label statement */
- /*----------------------------*/
- case LABEL :
- fprintf(outfile,"LABEL (%p)\n",tree);
- ast_print(tree->left,outfile,indent+2);
- ast_print(tree->right,outfile,indent);
- return;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* switch statement */
- /*----------------------------*/
- case SWITCH:
- {
- value *val;
- fprintf(outfile,"SWITCH (%p) ",tree);
- ast_print(tree->left,outfile,0);
- for (val = tree->values.switchVals.swVals; val ; val = val->next) {
- INDENT(indent+2,outfile);
- fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
- (int) floatFromVal(val),
- tree->values.switchVals.swNum,
- (int) floatFromVal(val));
- }
- ast_print(tree->right,outfile,indent);
- }
- return ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* ifx Statement */
- /*----------------------------*/
- case IFX:
- fprintf(outfile,"IF (%p) \n",tree);
- ast_print(tree->left,outfile,indent+2);
- if (tree->trueLabel) {
- INDENT(indent+2,outfile);
- fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
- }
- if (tree->falseLabel) {
- INDENT(indent+2,outfile);
- fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
- }
- 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 ;
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* for Statement */
- /*----------------------------*/
- case FOR:
- fprintf(outfile,"FOR (%p) \n",tree);
- if (AST_FOR( tree, initExpr)) {
- INDENT(indent+2,outfile);
- fprintf(outfile,"INIT EXPR ");
- ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
- }
- if (AST_FOR( tree, condExpr)) {
- INDENT(indent+2,outfile);
- fprintf(outfile,"COND EXPR ");
- ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
- }
- if (AST_FOR( tree, loopExpr)) {
- INDENT(indent+2,outfile);
- fprintf(outfile,"LOOP EXPR ");
- ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
- }
- fprintf(outfile,"FOR LOOP BODY \n");
- ast_print(tree->left,outfile,indent+2);
- return ;
- case CRITICAL:
- fprintf(outfile,"CRITICAL (%p) \n",tree);
- ast_print(tree->left,outfile,indent+2);
- default:
- return ;
- }
+ /* can print only decorated trees */
+ if (!tree->decorated) return;
+
+ /* if any child is an error | this one is an error do nothing */
+ if (tree->isError ||
+ (tree->left && tree->left->isError) ||
+ (tree->right && tree->right->isError)) {
+ fprintf(outfile,"ERROR_NODE(%p)\n",tree);
+ }
+
+
+ /* print the line */
+ /* if not block & function */
+ if (tree->type == EX_OP &&
+ (tree->opval.op != FUNCTION &&
+ tree->opval.op != BLOCK &&
+ tree->opval.op != NULLOP)) {
+ }
+
+ if (tree->opval.op == FUNCTION) {
+ 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->left->opval.val->type->next,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);
+ 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+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+2);
+ INDENT(indent,outfile);
+ fprintf(outfile,"}\n");
+ return;
+ }
+ if (tree->opval.op == NULLOP) {
+ ast_print(tree->left,outfile,indent);
+ ast_print(tree->right,outfile,indent);
+ return ;
+ }
+ INDENT(indent,outfile);
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* leaf has been reached */
+ /*----------------------------*/
+ /* if this is of type value */
+ /* just get the type */
+ if (tree->type == EX_VALUE) {
+
+ if (IS_LITERAL (tree->opval.val->etype)) {
+ fprintf(outfile,"CONSTANT (%p) value = ", tree);
+ if (SPEC_USIGN (tree->opval.val->etype))
+ fprintf(outfile,"%u", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val));
+ else
+ fprintf(outfile,"%d", (TYPE_TARGET_LONG) ulFromVal(tree->opval.val));
+ fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) ulFromVal(tree->opval.val),
+ floatFromVal(tree->opval.val));
+ } else if (tree->opval.val->sym) {
+ /* if the undefined flag is set then give error message */
+ if (tree->opval.val->sym->undefined) {
+ fprintf(outfile,"UNDEFINED SYMBOL ");
+ } else {
+ fprintf(outfile,"SYMBOL ");
+ }
+ fprintf(outfile,"(%s=%p @ %p)",
+ tree->opval.val->sym->name, tree, tree->opval.val->sym);
+ }
+ if (tree->ftype) {
+ fprintf(outfile," type (");
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ } else {
+ fprintf(outfile,"\n");
+ }
+ return ;
+ }
+
+ /* if type link for the case of cast */
+ if (tree->type == EX_LINK) {
+ fprintf(outfile,"TYPENODE (%p) type = (",tree);
+ printTypeChain(tree->opval.lnk,outfile);
+ fprintf(outfile,")\n");
+ return ;
+ }
+
+
+ /* depending on type of operator do */
+
+ switch (tree->opval.op) {
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* array node */
+ /*----------------------------*/
+ case '[':
+ fprintf(outfile,"ARRAY_OP (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* struct/union */
+ /*----------------------------*/
+ case '.':
+ fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* struct/union pointer */
+ /*----------------------------*/
+ case PTR_OP:
+ fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* ++/-- operation */
+ /*----------------------------*/
+ case INC_OP:
+ if (tree->left)
+ fprintf(outfile,"post-");
+ else
+ fprintf(outfile,"pre-");
+ fprintf(outfile,"INC_OP (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2); /* postincrement case */
+ ast_print(tree->right,outfile,indent+2); /* preincrement case */
+ return ;
+
+ case DEC_OP:
+ if (tree->left)
+ fprintf(outfile,"post-");
+ else
+ fprintf(outfile,"pre-");
+ fprintf(outfile,"DEC_OP (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2); /* postdecrement case */
+ ast_print(tree->right,outfile,indent+2); /* predecrement case */
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* bitwise and */
+ /*----------------------------*/
+ case '&':
+ if (tree->right) {
+ fprintf(outfile,"& (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+2);
+ ast_print(tree->right,outfile,indent+2);
+ }
+ return ;
+ /*----------------------------*/
+ /* bitwise or */
+ /*----------------------------*/
+ case '|':
+ fprintf(outfile,"OR (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* bitwise xor */
+ /*----------------------------*/
+ case '^':
+ fprintf(outfile,"XOR (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* division */
+ /*----------------------------*/
+ case '/':
+ fprintf(outfile,"DIV (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* modulus */
+ /*----------------------------*/
+ case '%':
+ fprintf(outfile,"MOD (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* address dereference */
+ /*----------------------------*/
+ case '*': /* can be unary : if right is null then unary operation */
+ if (!tree->right) {
+ fprintf(outfile,"DEREF (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ return ;
+ }
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* multiplication */
+ /*----------------------------*/
+ fprintf(outfile,"MULT (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* unary '+' operator */
+ /*----------------------------*/
+ case '+':
+ /* if unary plus */
+ if (!tree->right) {
+ fprintf(outfile,"UPLUS (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ } else {
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* addition */
+ /*----------------------------*/
+ fprintf(outfile,"ADD (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ }
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* unary '-' */
+ /*----------------------------*/
+ case '-': /* can be unary */
+ if (!tree->right) {
+ fprintf(outfile,"UMINUS (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ } else {
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* subtraction */
+ /*----------------------------*/
+ fprintf(outfile,"SUB (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ }
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* complement */
+ /*----------------------------*/
+ case '~':
+ fprintf(outfile,"COMPL (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ return ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* not */
+ /*----------------------------*/
+ case '!':
+ fprintf(outfile,"NOT (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ return ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* shift */
+ /*----------------------------*/
+ case RRC:
+ fprintf(outfile,"RRC (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+2);
+ return ;
+ case SWAP:
+ fprintf(outfile,"SWAP (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+2);
+ return ;
+ case GETABIT:
+ fprintf(outfile,"GETABIT (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+ case GETBYTE:
+ fprintf(outfile,"GETBYTE (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+ case GETWORD:
+ fprintf(outfile,"GETWORD (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,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+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+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* casting */
+ /*----------------------------*/
+ case CAST: /* change the type */
+ 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+2);
+ return ;
+
+ case AND_OP:
+ fprintf(outfile,"ANDAND (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* comparison operators */
+ /*----------------------------*/
+ case '>':
+ fprintf(outfile,"GT(>) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+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+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+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+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+2);
+ ast_print(tree->right,outfile,indent+2);
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* sizeof */
+ /*----------------------------*/
+ case SIZEOF: /* evaluate wihout code generation */
+ fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* conditional operator '?' */
+ /*----------------------------*/
+ case '?':
+ fprintf(outfile,"QUEST(?) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+2);
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* assignment operators */
+ /*----------------------------*/
+ case MUL_ASSIGN:
+ fprintf(outfile,"MULASS(*=) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+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+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ case OR_ASSIGN:
+ fprintf(outfile,"ORASS(|=) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ case XOR_ASSIGN:
+ fprintf(outfile,"XORASS(^=) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ 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+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ case LEFT_ASSIGN:
+ fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* -= operator */
+ /*----------------------------*/
+ case SUB_ASSIGN:
+ fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* += operator */
+ /*----------------------------*/
+ case ADD_ASSIGN:
+ fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* straight assignemnt */
+ /*----------------------------*/
+ case '=':
+ fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* comma operator */
+ /*----------------------------*/
+ case ',':
+ fprintf(outfile,"COMMA(,) (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* function call */
+ /*----------------------------*/
+ case CALL:
+ case PCALL:
+ fprintf(outfile,"CALL (%p) type (",tree);
+ printTypeChain(tree->ftype,outfile);
+ fprintf(outfile,")\n");
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent+2);
+ return;
+ case PARAM:
+ 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 ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* return statement */
+ /*----------------------------*/
+ case RETURN:
+ fprintf(outfile,"RETURN (%p) type (",tree);
+ if (tree->right) {
+ printTypeChain(tree->right->ftype,outfile);
+ }
+ fprintf(outfile,")\n");
+ ast_print(tree->right,outfile,indent+2);
+ return ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* label statement */
+ /*----------------------------*/
+ case LABEL :
+ fprintf(outfile,"LABEL (%p)\n",tree);
+ ast_print(tree->left,outfile,indent+2);
+ ast_print(tree->right,outfile,indent);
+ return;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* switch statement */
+ /*----------------------------*/
+ case SWITCH:
+ {
+ value *val;
+ fprintf(outfile,"SWITCH (%p) ",tree);
+ ast_print(tree->left,outfile,0);
+ for (val = tree->values.switchVals.swVals; val ; val = val->next) {
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
+ (int) ulFromVal(val),
+ tree->values.switchVals.swNum,
+ (int) ulFromVal(val));
+ }
+ ast_print(tree->right,outfile,indent);
+ }
+ return ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* ifx Statement */
+ /*----------------------------*/
+ case IFX:
+ fprintf(outfile,"IF (%p) \n",tree);
+ ast_print(tree->left,outfile,indent+2);
+ if (tree->trueLabel) {
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
+ }
+ if (tree->falseLabel) {
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
+ }
+ 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 ;
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* for Statement */
+ /*----------------------------*/
+ case FOR:
+ fprintf(outfile,"FOR (%p) \n",tree);
+ if (AST_FOR( tree, initExpr)) {
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"INIT EXPR ");
+ ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
+ }
+ if (AST_FOR( tree, condExpr)) {
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"COND EXPR ");
+ ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
+ }
+ if (AST_FOR( tree, loopExpr)) {
+ INDENT(indent+2,outfile);
+ fprintf(outfile,"LOOP EXPR ");
+ ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
+ }
+ fprintf(outfile,"FOR LOOP BODY \n");
+ ast_print(tree->left,outfile,indent+2);
+ return ;
+ case CRITICAL:
+ fprintf(outfile,"CRITICAL (%p) \n",tree);
+ ast_print(tree->left,outfile,indent+2);
+ default:
+ return ;
+ }
}
void PA(ast *t)
{
- ast_print(t,stdout,0);
+ ast_print(t,stdout,0);
}
-
-
/*-----------------------------------------------------------------*/
/* astErrors : returns non-zero if errors present in tree */
/*-----------------------------------------------------------------*/