X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCast.c;h=25640f80b516a75ac0f34a730d41a3c8fbd5fdef;hb=f8d2f13d4536e3fea8e1a0555afe0497a5ba33e1;hp=df6cccffaba0b7064b7d3b9211a721d5885f2fed;hpb=a98586cdec9a03df6eaf8890e67c8ace886d6839;p=fw%2Fsdcc diff --git a/src/SDCCast.c b/src/SDCCast.c index df6cccff..25640f80 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -46,7 +46,6 @@ int labelKey = 1; #define ALLOCATE 1 #define DEALLOCATE 2 -char buffer[1024]; int noLineno = 0; int noAlloc = 0; symbol *currFunc; @@ -224,7 +223,12 @@ copyAstValues (ast * dest, ast * src) case INLINEASM: dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1); strcpy (dest->values.inlineasm, src->values.inlineasm); + break; + case ARRAYINIT: + dest->values.constlist = copyLiteralList(src->values.constlist); + break; + case FOR: AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel)); AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel)); @@ -461,6 +465,7 @@ resolveSymbols (ast * tree) 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); + allocVariables (tree->opval.val->sym); } else { @@ -623,7 +628,7 @@ processParms (ast * func, /* have parameters */ if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto) { - werror (E_NONRENT_ARGS); + werror (W_NONRENT_ARGS); return 1; } @@ -737,20 +742,20 @@ processParms (ast * func, } } + /* the parameter type must be at least castable */ - if (checkType (defParm->type, actParm->ftype) == 0) - { - werror (E_TYPE_MISMATCH_PARM, *parmNumber); - werror (E_CONTINUE, "defined type "); - printTypeChain (defParm->type, stderr); - fprintf (stderr, "\n"); - werror (E_CONTINUE, "actual type "); - printTypeChain (actParm->ftype, stderr); - fprintf (stderr, "\n"); - } + if (compareType (defParm->type, actParm->ftype) == 0) { + werror (E_INCOMPAT_TYPES); + fprintf (stderr, "type --> '"); + printTypeChain (actParm->ftype, stderr); + fprintf (stderr, "' "); + fprintf (stderr, "assigned to type --> '"); + printTypeChain (defParm->type, stderr); + fprintf (stderr, "'\n"); + } /* if the parameter is castable then add the cast */ - if (checkType (defParm->type, actParm->ftype) < 0) + if (compareType (defParm->type, actParm->ftype) < 0) { ast *pTree = resolveSymbols (copyAst (actParm)); @@ -832,6 +837,7 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) ast *rast = NULL; initList *iloop; int lcnt = 0, size = 0; + literalList *literalL; /* take care of the special case */ /* array of characters can be init */ @@ -843,51 +849,77 @@ createIvalArray (ast * sym, sym_link * type, initList * ilist) return decorateType (resolveSymbols (rast)); - /* not the special case */ - if (ilist->type != INIT_DEEP) + /* not the special case */ + if (ilist->type != INIT_DEEP) { - werror (E_INIT_STRUCT, ""); - return NULL; + werror (E_INIT_STRUCT, ""); + return NULL; } - iloop = ilist->init.deep; - lcnt = DCL_ELEM (type); + iloop = ilist->init.deep; + lcnt = DCL_ELEM (type); - for (;;) + if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL)) { - ast *aSym; - size++; + ast *aSym; - aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1)))); - aSym = decorateType (resolveSymbols (aSym)); - rast = createIval (aSym, type->next, iloop, rast); - iloop = (iloop ? iloop->next : NULL); - if (!iloop) - break; - /* if not array limits given & we */ - /* are out of initialisers then */ - if (!DCL_ELEM (type) && !iloop) - break; - - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) { - /* if initializers left */ - if (iloop) { - // there has to be a better way - char *name=sym->opval.val->sym->name; - int lineno=sym->opval.val->sym->lineDef; - werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + aSym = decorateType (resolveSymbols(sym)); + + rast = newNode(ARRAYINIT, aSym, NULL); + rast->values.constlist = literalL; + + // Make sure size is set to length of initializer list. + while (iloop) + { + size++; + iloop = iloop->next; + } + + 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; + + werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + } + } + else + { + for (;;) + { + ast *aSym; + + aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++)))); + aSym = decorateType (resolveSymbols (aSym)); + rast = createIval (aSym, type->next, iloop, rast); + iloop = (iloop ? iloop->next : NULL); + if (!iloop) + { + break; + } + + /* no of elements given and we */ + /* have generated for all of them */ + if (!--lcnt) + { + // there has to be a better way + char *name=sym->opval.val->sym->name; + int lineno=sym->opval.val->sym->lineDef; + werror (W_EXESS_ARRAY_INITIALIZERS, name, lineno); + + break; + } } - break; - } } - /* if we have not been given a size */ - if (!DCL_ELEM (type)) - DCL_ELEM (type) = size; + /* if we have not been given a size */ + if (!DCL_ELEM (type)) + { + DCL_ELEM (type) = size; + } - return decorateType (resolveSymbols (rast)); + return decorateType (resolveSymbols (rast)); } @@ -912,7 +944,6 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) SPEC_SCLS (iexpr->etype) == S_CODE) && IS_ARRAY (iexpr->ftype)) { - /* for each character generate an assignment */ /* to the array element */ char *s = SPEC_CVAL (iexpr->etype).v_char; @@ -990,6 +1021,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /* if type is SPECIFIER */ if (IS_SPEC (type)) rast = createIvalType (sym, type, ilist); + if (wid) return decorateType (resolveSymbols (newNode (NULLOP, wid, rast))); else @@ -999,9 +1031,42 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) /*-----------------------------------------------------------------*/ /* initAggregates - initialises aggregate variables with initv */ /*-----------------------------------------------------------------*/ -ast * -initAggregates (symbol * sym, initList * ival, ast * wid) -{ + +/* this has to go */ void printIval (symbol *, sym_link *, initList *, FILE *); + +ast * initAggregates (symbol * sym, initList * ival, ast * wid) { + ast *ast; + symbol *newSym; + + if (getenv("TRY_THE_NEW_INITIALIZER")) { + + if (!TARGET_IS_MCS51 || !(options.model==MODEL_LARGE)) { + fprintf (stderr, "Can't \"TRY_THE_NEW_INITIALIZER\" unless " + "with -mmcs51 and --model-large"); + exit(404); + } + + if (SPEC_OCLS(sym->etype)==xdata && + getSize(sym->type) > 16) { // else it isn't worth it: do it the old way + + // copy this symbol + newSym=copySymbol (sym); + SPEC_OCLS(newSym->etype)=code; + sprintf (newSym->name, "%s_init__", sym->name); + sprintf (newSym->rname,"%s_init__", sym->rname); + addSym (SymbolTab, newSym, newSym->name, 0, 0, 1); + + // emit it in the static segment + addSet(&statsg->syms, newSym); + + // now memcpy() the entire array from cseg + ast=newNode (ARRAYINIT, // ASSIGN_AGGREGATE + newAst_VALUE (symbolVal (sym)), + newAst_VALUE (symbolVal (newSym))); + return decorateType(resolveSymbols(ast)); + } + } + return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid); } @@ -1041,7 +1106,7 @@ gatherAutoInit (symbol * autoChain) /* insert the symbol into the symbol table */ /* with level = 0 & name = rname */ newSym = copySymbol (sym); - addSym (SymbolTab, newSym, newSym->name, 0, 0, 1); + addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1); /* now lift the code to main */ if (IS_AGGREGATE (sym->type)) @@ -1137,8 +1202,8 @@ processBlockVars (ast * tree, int *stack, int action) if (action == ALLOCATE) { - autoInit = gatherAutoInit (tree->values.sym); *stack += allocVariables (tree->values.sym); + autoInit = gatherAutoInit (tree->values.sym); /* if there are auto inits then do them */ if (autoInit) @@ -1155,6 +1220,7 @@ processBlockVars (ast * tree, int *stack, int action) /*-----------------------------------------------------------------*/ /* constExprValue - returns the value of a constant expression */ +/* or NULL if it is not a constant expression */ /*-----------------------------------------------------------------*/ value * constExprValue (ast * cexpr, int check) @@ -1391,11 +1457,25 @@ astHasSymbol (ast * tree, symbol * sym) else return FALSE; } - + return astHasSymbol (tree->left, sym) || astHasSymbol (tree->right, sym); } +/*-----------------------------------------------------------------*/ +/* astHasDeref - return true if the ast has an indirect access */ +/*-----------------------------------------------------------------*/ +static bool +astHasDeref (ast * tree) +{ + if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree)) + return FALSE; + + if (tree->opval.op == '*' && tree->right == NULL) return TRUE; + + return astHasDeref (tree->left) || astHasDeref (tree->right); +} + /*-----------------------------------------------------------------*/ /* isConformingBody - the loop body has to conform to a set of rules */ /* for the loop to be considered reversible read on for rules */ @@ -1546,6 +1626,8 @@ isConformingBody (ast * pbody, symbol * sym, ast * body) if (astHasVolatile (pbody->left)) return FALSE; + + if (astHasDeref(pbody->right)) return FALSE; return isConformingBody (pbody->left, sym, body) && isConformingBody (pbody->right, sym, body); @@ -1712,7 +1794,7 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) } -#define DEMAND_INTEGER_PROMOTION +//#define DEMAND_INTEGER_PROMOTION #ifdef DEMAND_INTEGER_PROMOTION @@ -1908,10 +1990,10 @@ decorateType (ast * tree) switch (tree->opval.op) { -/*------------------------------------------------------------------*/ -/*----------------------------*/ - /* array node */ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ + /* array node */ + /*----------------------------*/ case '[': /* determine which is the array & which the index */ @@ -1950,10 +2032,10 @@ decorateType (ast * tree) } return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* struct/union */ -/*----------------------------*/ + /*----------------------------*/ case '.': /* if this is not a structure */ if (!IS_STRUCT (LTYPE (tree))) @@ -1967,10 +2049,10 @@ decorateType (ast * tree) TETYPE (tree) = getSpec (TTYPE (tree)); return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* struct/union pointer */ -/*----------------------------*/ + /*----------------------------*/ case PTR_OP: /* if not pointer to a structure */ if (!IS_PTR (LTYPE (tree))) @@ -2000,7 +2082,7 @@ decorateType (ast * tree) { sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree)); COPYTYPE (TTYPE (tree), TETYPE (tree), ltc); - if (!tree->initMode && IS_CONSTANT (TETYPE (tree))) + if (!tree->initMode && IS_CONSTANT(TETYPE(tree))) werror (E_CODE_WRITE, "++/--"); if (tree->right) @@ -2022,7 +2104,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2052,6 +2134,9 @@ decorateType (ast * tree) return decorateType (otree); } +#if 0 + // we can't do this because of "(int & 0xff) << 3" + /* if right or left is literal then result of that type */ if (IS_LITERAL (RTYPE (tree))) { @@ -2076,6 +2161,11 @@ decorateType (ast * tree) TETYPE (tree) = getSpec (TTYPE (tree)); } } +#else + TTYPE (tree) = + computeType (LTYPE (tree), RTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); +#endif LRVAL (tree) = RRVAL (tree) = 1; return tree; } @@ -2160,7 +2250,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2222,7 +2312,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { werror (E_BITWISE_OP); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2581,7 +2671,7 @@ decorateType (ast * tree) if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype)) { werror (E_SHIFT_OP_INVALID); - werror (E_CONTINUE, "left & right types are "); + werror (W_CONTINUE, "left & right types are "); printTypeChain (LTYPE (tree), stderr); fprintf (stderr, ","); printTypeChain (RTYPE (tree), stderr); @@ -2627,10 +2717,10 @@ decorateType (ast * tree) } return tree; -/*------------------------------------------------------------------*/ -/*----------------------------*/ + /*------------------------------------------------------------------*/ + /*----------------------------*/ /* casting */ -/*----------------------------*/ + /*----------------------------*/ case CAST: /* change the type */ /* cannot cast to an aggregate type */ if (IS_AGGREGATE (LTYPE (tree))) @@ -2642,23 +2732,51 @@ decorateType (ast * tree) /* make sure the type is complete and sane */ checkTypeSanity(LETYPE(tree), "(cast)"); +#if 0 /* if the right is a literal replace the tree */ - if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) - { - tree->type = EX_VALUE; - tree->opval.val = - valCastLiteral (LTYPE (tree), - floatFromVal (valFromType (RETYPE (tree)))); - tree->left = NULL; - tree->right = NULL; - TTYPE (tree) = tree->opval.val->type; - tree->values.literalFromCast = 1; - } - else - { - TTYPE (tree) = LTYPE (tree); - LRVAL (tree) = 1; - } + if (IS_LITERAL (RETYPE (tree))) { + if (!IS_PTR (LTYPE (tree))) { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + 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 */ { + sym_link *rest = LTYPE(tree)->next; + werror(W_LITERAL_GENERIC); + TTYPE(tree) = newLink(); + DCL_TYPE(TTYPE(tree)) = FPOINTER; + TTYPE(tree)->next = rest; + tree->left->opval.lnk = TTYPE(tree); + LRVAL (tree) = 1; + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } +#else + /* if the right is a literal replace the tree */ + if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + TTYPE (tree) = tree->opval.val->type; + tree->values.literalFromCast = 1; + } else { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } +#endif TETYPE (tree) = getSpec (TTYPE (tree)); @@ -2724,7 +2842,7 @@ decorateType (ast * tree) /* if they are pointers they must be castable */ if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) { - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); fprintf (stderr, "comparing type "); @@ -2741,7 +2859,7 @@ decorateType (ast * tree) if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) || (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))))) - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_COMPARE_OP); fprintf (stderr, "comparing type "); @@ -2798,7 +2916,7 @@ decorateType (ast * tree) case ':': /* if they don't match we have a problem */ - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_TYPE_MISMATCH, "conditional operator", " "); goto errorTreeReturn; @@ -2963,7 +3081,7 @@ decorateType (ast * tree) } /* they should either match or be castable */ - if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + if (compareType (LTYPE (tree), RTYPE (tree)) == 0) { werror (E_TYPE_MISMATCH, "assignment", " "); fprintf (stderr, "type --> '"); @@ -2988,22 +3106,13 @@ decorateType (ast * tree) fprintf (stderr, "'\n"); } - /* extra checks for pointer types */ - if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) && - !IS_GENPTR (LTYPE (tree))) - { - if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree))) - werror (W_PTR_ASSIGN); - } - TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); RRVAL (tree) = 1; LLVAL (tree) = 1; if (!tree->initMode ) { - if (IS_CONSTANT (LETYPE (tree))) { - werror (E_CODE_WRITE, " "); - } + if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree)))) + werror (E_CODE_WRITE, " "); } if (LRVAL (tree)) { @@ -3053,9 +3162,9 @@ decorateType (ast * tree) if (!tree->right) goto voidcheck; - if (checkType (currFunc->type->next, RTYPE (tree)) == 0) + if (compareType (currFunc->type->next, RTYPE (tree)) == 0) { - werror (E_RETURN_MISMATCH); + werror (W_RETURN_MISMATCH); goto errorTreeReturn; } @@ -3068,7 +3177,7 @@ decorateType (ast * tree) } /* if there is going to be a casing required then add it */ - if (checkType (currFunc->type->next, RTYPE (tree)) < 0) + if (compareType (currFunc->type->next, RTYPE (tree)) < 0) { #if 0 && defined DEMAND_INTEGER_PROMOTION if (IS_INTEGRAL (currFunc->type->next)) @@ -4164,7 +4273,7 @@ skipall: addSet (&operKeyReset, name); applyToSet (operKeyReset, resetParmKey); - if (options.debug && !options.nodebug) + if (options.debug) cdbStructBlock (1, cdbFile); cleanUpLevel (LabelTab, 0);