-//#define JWK_FIX_SHIFT_BUG
-//#define JWK_FIX_IMPLICIT_CAST
/*-------------------------------------------------------------------------
SDCCast.c - source file for parser support & all ast related routines
break;
case INLINEASM:
- dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
- strcpy (dest->values.inlineasm, src->values.inlineasm);
+ dest->values.inlineasm = Safe_strdup(src->values.inlineasm);
break;
case ARRAYINIT:
if (IS_INTEGRAL (ftype)
&& (getSize (ftype) < (unsigned) INTSIZE))
{
-#ifdef JWK_FIX_IMPLICIT_CAST
if (IS_AST_OP(actParm) &&
(actParm->opval.op == LEFT_OP ||
actParm->opval.op == '*' ||
} else {
newType = newAst_LINK(INTTYPE);
}
-#else
- newType = newAst_LINK(INTTYPE);
-#endif
}
if (IS_PTR(ftype) && !IS_GENPTR(ftype))
newAst_VALUE (valueFromLit ((float) i))),
newAst_VALUE (valueFromLit (*s))));
- // now we don't need iexpr's symbol anymore
- {
- symbol *sym=AST_SYMBOL(iexpr);
- memmap *segment=SPEC_OCLS(sym->etype);
- deleteSetItem(&segment->syms, sym);
- }
+ // now WE don't need iexpr's symbol anymore
+ freeStringSymbol(AST_SYMBOL(iexpr));
+
return decorateType (resolveSymbols (rast));
}
return init;
}
+/*-----------------------------------------------------------------*/
+/* freeStringSymbol - delete a literal string if no more usage */
+/*-----------------------------------------------------------------*/
+void freeStringSymbol(symbol *sym) {
+ /* make sure this is a literal string */
+ assert (sym->isstrlit);
+ if (--sym->isstrlit == 0) { // lower the usage count
+ memmap *segment=SPEC_OCLS(sym->etype);
+ if (segment) {
+ deleteSetItem(&segment->syms, sym);
+ }
+ }
+}
+
/*-----------------------------------------------------------------*/
/* stringToSymbol - creates a symbol from a literal string */
/*-----------------------------------------------------------------*/
char name[SDCC_NAME_MAX + 1];
static int charLbl = 0;
symbol *sym;
+ set *sp;
+
+ // have we heard this before?
+ for (sp=statsg->syms; sp; sp=sp->next) {
+ sym=sp->item;
+ if (sym->isstrlit &&
+ !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
+ // yes, this is old news. Don't publish it again.
+ sym->isstrlit++; // but raise the usage count
+ return symbolVal(sym);
+ }
+ }
- sprintf (name, "_str_%d", charLbl++);
+ SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
sym = newSymbol (name, 0); /* make it @ level 0 */
- strcpy (sym->rname, name);
+ strncpyz (sym->rname, name, SDCC_NAME_MAX);
/* copy the type from the value passed */
sym->type = copyLinkChain (val->type);
// a function's address will never change
return TRUE;
}
+ if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
+ // an array's address will never change
+ return TRUE;
+ }
if (IS_AST_SYM_VALUE(cexpr) &&
IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
// a symbol in code space will never change
val->sym = cexpr->opval.val->sym;
val->sym->type = copyLinkChain (cexpr->ftype);
val->sym->etype = getSpec (val->sym->type);
- strcpy (val->name, cexpr->opval.val->sym->rname);
+ strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
return val;
}
/*----------------------------*/
/* leaf has been reached */
/*----------------------------*/
+ lineno=tree->lineno;
/* if this is of type value */
/* just get the type */
if (tree->type == EX_VALUE)
if (dtr != tree->right)
tree->right = dtr;
-#ifdef JWK_FIX_IMPLICIT_CAST
if (IS_AST_OP(tree) &&
(tree->opval.op == CAST || tree->opval.op == '=') &&
(getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
(getSize(RTYPE(tree)) < INTSIZE)) {
// this is a cast/assign to a bigger type
- if (IS_AST_OP(tree->right) &&
+ if (IS_AST_OP(tree->right) &&
+ IS_INTEGRAL(tree->right->ftype) &&
(tree->right->opval.op == LEFT_OP ||
tree->right->opval.op == '*' ||
tree->right->opval.op == '+' ||
tree->right = decorateType(tree->right);
}
}
-#else
- /* special case for left shift operation : cast up right->left if type
- of left has greater size than right */
- if (tree->left && tree->right && tree->right->opval.op == LEFT_OP) {
- int lsize = getSize(LTYPE(tree));
- int rsize = getSize(RTYPE(tree));
-
- if (lsize > rsize) {
- tree->right->decorated = 0;
- tree->right->left = newNode( CAST, (lsize == 2 ?
- newAst_LINK(newIntLink()) :
- newAst_LINK(newLongLink())),
- tree->right->left);
- tree->right = decorateType(tree->right);
- }
- }
-#endif
}
/* depending on type of operator do */
ast *wtree = optimizeRRCRLC (tree);
if (wtree != tree)
return decorateType (wtree);
+ // fall through
}
/*------------------------------------------------------------------*/
/*----------------------------*/
LRVAL (tree) = RRVAL (tree) = 1;
/* if the left is a pointer */
- if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
+ if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
TETYPE (tree) = getSpec (TTYPE (tree) =
LTYPE (tree));
else
((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
(getSize (LTYPE (tree)) * 8))
{
-#ifdef JWK_FIX_SHIFT_BUG
if (tree->opval.op==LEFT_OP ||
(tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
lineno=tree->lineno;
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
return tree;
}
-#else
- /* if left shift then cast up */
- if (tree->opval.op==LEFT_OP) {
- int size = getSize(LTYPE(tree));
- tree->left =
- decorateType (newNode (CAST,
- (size == 1 ? newAst_LINK(newIntLink()) :
- (size == 2 ? newAst_LINK(newLongLink()) :
- newAst_LINK(newIntLink()))),
- tree->left));
- } else {
- werror (W_SHIFT_CHANGED,
- (tree->opval.op == LEFT_OP ? "left" : "right"));
- tree->type = EX_VALUE;
- tree->left = tree->right = NULL;
- tree->opval.val = constVal ("0");
- TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
- return tree;
- }
-#endif
}
LRVAL (tree) = RRVAL (tree) = 1;
if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
/* if they are pointers they must be castable */
if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
{
+ if (tree->opval.op==EQ_OP &&
+ !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
+ // we cannot cast a gptr to a !gptr: switch the leaves
+ struct ast *s=tree->left;
+ tree->left=tree->right;
+ tree->right=s;
+ }
if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
{
werror (E_COMPARE_OP);
- fprintf (stderr, "comparing type ");
+ fprintf (stderr, "comparring type ");
printTypeChain (LTYPE (tree), stderr);
fprintf (stderr, "to type ");
printTypeChain (RTYPE (tree), stderr);
case SIZEOF: /* evaluate wihout code generation */
/* change the type to a integer */
tree->type = EX_VALUE;
- sprintf (buffer, "%d", (getSize (tree->right->ftype)));
+ SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
tree->opval.val = constVal (buffer);
tree->right = tree->left = NULL;
TETYPE (tree) = getSpec (TTYPE (tree) =
break;
}
}
- sprintf (buffer, "%d", typeofv);
+ SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
tree->opval.val = constVal (buffer);
tree->right = tree->left = NULL;
TETYPE (tree) = getSpec (TTYPE (tree) =
checkTypeSanity(type, "(sizeof)");
/* get the size and convert it to character */
- sprintf (buff, "%d", getSize (type));
+ SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
/* now convert into value */
return constVal (buff);
static int localLbl = 0;
symbol *localLabel;
- sprintf (buffer, "_and_%d", localLbl++);
+ SNPRINTF(buffer, sizeof(buffer), "_and_%d", localLbl++);
localLabel = newSymbol (buffer, NestLevel);
tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
static int localLbl = 0;
symbol *localLabel;
- sprintf (buffer, "_or_%d", localLbl++);
+ SNPRINTF(buffer, sizeof(buffer), "_or_%d", localLbl++);
localLabel = newSymbol (buffer, NestLevel);
tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
label = newSymbol (label->name, label->level);
/* change the name before putting it in add _ */
- sprintf (name, "%s", label->name);
+ SNPRINTF(name, sizeof(name), "%s", label->name);
/* put the label in the LabelSymbol table */
/* but first check if a label of the same */
}
/* create the case label */
- sprintf (caseLbl, "_case_%d_%d",
+ SNPRINTF(caseLbl, sizeof(caseLbl),
+ "_case_%d_%d",
swStat->values.switchVals.swNum,
(int) floatFromVal (caseVal->opval.val));
swStat->values.switchVals.swDefault = 1;
/* create the label */
- sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
+ SNPRINTF (defLbl, sizeof(defLbl),
+ "_default_%d", swStat->values.switchVals.swNum);
return createLabel (newSymbol (defLbl, 0), stmnt);
}
}
/* create the labels */
- sprintf (buffer, "_iffalse_%d", Lblnum);
+ SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
ifFalse = newSymbol (buffer, NestLevel);
/* if no else body then end == false */
if (!elseBody)
ifEnd = ifFalse;
else
{
- sprintf (buffer, "_ifend_%d", Lblnum);
+ SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
ifEnd = newSymbol (buffer, NestLevel);
}
- sprintf (buffer, "_iftrue_%d", Lblnum);
+ SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
ifTrue = newSymbol (buffer, NestLevel);
Lblnum++;
name->stack = SPEC_STAK (fetype) = stack;
/* name needs to be mangled */
- sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
+ SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
body = resolveSymbols (body); /* resolve the symbols */
body = decorateType (body); /* propagateType & do semantic checks */