X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=9944eb407736217f94da4d98f6533c0c194cd5de;hb=1fcf333be9b5b4f71405a11db6d483abc271d683;hp=d0ba0c9b26fbabd151b9d0e13e3657df77f0574f;hpb=feddd68be35917362867a364ba8c51b7986cd67b;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index d0ba0c9b..9944eb40 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -84,6 +84,7 @@ newAst_ (unsigned type) ex->level = NestLevel; ex->block = currBlockno; ex->initMode = inInitMode; + ex->seqPoint = seqPointNo; return ex; } @@ -273,6 +274,52 @@ ast *removeIncDecOps (ast * tree) { return tree; } +/*-----------------------------------------------------------------*/ +/* removePreIncDecOps: remove for side effects in *_ASSIGN's */ +/* "*++s += 3" -> "*++s = *++s + 3" */ +/*-----------------------------------------------------------------*/ +ast *removePreIncDecOps (ast * tree) { + + // traverse the tree and remove pre-inc/dec ops + + if (!tree) + return NULL; + + if (tree->type == EX_OP && + (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) { + if (tree->right) + tree=tree->right; + } + + tree->left=removePreIncDecOps(tree->left); + tree->right=removePreIncDecOps(tree->right); + + return tree; +} + +/*-----------------------------------------------------------------*/ +/* removePostIncDecOps: remove for side effects in *_ASSIGN's */ +/* "*s++ += 3" -> "*s++ = *s++ + 3" */ +/*-----------------------------------------------------------------*/ +ast *removePostIncDecOps (ast * tree) { + + // traverse the tree and remove pre-inc/dec ops + + if (!tree) + return NULL; + + if (tree->type == EX_OP && + (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) { + if (tree->left) + tree=tree->left; + } + + tree->left=removePostIncDecOps(tree->left); + tree->right=removePostIncDecOps(tree->right); + + return tree; +} + /*-----------------------------------------------------------------*/ /* hasSEFcalls - returns TRUE if tree has a function call */ /*-----------------------------------------------------------------*/ @@ -297,7 +344,7 @@ hasSEFcalls (ast * tree) /*-----------------------------------------------------------------*/ /* isAstEqual - compares two asts & returns 1 if they are equal */ /*-----------------------------------------------------------------*/ -int +static int isAstEqual (ast * t1, ast * t2) { if (!t1 && !t2) @@ -383,7 +430,8 @@ resolveSymbols (ast * tree) tree->trueLabel->name))) tree->trueLabel = csym; else - werror (E_LABEL_UNDEF, tree->trueLabel->name); + werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, + tree->trueLabel->name); } if (tree->falseLabel) @@ -393,7 +441,8 @@ resolveSymbols (ast * tree) tree->falseLabel->name))) tree->falseLabel = csym; else - werror (E_LABEL_UNDEF, tree->falseLabel->name); + werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, + tree->falseLabel->name); } } @@ -408,7 +457,8 @@ resolveSymbols (ast * tree) tree->opval.val->sym->name); if (!csym) - werror (E_LABEL_UNDEF, tree->opval.val->sym->name); + werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF, + tree->opval.val->sym->name); else tree->opval.val->sym = csym; @@ -447,7 +497,9 @@ resolveSymbols (ast * tree) tree->opval.val->sym->etype = newIntLink (); tree->opval.val->etype = tree->opval.val->etype; tree->opval.val->type = tree->opval.val->sym->type; - werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name); + werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC, + tree->opval.val->sym->name); + //tree->opval.val->sym->undefined = 1; allocVariables (tree->opval.val->sym); } else @@ -624,6 +676,8 @@ processParms (ast * func, /* exist and this is not defined as a variable arg */ if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype)) { + //if (func->type==EX_VALUE && func->opval.val->sym->undefined) + // return 1; /* Already gave them an undefined function error */ werror (E_TOO_MANY_PARMS); return 1; } @@ -811,8 +865,9 @@ createIvalStruct (ast * sym, sym_link * type, initList * ilist) } if (iloop) { - werror (W_EXCESS_INITIALIZERS, "struct", - sym->opval.val->sym->name, sym->opval.val->sym->lineDef); + werrorfl (filename, sym->opval.val->sym->lineDef, + W_EXCESS_INITIALIZERS, "struct", + sym->opval.val->sym->name); } return rast; @@ -872,7 +927,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) char *name=sym->opval.val->sym->name; int lineno=sym->opval.val->sym->lineDef; - werror (W_EXCESS_INITIALIZERS, "array", name, lineno); + werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); } } else @@ -897,7 +952,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) // there has to be a better way char *name=sym->opval.val->sym->name; int lineno=sym->opval.val->sym->lineDef; - werror (W_EXCESS_INITIALIZERS, "array", name, lineno); + werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name); break; } @@ -939,8 +994,18 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) /* to the array element */ char *s = SPEC_CVAL (iexpr->etype).v_char; int i = 0; + int size = getSize (iexpr->ftype); + int symsize = getSize (type); + + if (size>symsize) + { + if (size>(symsize+1)) + werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS, + "string", sym->opval.val->sym->name); + size = symsize; + } - while (*s) + for (i=0;iival, NULL); } else { if (getNelements(sym->type, sym->ival)>1) { - werror (W_EXCESS_INITIALIZERS, "scalar", - sym->name, sym->lineDef); + werrorfl (filename, sym->lineDef, + W_EXCESS_INITIALIZERS, "scalar", + sym->name); } work = newNode ('=', newAst_VALUE (symbolVal (newSym)), list2expr (sym->ival)); @@ -1103,8 +1162,9 @@ gatherAutoInit (symbol * autoChain) work = initAggregates (sym, sym->ival, NULL); } else { if (getNelements(sym->type, sym->ival)>1) { - werror (W_EXCESS_INITIALIZERS, "scalar", - sym->name, sym->lineDef); + werrorfl (filename, sym->lineDef, + W_EXCESS_INITIALIZERS, "scalar", + sym->name); } work = newNode ('=', newAst_VALUE (symbolVal (sym)), list2expr (sym->ival)); @@ -1148,12 +1208,14 @@ stringToSymbol (value * val) static int charLbl = 0; symbol *sym; set *sp; + int size; // 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)) { + 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); @@ -1532,7 +1594,7 @@ astHasSymbol (ast * tree, symbol * sym) else return FALSE; } - + return astHasSymbol (tree->left, sym) || astHasSymbol (tree->right, sym); } @@ -2047,6 +2109,28 @@ decorateType (ast * tree) { ast *dtl, *dtr; + #if 0 + if (tree->opval.op == NULLOP || tree->opval.op == BLOCK) + { + if (tree->left && tree->left->type == EX_OPERAND + && (tree->left->opval.op == INC_OP + || tree->left->opval.op == DEC_OP) + && tree->left->left) + { + tree->left->right = tree->left->left; + tree->left->left = NULL; + } + if (tree->right && tree->right->type == EX_OPERAND + && (tree->right->opval.op == INC_OP + || tree->right->opval.op == DEC_OP) + && tree->right->left) + { + tree->right->right = tree->right->left; + tree->right->left = NULL; + } + } + #endif + dtl = decorateType (tree->left); /* delay right side for '?' operator since conditional macro expansions might rely on this */ @@ -2168,6 +2252,7 @@ decorateType (ast * tree) /* adjust the storage class */ switch (DCL_TYPE(tree->left->ftype)) { case POINTER: + SPEC_SCLS(TETYPE(tree)) = S_DATA; break; case FPOINTER: SPEC_SCLS(TETYPE(tree)) = S_XDATA; @@ -2176,6 +2261,7 @@ decorateType (ast * tree) SPEC_SCLS(TETYPE(tree)) = S_CODE; break; case GPOINTER: + SPEC_SCLS (TETYPE (tree)) = 0; break; case PPOINTER: SPEC_SCLS(TETYPE(tree)) = S_XSTACK; @@ -2187,11 +2273,17 @@ decorateType (ast * tree) SPEC_SCLS(TETYPE(tree)) = S_EEPROM; break; case UPOINTER: + SPEC_SCLS (TETYPE (tree)) = 0; + break; case ARRAY: case FUNCTION: break; } + /* This breaks with extern declarations, bitfields, and perhaps other */ + /* cases (gcse). Let's leave this optimization disabled for now and */ + /* ponder if there's a safe way to do this. -- EEP */ + #if 0 if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left) && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype)) { @@ -2224,7 +2316,8 @@ decorateType (ast * tree) tree->left = NULL; tree->right = NULL; } - + #endif + return tree; /*------------------------------------------------------------------*/ @@ -2289,7 +2382,7 @@ decorateType (ast * tree) } TTYPE (tree) = - computeType (LTYPE (tree), RTYPE (tree)); + computeType (LTYPE (tree), RTYPE (tree), FALSE); TETYPE (tree) = getSpec (TTYPE (tree)); /* if left is a literal exchange left & right */ @@ -2333,7 +2426,7 @@ decorateType (ast * tree) goto errorTreeReturn; } - if (SPEC_SCLS (tree->left->etype) == S_REGISTER) + if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER) { werror (E_ILLEGAL_ADDR, "address of register variable"); goto errorTreeReturn; @@ -2356,7 +2449,9 @@ decorateType (ast * tree) werror (E_LVALUE_REQUIRED, "address of"); goto errorTreeReturn; } - if (SPEC_SCLS (tree->left->etype) == S_CODE) + if (!LETYPE (tree)) + DCL_TYPE (p) = POINTER; + else if (SPEC_SCLS (tree->left->etype) == S_CODE) DCL_TYPE (p) = CPOINTER; else if (SPEC_SCLS (tree->left->etype) == S_XDATA) DCL_TYPE (p) = FPOINTER; @@ -2414,8 +2509,6 @@ decorateType (ast * tree) wtree = optimizeSWAP (tree); if (wtree != tree) return decorateType (wtree); - - // fall through } /* if left is a literal exchange left & right */ @@ -2442,6 +2535,8 @@ decorateType (ast * tree) decorateType (parent); } } + /* fall through */ + /*------------------------------------------------------------------*/ /*----------------------------*/ /* bitwise xor */ @@ -2483,7 +2578,8 @@ decorateType (ast * tree) /* if right is a literal and */ /* we can find a 2nd literal in a xor-tree then */ /* rearrange the tree */ - if (IS_LITERAL (RTYPE (tree))) + if (IS_LITERAL (RTYPE (tree)) && + tree->opval.op == '^') /* the same source is used by 'bitwise or' */ { ast *parent; ast *litTree = searchLitOp (tree, &parent, "^"); @@ -2500,7 +2596,10 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); + + return tree; /*------------------------------------------------------------------*/ /*----------------------------*/ @@ -2528,7 +2627,8 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + TRUE)); /* if right is a literal and */ /* left is also a division by a literal then */ @@ -2593,7 +2693,8 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + TRUE)); return tree; /*------------------------------------------------------------------*/ @@ -2621,6 +2722,36 @@ decorateType (ast * tree) } TTYPE (tree) = copyLinkChain (LTYPE (tree)->next); TETYPE (tree) = getSpec (TTYPE (tree)); + /* adjust the storage class */ + switch (DCL_TYPE(tree->left->ftype)) { + case POINTER: + SPEC_SCLS(TETYPE(tree)) = S_DATA; + break; + case FPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_XDATA; + break; + case CPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_CODE; + break; + case GPOINTER: + SPEC_SCLS (TETYPE (tree)) = 0; + break; + case PPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_XSTACK; + break; + case IPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_IDATA; + break; + case EEPPOINTER: + SPEC_SCLS(TETYPE(tree)) = S_EEPROM; + break; + case UPOINTER: + SPEC_SCLS (TETYPE (tree)) = 0; + break; + case ARRAY: + case FUNCTION: + break; + } return tree; } @@ -2675,13 +2806,8 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); - - /* promote result to int if left & right are char - this will facilitate hardware multiplies 8bit x 8bit = 16bit */ - if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) { - SPEC_NOUN(TETYPE(tree)) = V_INT; - } + RTYPE (tree), + TRUE)); return tree; @@ -2693,7 +2819,7 @@ decorateType (ast * tree) /* if unary plus */ if (!tree->right) { - if (!IS_INTEGRAL (LTYPE (tree))) + if (!IS_ARITHMETIC (LTYPE (tree))) { werror (E_UNARY_OP, '+'); goto errorTreeReturn; @@ -2812,7 +2938,8 @@ decorateType (ast * tree) else TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); return tree; /*------------------------------------------------------------------*/ @@ -2911,7 +3038,8 @@ decorateType (ast * tree) else TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); LRVAL (tree) = RRVAL (tree) = 1; @@ -3051,28 +3179,43 @@ decorateType (ast * tree) return tree; } + LRVAL (tree) = RRVAL (tree) = 1; + if (tree->opval.op == LEFT_OP) + { + /* promote char to int */ + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + LTYPE (tree), /* no, not RTYPE! */ + TRUE)); + } + else /* RIGHT_OP */ + { + /* no promotion necessary */ + TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree)); + if (IS_LITERAL (TTYPE (tree))) + SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL; + } + /* if only the right side is a literal & we are shifting more than size of the left operand then zero */ if (IS_LITERAL (RTYPE (tree)) && - ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >= - (getSize (LTYPE (tree)) * 8)) + ((TYPE_UDWORD) floatFromVal (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, - (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; - } + (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) + { + lineno=tree->lineno; + werror (W_SHIFT_CHANGED, + (tree->opval.op == LEFT_OP ? "left" : "right")); + tree->type = EX_VALUE; + tree->left = tree->right = NULL; + tree->opval.val = constVal ("0"); + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } } - LRVAL (tree) = RRVAL (tree) = 1; - TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree)); - if (IS_LITERAL (TTYPE (tree))) - SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL; + return tree; /*------------------------------------------------------------------*/ @@ -3166,7 +3309,7 @@ decorateType (ast * tree) tree->opval.val = valCastLiteral ( LTYPE (tree), element->offset - + floatFromVal (valFromType (RETYPE (tree->right->left->left))) + + floatFromVal (valFromType (RTYPE (tree->right->left->left))) ); TTYPE (tree) = tree->opval.val->type; @@ -3179,7 +3322,8 @@ decorateType (ast * tree) /* if the right is a literal replace the tree */ if (IS_LITERAL (RETYPE (tree))) { - if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) { + #if 0 + if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) { /* rewrite (type *)litaddr as &temp and define type at litaddr temp @@ -3202,7 +3346,7 @@ decorateType (ast * tree) sym->cdef = 1; sym->isref = 1; SPEC_STAT (sym->etype) = 1; - SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree))); + SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree))); SPEC_ABSA(sym->etype) = 1; addSym (SymbolTab, sym, sym->name, 0, 0, 0); allocGlobal (sym); @@ -3216,11 +3360,12 @@ decorateType (ast * tree) TLVAL (newTree) = 1; return newTree; } + #endif if (!IS_PTR (LTYPE (tree))) { tree->type = EX_VALUE; tree->opval.val = valCastLiteral (LTYPE (tree), - floatFromVal (valFromType (RETYPE (tree)))); + floatFromVal (valFromType (RTYPE (tree)))); TTYPE (tree) = tree->opval.val->type; tree->left = NULL; tree->right = NULL; @@ -3265,8 +3410,8 @@ decorateType (ast * tree) IS_LITERAL (LTYPE (tree))) { tree->type = EX_VALUE; - tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)), - valFromType (RETYPE (tree)), + tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)), + valFromType (RTYPE (tree)), tree->opval.op); tree->right = tree->left = NULL; TETYPE (tree) = getSpec (TTYPE (tree) = @@ -3307,7 +3452,7 @@ decorateType (ast * tree) if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); - fprintf (stderr, "comparring type "); + fprintf (stderr, "comparing type "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, "to type "); printTypeChain (RTYPE (tree), stderr); @@ -3334,16 +3479,18 @@ decorateType (ast * tree) } /* if unsigned value < 0 then always false */ /* if (unsigned value) > 0 then (unsigned value) */ - if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && - ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) { - - if (tree->opval.op == '<') { + if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && + ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) + { + if (tree->opval.op == '<') + { return tree->right; - } - if (tree->opval.op == '>') { + } + if (tree->opval.op == '>') + { return tree->left; - } - } + } + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && @@ -3482,7 +3629,7 @@ decorateType (ast * tree) goto errorTreeReturn; } - TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree)); + TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -3505,11 +3652,11 @@ decorateType (ast * tree) TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); if (!tree->initMode && IS_CONSTANT (LTYPE (tree))) - werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/="); + werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); if (LRVAL (tree)) { - werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/="); + werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/="); goto errorTreeReturn; } LLVAL (tree) = 1; @@ -3564,7 +3711,8 @@ decorateType (ast * tree) RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) werror (E_CODE_WRITE, "-="); @@ -3605,7 +3753,8 @@ decorateType (ast * tree) RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) werror (E_CODE_WRITE, "+="); @@ -3710,7 +3859,7 @@ decorateType (ast * tree) if (compareType (currFunc->type->next, RTYPE (tree)) == 0) { - werror (W_RETURN_MISMATCH); + werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH); printFromToType (RTYPE(tree), currFunc->type->next); goto errorTreeReturn; } @@ -3719,7 +3868,7 @@ decorateType (ast * tree) && tree->right && !IS_VOID (RTYPE (tree))) { - werror (E_FUNC_VOID); + werrorfl (tree->filename, tree->lineno, E_FUNC_VOID); goto errorTreeReturn; } @@ -3754,7 +3903,7 @@ decorateType (ast * tree) /* the switch value must be an integer */ if (!IS_INTEGRAL (LTYPE (tree))) { - werror (E_SWITCH_NON_INTEGER); + werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER); goto errorTreeReturn; } LRVAL (tree) = 1; @@ -4011,7 +4160,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) /* then case is out of context */ if (!swStat) { - werror (E_CASE_CONTEXT); + werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT); return NULL; } @@ -4019,14 +4168,14 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) /* if not a constant then error */ if (!IS_LITERAL (caseVal->ftype)) { - werror (E_CASE_CONSTANT); + werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT); return NULL; } /* if not a integer than error */ if (!IS_INTEGRAL (caseVal->ftype)) { - werror (E_CASE_NON_INTEGER); + werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER); return NULL; } @@ -4049,6 +4198,12 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) { pval->next = caseVal->opval.val; } + else if ((int) floatFromVal (val) == cVal) + { + werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL, + "case"); + return NULL; + } else { /* we found a value greater than */ @@ -4081,7 +4236,7 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt) /* createDefault - creates the parse tree for the default statement */ /*-----------------------------------------------------------------*/ ast * -createDefault (ast * swStat, ast * stmnt) +createDefault (ast * swStat, ast * defaultVal, ast * stmnt) { char defLbl[SDCC_NAME_MAX + 1]; @@ -4089,7 +4244,14 @@ createDefault (ast * swStat, ast * stmnt) /* then case is out of context */ if (!swStat) { - werror (E_CASE_CONTEXT); + werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT); + return NULL; + } + + if (swStat->values.switchVals.swDefault) + { + werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL, + "default"); return NULL; } @@ -5002,7 +5164,7 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val)); else fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val)); - fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val), + fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val), floatFromVal(tree->opval.val)); } else if (tree->opval.val->sym) { /* if the undefined flag is set then give error message */ @@ -5614,3 +5776,29 @@ void PA(ast *t) { ast_print(t,stdout,0); } + + + +/*-----------------------------------------------------------------*/ +/* astErrors : returns non-zero if errors present in tree */ +/*-----------------------------------------------------------------*/ +int astErrors(ast *t) +{ + int errors=0; + + if (t) + { + if (t->isError) + errors++; + + if (t->type == EX_VALUE + && t->opval.val->sym + && t->opval.val->sym->undefined) + errors++; + + errors += astErrors(t->left); + errors += astErrors(t->right); + } + + return errors; +}