X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCval.c;h=31b4159c0e09a9d632b410cbac3cfedcdf3312a7;hb=c7dfe1a5cd275f3da65ed8c24da944a1500da33a;hp=016aad1503f23e1d2cbfd89199ef8d83f87798be;hpb=59a83cb7479f6d80dc9e1f602978f42b87ed25e5;p=fw%2Fsdcc diff --git a/src/SDCCval.c b/src/SDCCval.c index 016aad15..31b4159c 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -1,4 +1,3 @@ -void CatchMe() {} /*---------------------------------------------------------------------- SDCCval.c :- has routine to do all kinds of fun stuff with the value wrapper & with initialiser lists. @@ -98,6 +97,107 @@ revinit (initList * val) return prev; } +bool +convertIListToConstList(initList *src, literalList **lList) +{ + initList *iLoop; + literalList *head, *last, *newL; + + head = last = NULL; + + if (!src || src->type != INIT_DEEP) + { + return FALSE; + } + + iLoop = src->init.deep; + + while (iLoop) + { + if (iLoop->type != INIT_NODE) + { + return FALSE; + } + + if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node)))) + { + return FALSE; + } + iLoop = iLoop->next; + } + + // We've now established that the initializer list contains only literal values. + + iLoop = src->init.deep; + while (iLoop) + { + double val = AST_LIT_VALUE(iLoop->init.node); + + if (last && last->literalValue == val) + { + last->count++; + } + else + { + newL = Safe_malloc(sizeof(literalList)); + newL->literalValue = val; + newL->count = 1; + newL->next = NULL; + + if (last) + { + last->next = newL; + } + else + { + head = newL; + } + last = newL; + } + iLoop = iLoop->next; + } + + if (!head) + { + return FALSE; + } + + *lList = head; + return TRUE; +} + +literalList * +copyLiteralList(literalList *src) +{ + literalList *head, *prev, *newL; + + head = prev = NULL; + + while (src) + { + newL = Safe_malloc(sizeof(literalList)); + + newL->literalValue = src->literalValue; + newL->count = src->count; + newL->next = NULL; + + if (prev) + { + prev->next = newL; + } + else + { + head = newL; + } + prev = newL; + src = src->next; + } + + return head; +} + + + /*------------------------------------------------------------------*/ /* copyIlist - copy initializer list */ /*------------------------------------------------------------------*/ @@ -310,30 +410,32 @@ constVal (char *s) else sval = atol (s); - - if (SPEC_LONG (val->type) || sval > 32768) - { + // check if we have to promote to long + if (SPEC_LONG (val->type) || + (SPEC_USIGN(val->type) && sval>0xffff) || + (!SPEC_USIGN(val->type) && ((long)sval>32767 || (long)sval<-32768))) { if (SPEC_USIGN (val->type)) SPEC_CVAL (val->type).v_ulong = sval; else SPEC_CVAL (val->type).v_long = sval; SPEC_LONG (val->type) = 1; + return val; } + + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = sval; else - { - if (SPEC_USIGN (val->type)) - SPEC_CVAL (val->type).v_uint = sval; - else - SPEC_CVAL (val->type).v_int = sval; - } - - // check the size and make it a short if required - if (sval < 256) - SPEC_SHORT (val->etype) = 1; - + SPEC_CVAL (val->type).v_int = sval; + + + // check if we can make it a char + if ((SPEC_USIGN(val->type) && sval < 256) || + (!SPEC_USIGN(val->type) && ((long)sval<127 && (long)sval>-128))) { + SPEC_NOUN (val->etype) = V_CHAR; + } return val; - } + /*! /fn char hexEscape(char **src) /param src Pointer to 'x' from start of hex character value @@ -1310,7 +1412,7 @@ getNelements (sym_link * type, initList * ilist) ilist = ilist->init.deep; /* if type is a character array and there is only one - initialiser then get the length of the string */ + (string) initialiser then get the length of the string */ if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next) { ast *iast = ilist->init.node; @@ -1320,12 +1422,12 @@ getNelements (sym_link * type, initList * ilist) werror (E_INIT_WRONG); return 0; } - if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype)) + + if (IS_ARRAY (v->type) && IS_CHAR (v->etype)) + // yep, it's a string { - werror (E_INIT_WRONG); - return 0; + return DCL_ELEM (v->type); } - return DCL_ELEM (v->type); } i = 0;