1 /*----------------------------------------------------------------------
2     SDCCval.c :- has routine to do all kinds of fun stuff with the
3                 value wrapper & with initialiser lists.
4 
5     Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 
7     This program is free software; you can redistribute it and/or modify it
8     under the terms of the GNU General Public License as published by the
9     Free Software Foundation; either version 2, or (at your option) any
10     later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 
21     In other words, you are welcome to use, share and improve this program.
22     You are forbidden to forbid anyone else to use, share and improve
23     what you give them.   Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
25 
26 #include "common.h"
27 #include <math.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include "newalloc.h"
32 #include "dbuf_string.h"
33 
34 long cNestLevel;
35 
36 
37 /*-----------------------------------------------------------------*/
38 /* newValue - allocates and returns a new value                    */
39 /*-----------------------------------------------------------------*/
40 value *
newValue(void)41 newValue (void)
42 {
43   value *val;
44 
45   val = Safe_alloc (sizeof (value));
46 
47   return val;
48 }
49 
50 /*-----------------------------------------------------------------*/
51 /* newiList - new initializer list                                 */
52 /*-----------------------------------------------------------------*/
53 initList *
newiList(int type,void * ilist)54 newiList (int type, void *ilist)
55 {
56   initList *nilist;
57 
58   nilist = Safe_alloc (sizeof (initList));
59 
60   nilist->type = type;
61   nilist->filename = lexFilename;
62   nilist->lineno = lexLineno;
63   nilist->designation = NULL;
64 
65   switch (type)
66     {
67     case INIT_NODE:
68       nilist->init.node = (struct ast *) ilist;
69       break;
70 
71     case INIT_DEEP:
72       nilist->init.deep = (struct initList *) ilist;
73       break;
74     }
75 
76   return nilist;
77 }
78 
79 /*------------------------------------------------------------------*/
80 /* revinit   - reverses the initial values for a value chain        */
81 /*------------------------------------------------------------------*/
82 initList *
revinit(initList * val)83 revinit (initList * val)
84 {
85   initList *prev, *curr, *next;
86 
87   if (!val)
88     return NULL;
89 
90   prev = val;
91   curr = val->next;
92 
93   while (curr)
94     {
95       next = curr->next;
96       curr->next = prev;
97       prev = curr;
98       curr = next;
99     }
100   val->next = (void *) NULL;
101   return prev;
102 }
103 
104 bool
convertIListToConstList(initList * src,literalList ** lList,int size)105 convertIListToConstList (initList * src, literalList ** lList, int size)
106 {
107   int cnt = 0;
108   initList *iLoop;
109   literalList *head, *last, *newL;
110 
111   head = last = NULL;
112 
113   if (src && src->type != INIT_DEEP)
114     {
115       return FALSE;
116     }
117 
118   iLoop = src ? src->init.deep : NULL;
119 
120   while (iLoop)
121     {
122       if (iLoop->designation != NULL)
123         {
124           return FALSE;
125         }
126 
127       if (iLoop->type != INIT_NODE)
128         {
129           return FALSE;
130         }
131 
132       if (!IS_AST_LIT_VALUE (decorateType (resolveSymbols (iLoop->init.node), RESULT_TYPE_NONE)))
133         {
134           return FALSE;
135         }
136       iLoop = iLoop->next;
137       cnt++;
138     }
139   if (!size)
140     {
141       size = cnt;
142     }
143 
144   /* We've now established that the initializer list contains only literal values. */
145 
146   iLoop = src ? src->init.deep : NULL;
147   while (size--)
148     {
149       double val = iLoop ? AST_FLOAT_VALUE (iLoop->init.node) : 0;
150 
151       if (last && last->literalValue == val)
152         {
153           last->count++;
154         }
155       else
156         {
157           newL = Safe_alloc (sizeof (literalList));
158           newL->literalValue = val;
159           newL->count = 1;
160           newL->next = NULL;
161 
162           if (last)
163             {
164               last->next = newL;
165             }
166           else
167             {
168               head = newL;
169             }
170           last = newL;
171         }
172       iLoop = iLoop ? iLoop->next : NULL;
173     }
174 
175   if (!head)
176     {
177       return FALSE;
178     }
179 
180   *lList = head;
181   return TRUE;
182 }
183 
184 literalList *
copyLiteralList(literalList * src)185 copyLiteralList (literalList * src)
186 {
187   literalList *head, *prev, *newL;
188 
189   head = prev = NULL;
190 
191   while (src)
192     {
193       newL = Safe_alloc (sizeof (literalList));
194 
195       newL->literalValue = src->literalValue;
196       newL->count = src->count;
197       newL->next = NULL;
198 
199       if (prev)
200         {
201           prev->next = newL;
202         }
203       else
204         {
205           head = newL;
206         }
207       prev = newL;
208       src = src->next;
209     }
210 
211   return head;
212 }
213 
214 /*------------------------------------------------------------------*/
215 /* copyIlist - copy initializer list                                */
216 /*------------------------------------------------------------------*/
217 initList *
copyIlist(initList * src)218 copyIlist (initList * src)
219 {
220   initList *dest = NULL;
221 
222   if (!src)
223     return NULL;
224 
225   switch (src->type)
226     {
227     case INIT_DEEP:
228       dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
229       break;
230     case INIT_NODE:
231       dest = newiList (INIT_NODE, copyAst (src->init.node));
232       break;
233     }
234 
235   if (src->designation)
236     dest->designation = copyDesignation (src->designation);
237 
238   if (src->next)
239     assert (dest != NULL);
240   dest->next = copyIlist (src->next);
241 
242   return dest;
243 }
244 
245 /*------------------------------------------------------------------*/
246 /* list2int - converts the first element of the list to value       */
247 /*------------------------------------------------------------------*/
248 double
list2int(initList * val)249 list2int (initList * val)
250 {
251   initList *i = val;
252 
253   assert (i->type != INIT_HOLE);
254 
255   if (i->type == INIT_DEEP)
256     return list2int (val->init.deep);
257 
258   return floatFromVal (constExprValue (val->init.node, TRUE));
259 }
260 
261 /*------------------------------------------------------------------*/
262 /* list2val - converts the first element of the list to value       */
263 /*------------------------------------------------------------------*/
264 value *
list2val(initList * val,int check)265 list2val (initList * val, int check)
266 {
267   if (!val)
268     return NULL;
269 
270   if(val->type == INIT_HOLE)
271     return NULL;
272 
273   if (val->type == INIT_DEEP)
274     return list2val (val->init.deep, check);
275 
276   if (val->type == INIT_NODE && val->init.node->opval.op == CAST)
277     return constExprValue (val->init.node->right, check);
278 
279   return constExprValue (val->init.node, check);
280 }
281 
282 /*------------------------------------------------------------------*/
283 /* list2expr - returns the first expression in the initializer list */
284 /*------------------------------------------------------------------*/
285 ast *
list2expr(initList * ilist)286 list2expr (initList * ilist)
287 {
288   if (!ilist)
289     return NULL;
290 
291   assert (ilist->type != INIT_HOLE);
292 
293   if (ilist->type == INIT_DEEP)
294     return list2expr (ilist->init.deep);
295   return ilist->init.node;
296 }
297 
298 /*------------------------------------------------------------------*/
299 /* resolveIvalSym - resolve symbols in initial values               */
300 /*------------------------------------------------------------------*/
301 void
resolveIvalSym(initList * ilist,sym_link * type)302 resolveIvalSym (initList *ilist, sym_link *type)
303 {
304   int is_ptr = IS_PTR (type) || (IS_ARRAY(type) && IS_PTR(type->next));
305   RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
306 
307   while (ilist)
308     {
309       if (ilist->type == INIT_NODE)
310         {
311           ilist->init.node = decorateType (resolveSymbols (ilist->init.node), is_ptr ? RESULT_TYPE_INT : resultType);
312         }
313       else if (ilist->type == INIT_DEEP)
314         {
315           resolveIvalSym (ilist->init.deep, type);
316         }
317 
318       ilist = ilist->next;
319     }
320 }
321 
322 /*-----------------------------------------------------------------*/
323 /* newDesignation - new designation                                */
324 /*-----------------------------------------------------------------*/
325 designation *
newDesignation(int type,void * designator)326 newDesignation (int type, void *designator)
327 {
328   designation *ndesignation;
329 
330   ndesignation = Safe_alloc (sizeof (designation));
331 
332   ndesignation->type = type;
333   ndesignation->filename = lexFilename;
334   ndesignation->lineno = lexLineno;
335 
336   switch (type)
337     {
338     case DESIGNATOR_STRUCT:
339       ndesignation->designator.tag = (struct symbol *) designator;
340       break;
341 
342     case DESIGNATOR_ARRAY:
343       ndesignation->designator.elemno = * ((int *) designator);
344       break;
345     }
346 
347   return ndesignation;
348 }
349 
350 /*------------------------------------------------------------------*/
351 /* revDesignation   - reverses the designation chain                */
352 /*------------------------------------------------------------------*/
353 designation *
revDesignation(designation * val)354 revDesignation (designation * val)
355 {
356   designation *prev, *curr, *next;
357 
358   if (!val)
359     return NULL;
360 
361   prev = val;
362   curr = val->next;
363 
364   while (curr)
365     {
366       next = curr->next;
367       curr->next = prev;
368       prev = curr;
369       curr = next;
370     }
371   val->next = (void *) NULL;
372   return prev;
373 }
374 
375 /*------------------------------------------------------------------*/
376 /* copyDesignation - copy designation list                          */
377 /*------------------------------------------------------------------*/
378 designation *
copyDesignation(designation * src)379 copyDesignation (designation * src)
380 {
381   designation *dest = NULL;
382 
383   if (!src)
384     return NULL;
385 
386   switch (src->type)
387     {
388     case DESIGNATOR_STRUCT:
389       dest = newDesignation (DESIGNATOR_STRUCT, copySymbol (src->designator.tag));
390       break;
391     case DESIGNATOR_ARRAY:
392       dest = newDesignation (DESIGNATOR_ARRAY, &(src->designator.elemno) );
393       break;
394     }
395 
396   dest->lineno = src->lineno;
397   dest->filename = src->filename;
398 
399   if (src->next)
400     dest->next = copyDesignation (src->next);
401 
402   return dest;
403 }
404 
405 /*------------------------------------------------------------------*/
406 /* moveNestedInit - rewrites an initList node with a nested         */
407 /*                  designator to remove one level of nesting.      */
408 /*------------------------------------------------------------------*/
409 static
moveNestedInit(initList * deepParent,initList * src)410 void moveNestedInit(initList *deepParent, initList *src)
411 {
412   initList *dst = NULL, **eol;
413 
414   /** Create new initList element */
415   switch (src->type)
416     {
417     case INIT_NODE:
418       dst = newiList(INIT_NODE, src->init.node);
419       break;
420     case INIT_DEEP:
421       dst = newiList(INIT_DEEP, src->init.deep);
422       break;
423     }
424   dst->filename = src->filename;
425   dst->lineno = src->lineno;
426   dst->designation = src->designation->next;
427 
428   /* add dst to end of deepParent */
429   if (deepParent->type != INIT_DEEP)
430     {
431       werrorfl (deepParent->filename, deepParent->lineno,
432                 E_INIT_STRUCT, "<unknown>");
433       return;
434     }
435   for (eol = &(deepParent->init.deep); *eol ; )
436     eol = &((*eol)->next);
437   *eol = dst;
438 }
439 
440 /*-----------------------------------------------------------------*/
441 /* findStructField - find a specific field in a struct definition  */
442 /*-----------------------------------------------------------------*/
443 static int
findStructField(symbol * fields,symbol * target)444 findStructField (symbol *fields, symbol *target)
445 {
446   int i;
447 
448   for (i=0 ; fields; fields = fields->next)
449     {
450       /* skip past unnamed bitfields */
451       if (IS_BITFIELD (fields->type) && SPEC_BUNNAMED (fields->etype))
452         continue;
453       /* is this it? */
454       if (strcmp(fields->name, target->name) == 0)
455         return i;
456       i++;
457     }
458 
459   /* not found */
460   werrorfl (target->fileDef, target->lineDef, E_NOT_MEMBER, target->name);
461   return 0;
462 }
463 
464 /*------------------------------------------------------------------*/
465 /* reorderIlist - expands an initializer list to match designated   */
466 /*                initializers.                                     */
467 /*------------------------------------------------------------------*/
reorderIlist(sym_link * type,initList * ilist)468 initList *reorderIlist (sym_link * type, initList * ilist)
469 {
470   initList *iloop, *nlist, **nlistArray;
471   symbol *sflds;
472   int size=0, idx;
473 
474   if (!IS_AGGREGATE (type))
475     /* uninteresting: no designated initializers */
476     return ilist;
477 
478   if (ilist && ilist->type == INIT_HOLE)
479     /* ditto; just a uninitialized hole */
480     return ilist;
481 
482   /* special case: check for string initializer */
483   if (IS_ARRAY (type) && IS_CHAR (type->next) &&
484       ilist && ilist->type == INIT_NODE)
485     {
486       ast *iast = ilist->init.node;
487       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
488       if (v && IS_ARRAY (v->type) && IS_CHAR (v->etype))
489         {
490           /* yep, it's a string; no changes needed here. */
491           return ilist;
492         }
493     }
494 
495   if (ilist && ilist->type != INIT_DEEP)
496     {
497       werrorfl (ilist->filename, ilist->lineno, E_INIT_STRUCT, "<unknown>");
498       return NULL;
499     }
500 
501   /* okay, allocate enough space */
502   if (IS_ARRAY (type))
503     size = getNelements(type, ilist);
504   else if (IS_STRUCT (type))
505     {
506       /* compute size from struct type. */
507       size = 0;
508       for (sflds = SPEC_STRUCT (type)->fields; sflds; sflds = sflds->next)
509         {
510           /* skip past unnamed bitfields */
511           if (IS_BITFIELD (sflds->type) && SPEC_BUNNAMED (sflds->etype))
512             continue;
513           size++;
514         }
515     }
516   nlistArray = Safe_calloc ( size, sizeof(initList *) );
517 
518   /* pull together all the initializers into an ordered list */
519   iloop = ilist ? ilist->init.deep : NULL;
520   for (idx = 0 ; iloop ; iloop = iloop->next, idx++)
521     {
522       if (iloop->designation)
523         {
524           assert (iloop->type != INIT_HOLE);
525 
526           if (IS_ARRAY (type))
527             {
528               if (iloop->designation->type == DESIGNATOR_ARRAY)
529                 idx = iloop->designation->designator.elemno;
530               else
531                 werrorfl (iloop->filename, iloop->lineno, E_BAD_DESIGNATOR);
532             }
533           else if (IS_STRUCT (type))
534             {
535               if (iloop->designation->type == DESIGNATOR_STRUCT)
536                 idx = findStructField (SPEC_STRUCT (type)->fields,
537                                        iloop->designation->designator.tag);
538               else
539                 werrorfl (iloop->filename, iloop->lineno, E_BAD_DESIGNATOR);
540             }
541           else
542             {
543               assert (0);
544             }
545 
546           if (iloop->designation->next)
547             {
548               if (idx >= size)
549                 continue;
550               if (nlistArray[idx] == NULL)
551                 nlistArray[idx] = newiList(INIT_DEEP, NULL);
552               moveNestedInit(nlistArray[idx], iloop);
553               continue;
554             }
555         }
556 
557       /* overwrite any existing entry with iloop */
558       if (iloop->type != INIT_HOLE)
559         {
560           if (idx >= size)
561             continue;
562           if (nlistArray[idx] != NULL)
563             werrorfl (iloop->filename, iloop->lineno, W_DUPLICATE_INIT, idx);
564           nlistArray[idx] = iloop;
565         }
566     }
567 
568   /* create new list from nlistArray/size */
569   nlist = NULL;
570   sflds = IS_STRUCT (type) ? SPEC_STRUCT (type)->fields : NULL;
571   for ( idx=0; idx < size; idx++ )
572     {
573       initList *src = nlistArray[idx], *dst = NULL;
574       if (!src || src->type==INIT_HOLE)
575         {
576           dst = newiList(INIT_HOLE, NULL);
577           dst->filename = ilist->filename;
578           dst->lineno = ilist->lineno;
579         }
580       else
581         {
582           switch (src->type)
583             {
584             case INIT_NODE:
585               dst = newiList(INIT_NODE, src->init.node);
586               break;
587             case INIT_DEEP:
588               dst = newiList(INIT_DEEP, src->init.deep);
589               break;
590             }
591           dst->filename = src->filename;
592           dst->lineno = src->lineno;
593         }
594       dst->next = nlist;
595       nlist = dst;
596       /* advance to next field which is not an unnamed bitfield */
597       do
598         {
599           sflds = sflds ? sflds->next : NULL;
600         }
601       while (sflds &&
602              IS_BITFIELD (sflds->type) && SPEC_BUNNAMED (sflds->etype));
603     }
604 
605   nlist = newiList(INIT_DEEP, revinit (nlist));
606   nlist->filename = ilist->filename;
607   nlist->lineno = ilist->lineno;
608   nlist->designation = ilist->designation;
609   nlist->next = ilist->next;
610   return nlist;
611 }
612 
613 /*------------------------------------------------------------------*/
614 /* symbolVal - creates a value for a symbol                         */
615 /*------------------------------------------------------------------*/
616 value *
symbolVal(symbol * sym)617 symbolVal (symbol * sym)
618 {
619   value *val;
620 
621   if (!sym)
622     return NULL;
623 
624   val = newValue ();
625   val->sym = sym;
626 
627   if (sym->type)
628     {
629       val->type = sym->type;
630       val->etype = getSpec (val->type);
631     }
632 
633   if (*sym->rname)
634     {
635       SNPRINTF (val->name, sizeof (val->name), "%s", sym->rname);
636     }
637   else
638     {
639       SNPRINTF (val->name, sizeof (val->name), "_%s", sym->name);
640     }
641 
642   return val;
643 }
644 
645 /*--------------------------------------------------------------------*/
646 /* cheapestVal - try to reduce 'signed int' to 'char'                 */
647 /*--------------------------------------------------------------------*/
648 static value *
cheapestVal(value * val)649 cheapestVal (value * val)
650 {
651   /* only int can be reduced */
652   if (!IS_INT (val->type))
653     return val;
654 
655   /* long must not be changed */
656   if (SPEC_LONG (val->type) || SPEC_LONGLONG (val->type))
657     return val;
658 
659   /* unsigned must not be changed */
660   if (SPEC_USIGN (val->type))
661     return val;
662 
663   /* the only possible reduction is from signed int to (un)signed char,
664      because it's automatically promoted back to signed int.
665 
666      a reduction from unsigned int to unsigned char is a bug,
667      because an _unsigned_ char is promoted to _signed_ int! */
668   if (SPEC_CVAL (val->type).v_int < -128 || SPEC_CVAL (val->type).v_int > 255)
669     {
670       /* not in the range of (un)signed char */
671       return val;
672     }
673 
674   SPEC_NOUN (val->type) = V_CHAR;
675 
676   /* 'unsigned char' promotes to 'signed int', so that we can
677      reduce it the other way */
678   if (SPEC_CVAL (val->type).v_int >= 0)
679     {
680       /* 'bool' promotes to 'signed int' too */
681       if (SPEC_CVAL (val->type).v_int <= 1)
682         {
683           /* Do not use V_BIT here because in some contexts it also */
684           /* implies a storage class. */
685           SPEC_NOUN (val->type) = V_BOOL;
686         }
687       else
688         {
689           /* Boolean types are intrinsically unsigned, so only */
690           /* set the USIGN flag for char types to avoid triggering */
691           /* type checking errors/warnings. */
692           SPEC_USIGN (val->type) = 1;
693         }
694     }
695 
696   return (val);
697 }
698 
699 /*-----------------------------------------------------------------*/
700 /* double2ul - double to unsigned long conversion                  */
701 /*-----------------------------------------------------------------*/
702 unsigned long
double2ul(double val)703 double2ul (double val)
704 {
705 /*
706  * See ISO/IEC 9899, chapter 6.3.1.4 Real floating and integer:
707  * If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
708  * This shows up on Mac OS X i386 platform which useus SSE unit instead of the x87 FPU for floating-point operations
709  */
710 /*
711  * on Mac OS X ppc (long) 2147483648.0 equals to 2147483647, so we explicitely convert it to 0x80000000
712  * on other known platforms (long) 2147483648.0 equals to -2147483648
713  */
714   return ((val) < 0) ? (((val) < -2147483647.0) ? 0x80000000UL : (unsigned long) -((long) -(val))) : (unsigned long) (val);
715 }
716 
717 /*--------------------------------------------------------------------*/
718 /* checkConstantRange - check if constant fits in numeric range of    */
719 /* var type in comparisons and assignments                            */
720 /*--------------------------------------------------------------------*/
721 CCR_RESULT
checkConstantRange(sym_link * var,sym_link * lit,int op,bool exchangeLeftRight)722 checkConstantRange (sym_link * var, sym_link * lit, int op, bool exchangeLeftRight)
723 {
724   sym_link *reType;
725   TYPE_TARGET_LONGLONG litVal;
726   TYPE_TARGET_ULONGLONG ulitVal;
727   TYPE_TARGET_ULONGLONG signExtMask;
728   TYPE_TARGET_ULONGLONG signMask;
729   bool litValUnsigned;
730   int varBits;
731 
732   litVal = ullFromLit (lit);
733   ulitVal = (TYPE_TARGET_ULONGLONG) litVal;
734   litValUnsigned = SPEC_USIGN (lit);
735   varBits = bitsForType (var);
736   signMask = 1ull << (varBits-1);
737   signExtMask = varBits >= sizeof(TYPE_TARGET_ULONGLONG)*8 ? 0 : ~((1ull << varBits)-1);
738 
739 #if 0
740   printf("   ulitVal     = 0x%016lx\n", ulitVal);
741   printf("   signExtMask = 0x%016lx\n", signExtMask);
742   printf("   signMask    = 0x%016lx\n",signMask);
743 #endif
744 
745   //return CCR_OK; /* EEP - debug for long long */
746   /* sanity checks */
747   if (IS_FLOAT (var) || IS_FIXED (var))
748     return CCR_OK;
749   if (varBits < 1)
750     return CCR_ALWAYS_FALSE;
751   if (varBits > 64)
752     return CCR_ALWAYS_TRUE;
753 
754   /* special: assignment */
755   if (op == '=')
756     {
757       if (IS_BOOLEAN (var))
758         return CCR_OK;
759 
760       if (1) // Though the else branch is dead, I still would like to keep it.
761       //if (getenv ("SDCC_VERY_PEDANTIC"))
762         {
763           if (SPEC_USIGN (var))
764             {
765               if ((!litValUnsigned && litVal < 0) || (litVal & signExtMask) != 0)
766                 return CCR_OVL;
767               return CCR_OK;
768             }
769           else
770             {
771               if (litValUnsigned)
772                 {
773                   if ((ulitVal & (signExtMask | signMask)) == 0)
774                     return CCR_OK;
775                 }
776               else
777                 {
778                   if ((litVal & (signExtMask | signMask)) == 0)
779                     return CCR_OK;
780                   if ((litVal & (signExtMask | signMask)) == (signExtMask | signMask))
781                     return CCR_OK;
782                 }
783               return CCR_OVL;
784             }
785         }
786       else
787         {
788           /* ignore signedness, e.g. allow everything
789              from -127...+255 for (unsigned) char */
790           if ((litVal & signExtMask) == 0)
791             return CCR_OK;
792           if ((litVal & (signExtMask | signMask)) == (signExtMask | signMask))
793             return CCR_OK;
794           return CCR_OVL;
795         }
796     }
797 
798   if (exchangeLeftRight)
799     switch (op)
800       {
801       case EQ_OP:
802         break;
803       case NE_OP:
804         break;
805       case '>':
806         op = '<';
807         break;
808       case GE_OP:
809         op = LE_OP;
810         break;
811       case '<':
812         op = '>';
813         break;
814       case LE_OP:
815         op = GE_OP;
816         break;
817       default:
818         return CCR_ALWAYS_FALSE;
819       }
820 
821   reType = computeType (var, lit, RESULT_TYPE_NONE, op);
822 
823   if (SPEC_USIGN (reType))
824     {
825       /* unsigned operation */
826       int reBits = bitsForType (reType);
827       TYPE_TARGET_ULONGLONG minValP, maxValP, minValM, maxValM;
828       TYPE_TARGET_ULONGLONG opBitsMask = reBits >= sizeof(opBitsMask)*8 ? ~0ull : ((1ull << reBits)-1);
829 
830       if (IS_BOOL (var))
831         {
832           minValP = 0;
833           maxValP = 1;
834           minValM = 0;
835           maxValM = 1;
836         }
837       else if (SPEC_USIGN (lit) && SPEC_USIGN (var))
838         {
839           /* both operands are unsigned, this is easy */
840           minValP = 0;
841           maxValP = ~signExtMask;
842           /* there's only range, just copy it to 2nd set */
843           minValM = minValP;
844           maxValM = maxValP;
845         }
846       else if (SPEC_USIGN (var))
847         {
848           /* lit is casted from signed to unsigned, e.g.:
849              unsigned u;
850              u == (char) -17
851              -> u == 0xffef'
852            */
853           minValP = 0;
854           maxValP = ~signExtMask;
855           /* there's only one range, just copy it to 2nd set */
856           minValM = minValP;
857           maxValM = maxValP;
858 
859           /* it's an unsigned operation */
860           ulitVal &= opBitsMask;
861         }
862       else                      /* SPEC_USIGN (lit) */
863         {
864           /* var is casted from signed to unsigned, e.g.:
865              signed char c;
866              c == (unsigned) -17
867              -> c == 0xffef'
868 
869              The possible values after casting var
870              split up in two, nonconsecutive ranges:
871 
872              minValP =      0;  positive range: 0...127
873              maxValP =   0x7f;
874              minValM = 0xff80;  negative range: -128...-1
875              maxValM = 0xffff;
876            */
877 
878           /* positive range */
879           minValP = 0;
880           maxValP = ~(signExtMask | signMask);
881 
882           /* negative range */
883           minValM = signExtMask | signMask;
884           maxValM = (TYPE_TARGET_ULONGLONG)~0ull;     /* -1 */
885           /* limit number of bits to size of return type */
886           minValM &= opBitsMask;
887           maxValM &= opBitsMask;
888         }
889 #if 0
890       printf("   reType      = ");
891       printTypeChain (reType, NULL);
892       printf("   ulitVal     = 0x%016lx\n", ulitVal);
893       printf("   opBitsMask  = 0x%016lx\n", opBitsMask);
894       printf("   maxValP     = 0x%016lx\n", maxValP);
895       printf("   minValP     = 0x%016lx\n", minValP);
896       printf("   maxValM     = 0x%016lx\n", maxValM);
897       printf("   minValM     = 0x%016lx\n", minValM);
898 #endif
899 
900       switch (op)
901         {
902         case EQ_OP:            /* var == lit */
903           if (ulitVal <= maxValP && ulitVal >= minValP)   /* 0 */
904             return CCR_OK;
905           if (ulitVal <= maxValM && ulitVal >= minValM)
906             return CCR_OK;
907           return CCR_ALWAYS_FALSE;
908         case NE_OP:            /* var != lit */
909           if (ulitVal <= maxValP && ulitVal >= minValP)   /* 0 */
910             return CCR_OK;
911           if (ulitVal <= maxValM && ulitVal >= minValM)
912             return CCR_OK;
913           return CCR_ALWAYS_TRUE;
914         case '>':              /* var >  lit */
915           if (ulitVal >= maxValM)
916             return CCR_ALWAYS_FALSE;
917           if (ulitVal < minValP) /* 0 */
918             return CCR_ALWAYS_TRUE;
919           return CCR_OK;
920         case GE_OP:            /* var >= lit */
921           if (ulitVal > maxValM)
922             return CCR_ALWAYS_FALSE;
923           if (ulitVal <= minValP)        /* 0 */
924             return CCR_ALWAYS_TRUE;
925           return CCR_OK;
926         case '<':              /* var <  lit */
927           if (ulitVal > maxValM)
928             return CCR_ALWAYS_TRUE;
929           if (ulitVal <= minValP)        /* 0 */
930             return CCR_ALWAYS_FALSE;
931           return CCR_OK;
932         case LE_OP:            /* var <= lit */
933           if (ulitVal >= maxValM)
934             return CCR_ALWAYS_TRUE;
935           if (ulitVal < minValP) /* 0 */
936             return CCR_ALWAYS_FALSE;
937           return CCR_OK;
938         default:
939           return CCR_ALWAYS_FALSE;
940         }
941     }
942   else
943     {
944       /* signed operation */
945       TYPE_TARGET_LONGLONG minVal, maxVal;
946 
947       if (IS_BOOL (var))
948         {
949           minVal = 0;
950           maxVal = 1;
951         }
952       else if (SPEC_USIGN (var))
953         {
954           /* unsigned var, but signed operation. This happens
955              when var is promoted to signed int.
956              Set actual min/max values of var. */
957           minVal = 0;
958           maxVal = ~signExtMask;
959         }
960       else
961         {
962           /* signed var */
963           minVal = signExtMask | signMask;
964           maxVal = ~(signExtMask | signMask);
965         }
966 
967       switch (op)
968         {
969         case EQ_OP:            /* var == lit */
970           if (litVal > maxVal || litVal < minVal)
971             return CCR_ALWAYS_FALSE;
972           return CCR_OK;
973         case NE_OP:            /* var != lit */
974           if (litVal > maxVal || litVal < minVal)
975             return CCR_ALWAYS_TRUE;
976           return CCR_OK;
977         case '>':              /* var >  lit */
978           if (litVal >= maxVal)
979             return CCR_ALWAYS_FALSE;
980           if (litVal < minVal)
981             return CCR_ALWAYS_TRUE;
982           return CCR_OK;
983         case GE_OP:            /* var >= lit */
984           if (litVal > maxVal)
985             return CCR_ALWAYS_FALSE;
986           if (litVal <= minVal)
987             return CCR_ALWAYS_TRUE;
988           return CCR_OK;
989         case '<':              /* var <  lit */
990           if (litVal > maxVal)
991             return CCR_ALWAYS_TRUE;
992           if (litVal <= minVal)
993             return CCR_ALWAYS_FALSE;
994           return CCR_OK;
995         case LE_OP:            /* var <= lit */
996           if (litVal >= maxVal)
997             return CCR_ALWAYS_TRUE;
998           if (litVal < minVal)
999             return CCR_ALWAYS_FALSE;
1000           return CCR_OK;
1001         default:
1002           return CCR_ALWAYS_FALSE;
1003         }
1004     }
1005 }
1006 
1007 #if 0
1008 CCR_RESULT
1009 checkConstantRange (sym_link * var, sym_link * lit, int op, bool exchangeLeftRight)
1010 {
1011   CCR_RESULT result;
1012 
1013   printf ("checkConstantRange:\n");
1014   printf ("  var: ");
1015   printTypeChain (var, NULL);
1016   printf ("  lit = 0x%lx: ",ullFromLit (lit));
1017   printTypeChain (lit, NULL);
1018   printf ("  op: '");
1019   switch (op)
1020     {
1021     case '<': printf ("<"); break;
1022     case '=': printf ("="); break;
1023     case '>': printf (">"); break;
1024     case LE_OP: printf ("<="); break;
1025     case GE_OP: printf (">="); break;
1026     case EQ_OP: printf ("=="); break;
1027     case NE_OP: printf ("!="); break;
1028     default: printf ("%d",op);
1029     }
1030   printf("'\n");
1031   result = checkConstantRange2 (var, lit, op, exchangeLeftRight);
1032   switch (result)
1033     {
1034       case CCR_ALWAYS_TRUE: printf ("  CCR_ALWAYS_TRUE\n"); break;
1035       case CCR_ALWAYS_FALSE: printf ("  CCR_ALWAYS_FALSE\n"); break;
1036       case CCR_OK: printf ("  CCR_OK\n"); break;
1037       case CCR_OVL: printf ("  CCR_OVL\n"); break;
1038       default: printf("  CCR_%d\n",result);
1039     }
1040   return result;
1041 }
1042 #endif
1043 
1044 
1045 /*-----------------------------------------------------------------*/
1046 /* valueFromLit - creates a value from a literal                   */
1047 /*-----------------------------------------------------------------*/
1048 value *
valueFromLit(double lit)1049 valueFromLit (double lit)
1050 {
1051   struct dbuf_s dbuf;
1052   value *ret;
1053 
1054   if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
1055     {
1056       dbuf_init (&dbuf, 128);
1057       dbuf_printf (&dbuf, "%d", (TYPE_TARGET_LONG) lit);
1058       ret = constVal (dbuf_c_str (&dbuf));
1059       dbuf_destroy (&dbuf);
1060       return ret;
1061     }
1062 
1063   dbuf_init (&dbuf, 128);
1064   dbuf_printf (&dbuf, "%f", lit);
1065   ret = constFloatVal (dbuf_c_str (&dbuf));
1066   dbuf_destroy (&dbuf);
1067   return ret;
1068 }
1069 
1070 /*-----------------------------------------------------------------*/
1071 /* constFloatVal - converts a FLOAT constant to value              */
1072 /*-----------------------------------------------------------------*/
1073 value *
constFloatVal(const char * s)1074 constFloatVal (const char *s)
1075 {
1076   value *val = newValue ();
1077   double sval;
1078   char *p;
1079 
1080   sval = strtod (s, &p);
1081   if (p == s)
1082     {
1083       werror (E_INVALID_FLOAT_CONST, s);
1084       return constCharVal (0);
1085     }
1086 
1087   val->type = val->etype = newLink (SPECIFIER);
1088   SPEC_NOUN (val->type) = V_FLOAT;
1089   SPEC_SCLS (val->type) = S_LITERAL;
1090   SPEC_CONST (val->type) = 1;
1091   SPEC_CVAL (val->type).v_float = sval;
1092 
1093   return val;
1094 }
1095 
1096 /*-----------------------------------------------------------------*/
1097 /* constFixed16x16Val - converts a FIXED16X16 constant to value    */
1098 /*-----------------------------------------------------------------*/
1099 value *
constFixed16x16Val(const char * s)1100 constFixed16x16Val (const char *s)
1101 {
1102   value *val = newValue ();
1103   double sval;
1104   char *p;
1105 
1106   sval = strtod (s, &p);
1107   if (p == s)
1108     {
1109       werror (E_INVALID_FLOAT_CONST, s);
1110       return constCharVal (0);
1111     }
1112 
1113   val->type = val->etype = newLink (SPECIFIER);
1114   SPEC_NOUN (val->type) = V_FLOAT;
1115   SPEC_SCLS (val->type) = S_LITERAL;
1116   SPEC_CONST (val->type) = 1;
1117   SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (sval);
1118 
1119   return val;
1120 }
1121 
1122 /*-----------------------------------------------------------------*/
1123 /* constVal - converts a constant into a cheap value type          */
1124 /*-----------------------------------------------------------------*/
1125 value *
constVal(const char * s)1126 constVal (const char *s)
1127 {
1128   value *val = constIntVal (s);
1129 
1130   wassert (SPEC_NOUN (val->type) == V_INT);
1131 
1132   if (SPEC_LONGLONG (val->type))
1133     ;
1134   else if (SPEC_LONG (val->type))
1135     ;
1136   else if (SPEC_USIGN (val->type))
1137     {
1138       unsigned int i = SPEC_CVAL (val->type).v_uint;
1139       if (i < 256)
1140         SPEC_NOUN (val->type) = V_CHAR;
1141     }
1142   else
1143     {
1144       int i = SPEC_CVAL (val->type).v_int;
1145       if (i >= 0 && i < 256)
1146         {
1147           SPEC_NOUN (val->type) = V_CHAR;
1148           SPEC_USIGN (val->type) = TRUE;
1149           SPEC_CVAL (val->type).v_uint = i;
1150         }
1151       else if (i >= -128 && i < 128)
1152         {
1153           SPEC_NOUN (val->type) = V_CHAR;
1154         }
1155     }
1156 
1157   return val;
1158 }
1159 
1160 /*-----------------------------------------------------------------*/
1161 /* constIntVal - converts an integer constant into correct type    */
1162 /* See ISO C11, section 6.4.4.1 for the rules.                     */
1163 /*-----------------------------------------------------------------*/
1164 value *
constIntVal(const char * s)1165 constIntVal (const char *s)
1166 {
1167   char *p, *p2;
1168   double dval;
1169   long long int llval;
1170   value *val = newValue ();
1171   bool decimal, u_suffix = FALSE, l_suffix = FALSE, ll_suffix = FALSE;
1172 
1173   val->type = val->etype = newLink (SPECIFIER);
1174   SPEC_SCLS (val->type) = S_LITERAL;
1175   SPEC_CONST (val->type) = 1;
1176   SPEC_USIGN (val->type) = 0;
1177 
1178   errno = 0;
1179 
1180   if (s[0] == '0')
1181     {
1182       if (s[1] == 'b' || s[1] == 'B')
1183         llval = strtoull (s + 2, &p, 2);
1184       else
1185         llval = strtoull (s, &p, 0);
1186       dval = (double)(unsigned long long int) llval;
1187       decimal = FALSE;
1188     }
1189   else
1190     {
1191       dval = strtod (s, &p);
1192       if (dval >= 0.0)
1193         llval = strtoull (s, &p, 0);
1194       else
1195         llval = strtoll (s, &p, 0);
1196       decimal = TRUE;
1197     }
1198 
1199   if (errno)
1200     {
1201       dval = 4294967295.0;
1202       werror (W_INVALID_INT_CONST, s, dval);
1203     }
1204 
1205   // Check suffixes
1206   if ((p2 = strchr (p, 'u')) || (p2 = strchr (p, 'U')))
1207     {
1208       u_suffix = TRUE;
1209       p2++;
1210       if (strchr (p2, 'u') || strchr (p2, 'U'))
1211         werror (E_INTEGERSUFFIX, p);
1212     }
1213 
1214   if ((p2 = strstr (p, "ll")) || (p2 = strstr (p, "LL")))
1215     {
1216       ll_suffix = TRUE;
1217       p2 += 2;
1218       if (strchr (p2, 'l') || strchr (p2, 'L'))
1219         werror (E_INTEGERSUFFIX, p);
1220     }
1221   else if ((p2 = strchr (p, 'l')) || (p2 = strchr (p, 'L')))
1222     {
1223       l_suffix = TRUE;
1224       p2++;
1225       if (strchr (p2, 'l') || strchr (p2, 'L'))
1226         werror (E_INTEGERSUFFIX, p);
1227     }
1228 
1229   SPEC_NOUN (val->type) = V_INT;
1230 
1231   if (u_suffix) // Choose first of unsigned int, unsigned long int, unsigned long long int that fits.
1232     {
1233       SPEC_USIGN (val->type) = 1;
1234       if (ll_suffix || dval > 0xffffffff)
1235         SPEC_LONGLONG (val->type) = 1;
1236       else if(l_suffix || dval > 0xffff)
1237         SPEC_LONG (val->type) = 1;
1238     }
1239   else
1240     {
1241       if (decimal) // Choose first of int, long int, long long int that fits.
1242         {
1243           if (ll_suffix || dval > 0x7fffffff || dval < -0x80000000ll)
1244             {
1245               if (!options.std_c99) // C90 exception: Use unsigned long
1246                 {
1247                   SPEC_USIGN (val->type) = 1;
1248                   SPEC_LONG (val->type) = 1;
1249                 }
1250               else
1251                 SPEC_LONGLONG (val->type) = 1;
1252             }
1253           else if(l_suffix || dval > 0x7fff || dval < -0x8000l)
1254             SPEC_LONG (val->type) = 1;
1255         }
1256       else // Choose first of int, unsigned int, long int, unsigned long int, long long int, unsigned long long int that fits.
1257        {
1258          if (dval > 0x7fffffffffffffff)
1259            {
1260              SPEC_USIGN (val->type) = 1;
1261              SPEC_LONGLONG (val->type) = 1;
1262            }
1263          else if (ll_suffix || dval > 0xffffffff || dval < -0x80000000ll)
1264            {
1265              SPEC_LONGLONG (val->type) = 1;
1266            }
1267          else if (dval > 0x7fffffff)
1268            {
1269              SPEC_USIGN (val->type) = 1;
1270              SPEC_LONG (val->type) = 1;
1271            }
1272          else if (l_suffix || dval > 0xffff || dval < -0x8000l)
1273            {
1274              SPEC_LONG (val->type) = 1;
1275            }
1276          else if (dval > 0x7fff)
1277            {
1278              SPEC_USIGN (val->type) = 1;
1279            }
1280        }
1281     }
1282 
1283   /* check for out of range */
1284   if (!SPEC_LONGLONG (val->type))
1285     {
1286       if (dval < -2147483648.0)
1287         {
1288           dval = -2147483648.0;
1289           werror (W_INVALID_INT_CONST, s, dval);
1290         }
1291       if (dval > 2147483648.0 && !SPEC_USIGN (val->type))
1292         {
1293           dval = 2147483647.0;
1294           werror (W_INVALID_INT_CONST, s, dval);
1295         }
1296       if (dval > 4294967295.0)
1297         {
1298           dval = 4294967295.0;
1299           werror (W_INVALID_INT_CONST, s, dval);
1300         }
1301     }
1302 
1303   if (SPEC_LONGLONG (val->type))
1304     {
1305       if (SPEC_USIGN (val->type))
1306         {
1307           SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) llval;
1308         }
1309       else
1310         {
1311           SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) llval;
1312         }
1313     }
1314   else if (SPEC_LONG (val->type))
1315     {
1316       if (SPEC_USIGN (val->type))
1317         {
1318           SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
1319         }
1320       else
1321         {
1322           SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
1323         }
1324     }
1325   else
1326     {
1327       if (SPEC_USIGN (val->type))
1328         {
1329           SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
1330         }
1331       else
1332         {
1333           SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
1334         }
1335     }
1336 
1337   return val;
1338 }
1339 
1340 /*-----------------------------------------------------------------*/
1341 /* constCharacterVal - converts a character constant to value      */
1342 /*-----------------------------------------------------------------*/
1343 value *
constCharacterVal(unsigned long v,char type)1344 constCharacterVal (unsigned long v, char type)
1345 {
1346   value *val = newValue ();     /* alloc space for value   */
1347 
1348   val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
1349   SPEC_SCLS (val->type) = S_LITERAL;
1350   SPEC_CONST (val->type) = 1;
1351 
1352   switch (type)
1353     {
1354     case 0: // character constant
1355       SPEC_NOUN (val->type) = V_INT;
1356       SPEC_USIGN (val->type) = 0;
1357       SPEC_CVAL (val->type).v_int = options.signed_char ? (signed char) v : (unsigned char) v;
1358       break;
1359     case 'L': // wide character constant
1360       if (!options.std_c95)
1361         werror (E_WCHAR_CONST_C95);
1362       SPEC_NOUN (val->type) = V_INT;
1363       SPEC_USIGN (val->type) = 1;
1364       SPEC_LONG (val->etype) = 1;
1365       SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) v;
1366       break;
1367     case 'u': // wide character constant
1368       if (!options.std_c11)
1369         werror (E_WCHAR_CONST_C11);
1370       SPEC_NOUN (val->type) = V_INT;
1371       SPEC_USIGN (val->type) = 1;
1372       SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) v;
1373       break;
1374     case 'U': // wide character constant
1375       if (!options.std_c11)
1376         werror (E_WCHAR_CONST_C11);
1377       SPEC_NOUN (val->type) = V_INT;
1378       SPEC_USIGN (val->type) = 1;
1379       SPEC_LONG (val->etype) = 1;
1380       SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) v;
1381       break;
1382     case '8':
1383       if (!options.std_c2x)
1384         werror (E_U8_CHAR_C2X);
1385       if (v >= 128)
1386         werror (E_U8_CHAR_INVALID);
1387       SPEC_NOUN (val->type) = V_CHAR;
1388       SPEC_USIGN (val->type) = 1;
1389       SPEC_CVAL (val->type).v_int = (unsigned char) v;
1390       break;
1391     default:
1392       wassert (0);
1393     }
1394 
1395   return val;
1396 }
1397 
1398 /*-----------------------------------------------------------------*/
1399 /* constCharVal - converts a character constant to value           */
1400 /*-----------------------------------------------------------------*/
1401 value *
constCharVal(unsigned char v)1402 constCharVal (unsigned char v)
1403 {
1404   return constCharacterVal (v, 0);
1405 }
1406 
1407 /*-----------------------------------------------------------------*/
1408 /* constBoolVal - converts a BOOL constant to value                */
1409 /*-----------------------------------------------------------------*/
1410 value *
constBoolVal(bool v)1411 constBoolVal (bool v)
1412 {
1413   value *val = newValue ();     /* alloc space for value   */
1414 
1415   val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
1416   SPEC_SCLS (val->type) = S_LITERAL;
1417   SPEC_CONST (val->type) = 1;
1418 
1419   SPEC_NOUN (val->type) = (bit) ? V_BIT : V_BOOL;
1420 
1421   SPEC_CVAL (val->type).v_uint = (unsigned int) v;
1422 
1423   return val;
1424 }
1425 
1426 // TODO: Move this function to SDCCutil?
utf_32_from_utf_8(size_t * utf_32_len,const char * utf_8,size_t utf_8_len)1427 static const TYPE_UDWORD *utf_32_from_utf_8 (size_t *utf_32_len, const char *utf_8, size_t utf_8_len)
1428 {
1429   size_t allocated = 0;
1430   TYPE_UDWORD *utf_32 = 0;
1431   unsigned char first_byte;
1432   TYPE_UDWORD codepoint;
1433   size_t seqlen;
1434 
1435   for (*utf_32_len = 0; utf_8_len; (*utf_32_len)++)
1436     {
1437       if (allocated == *utf_32_len)
1438         {
1439           utf_32 = realloc (utf_32, sizeof(TYPE_UDWORD) * (*utf_32_len + 16));
1440           wassert (utf_32);
1441           allocated = *utf_32_len + 16;
1442         }
1443 
1444       first_byte = *utf_8;
1445       seqlen = 1;
1446       if (first_byte & 0x80)
1447         {
1448           while (first_byte & (0x80 >> seqlen))
1449             seqlen++;
1450           first_byte &= (0xff >> (seqlen + 1));
1451         }
1452       wassert (seqlen <= 6); // seqlen 5 and 6 are deprecated in current unicode standard, but for now, allow them.
1453 
1454       codepoint = first_byte;
1455       utf_8++;
1456       utf_8_len--;
1457       seqlen--;
1458 
1459       for(; seqlen; seqlen--)
1460         {
1461           codepoint <<= 6;
1462           codepoint |= (*utf_8 & 0x3f);
1463           utf_8++;
1464           utf_8_len--;
1465         }
1466 
1467       utf_32[*utf_32_len] = codepoint;
1468     }
1469   return (utf_32);
1470 }
1471 
1472 // TODO: Move this function to SDCCutil?
utf_16_from_utf_32(size_t * utf_16_len,const TYPE_UDWORD * utf_32,size_t utf_32_len)1473 static const TYPE_UWORD *utf_16_from_utf_32 (size_t *utf_16_len, const TYPE_UDWORD *utf_32, size_t utf_32_len)
1474 {
1475   size_t allocated = 0;
1476   TYPE_UWORD *utf_16 = 0;
1477   TYPE_UDWORD codepoint;
1478 
1479   for (*utf_16_len = 0; utf_32_len; utf_32_len--, utf_32++)
1480     {
1481       if (allocated <= *utf_16_len + 2)
1482         {
1483           utf_16 = realloc (utf_16, sizeof(TYPE_UWORD) * (*utf_16_len + 16));
1484           wassert (utf_16);
1485           allocated = *utf_16_len + 16;
1486         }
1487 
1488       codepoint = *utf_32;
1489 
1490       if (codepoint < 0xd7ff || codepoint >= 0xe000 && codepoint <= 0xffff) // Code in basic multilingual plane.
1491         {
1492           utf_16[(*utf_16_len)++] = codepoint;
1493           continue;
1494         }
1495 
1496       // Code point in supplementary plane.
1497       wassert (codepoint >= 0x100000 && codepoint <= 0x10ffff);
1498       codepoint -= 0x100000;
1499 
1500       utf_16[(*utf_16_len)++] = ((codepoint >> 10) & 0x3ff) + 0xd800;
1501       utf_16[(*utf_16_len)++] = (codepoint & 0x3ff) + 0xdc00;
1502     }
1503 
1504   return (utf_16);
1505 }
1506 
1507 /*------------------------------------------------------------------*/
1508 /* strVal - converts a string constant to a value                   */
1509 /*------------------------------------------------------------------*/
1510 value *
strVal(const char * s)1511 strVal (const char *s)
1512 {
1513   value *val;
1514   const char *utf_8;
1515   size_t utf_8_size;
1516 
1517   val = newValue ();
1518 
1519   /* get a declarator */
1520   val->type = newLink (DECLARATOR);
1521   DCL_TYPE (val->type) = ARRAY;
1522   val->type->next = val->etype = newLink (SPECIFIER);
1523   SPEC_SCLS (val->etype) = S_LITERAL;
1524   SPEC_CONST (val->etype) = 1;
1525 
1526   // Convert input string (mixed UTF-8 and UTF-32) to UTF-8 first (handling all escape sequences, etc).
1527   utf_8 = copyStr (s[0] == '"' ? s : s + 1, &utf_8_size);
1528 
1529   if (s[0] == '"') // UTF-8 string literal (any prefix u8 or L in the source would already have been stripped by earlier stages)
1530     {
1531       SPEC_NOUN (val->etype) = V_CHAR;
1532       SPEC_USIGN (val->etype) = !options.signed_char;
1533       val->etype->select.s.b_implicit_sign = true;
1534       SPEC_CVAL (val->etype).v_char = utf_8;
1535       DCL_ELEM (val->type) = utf_8_size;
1536     }
1537   else
1538     {
1539       size_t utf_32_size;
1540       // Convert to UTF-32 next, since converting UTF-32 to UTF-16 is easier than UTF-8 to UTF-16.
1541       const TYPE_UDWORD *utf_32 = utf_32_from_utf_8 (&utf_32_size, utf_8, utf_8_size);
1542 
1543       dbuf_free (utf_8);
1544 
1545       if (s[0] == 'U' || s[0] == 'L') // UTF-32 string literal
1546         {
1547           SPEC_NOUN (val->etype) = V_INT;
1548           SPEC_USIGN (val->etype) = 1;
1549           SPEC_LONG (val->etype) = 1;
1550           SPEC_CVAL (val->etype).v_char32 = utf_32;
1551           DCL_ELEM (val->type) = utf_32_size;
1552         }
1553       else if (s[0] == 'u') // UTF-16 string literal
1554         {
1555           size_t utf_16_size;
1556           const TYPE_UWORD *utf_16 = utf_16_from_utf_32 (&utf_16_size, utf_32, utf_32_size);
1557 
1558           SPEC_NOUN (val->etype) = V_INT;
1559           SPEC_USIGN (val->etype) = 1;
1560           SPEC_CVAL (val->etype).v_char16 = utf_16;
1561           DCL_ELEM (val->type) = utf_16_size;
1562         }
1563       else
1564         wassert (0);
1565     }
1566 
1567   return (val);
1568 }
1569 
1570 /*------------------------------------------------------------------*/
1571 /* rawStrVal - converts a string to a value                         */
1572 /*------------------------------------------------------------------*/
1573 value *
rawStrVal(const char * s,size_t size)1574 rawStrVal (const char *s, size_t size)
1575 {
1576   struct dbuf_s dbuf;
1577   value *val = newValue ();
1578 
1579   dbuf_init (&dbuf, size);
1580   wassert (dbuf_append (&dbuf, s, size));
1581 
1582   /* get a declarator */
1583   val->type = newLink (DECLARATOR);
1584   DCL_TYPE (val->type) = ARRAY;
1585   val->type->next = val->etype = newLink (SPECIFIER);
1586   SPEC_SCLS (val->etype) = S_LITERAL;
1587   SPEC_CONST (val->etype) = 1;
1588 
1589   SPEC_NOUN (val->etype) = V_CHAR;
1590   SPEC_USIGN (val->etype) = !options.signed_char;
1591   val->etype->select.s.b_implicit_sign = true;
1592   SPEC_CVAL (val->etype).v_char = dbuf_detach (&dbuf);
1593   DCL_ELEM (val->type) = size;
1594 
1595   return (val);
1596 }
1597 
1598 /*------------------------------------------------------------------*/
1599 /* reverseValWithType - reverses value chain with type & etype      */
1600 /*------------------------------------------------------------------*/
1601 value *
reverseValWithType(value * val)1602 reverseValWithType (value * val)
1603 {
1604   sym_link *type;
1605   sym_link *etype;
1606 
1607   if (!val)
1608     return NULL;
1609 
1610   /* save the type * etype chains */
1611   type = val->type;
1612   etype = val->etype;
1613 
1614   /* set the current one 2b null */
1615   val->type = val->etype = NULL;
1616   val = reverseVal (val);
1617 
1618   /* restore type & etype */
1619   val->type = type;
1620   val->etype = etype;
1621 
1622   return val;
1623 }
1624 
1625 /*------------------------------------------------------------------*/
1626 /* reverseVal - reverses the values for a value chain               */
1627 /*------------------------------------------------------------------*/
1628 value *
reverseVal(value * val)1629 reverseVal (value * val)
1630 {
1631   value *prev, *curr, *next;
1632 
1633   if (!val)
1634     return NULL;
1635 
1636   prev = val;
1637   curr = val->next;
1638 
1639   while (curr)
1640     {
1641       next = curr->next;
1642       curr->next = prev;
1643       prev = curr;
1644       curr = next;
1645     }
1646   val->next = (void *) NULL;
1647   return prev;
1648 }
1649 
1650 /*------------------------------------------------------------------*/
1651 /* copyValueChain - will copy a chain of values                     */
1652 /*------------------------------------------------------------------*/
1653 value *
copyValueChain(value * src)1654 copyValueChain (value * src)
1655 {
1656   value *dest;
1657 
1658   if (!src)
1659     return NULL;
1660 
1661   dest = copyValue (src);
1662   dest->next = copyValueChain (src->next);
1663 
1664   return dest;
1665 }
1666 
1667 /*------------------------------------------------------------------*/
1668 /* copyValue - copies contents of a value to a fresh one            */
1669 /*------------------------------------------------------------------*/
1670 value *
copyValue(value * src)1671 copyValue (value * src)
1672 {
1673   value *dest;
1674 
1675   dest = newValue ();
1676   dest->sym = copySymbol (src->sym);
1677   strncpyz (dest->name, src->name, SDCC_NAME_MAX);
1678   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
1679   dest->etype = (src->type ? getSpec (dest->type) : NULL);
1680 
1681   return dest;
1682 }
1683 
1684 /*------------------------------------------------------------------*/
1685 /* charVal - converts a character constant to a value               */
1686 /*------------------------------------------------------------------*/
1687 value *
charVal(const char * s)1688 charVal (const char *s)
1689 {
1690   char type;
1691 
1692   if ((s[0] == 'L' || s[0] == 'u' || s[0] == 'U') && s[1] == '\'')
1693     type = *s++;
1694   else if (s[0] == 'u' && s[1] == '8' && s[2] == '\'')
1695     {
1696       if (s[4] != '\'')
1697         werror (E_U8_CHAR_INVALID);
1698       type = '8';
1699       s += 2;
1700     }
1701   else
1702     type = 0;
1703 
1704   s++; // Get rid of quotation.
1705 
1706   /* if \ then special processing */
1707   if (*s == '\\')
1708     {
1709       switch (*++s)             /* go beyond the backslash  */
1710         {
1711         case 'n':
1712           return constCharacterVal ('\n', type);
1713         case 't':
1714           return constCharacterVal ('\t', type);
1715         case 'v':
1716           return constCharacterVal ('\v', type);
1717         case 'b':
1718           return constCharacterVal ('\b', type);
1719         case 'r':
1720           return constCharacterVal ('\r', type);
1721         case 'f':
1722           return constCharacterVal ('\f', type);
1723         case 'a':
1724           return constCharacterVal ('\a', type);
1725         case '\\':
1726           return constCharacterVal ('\\', type);
1727         case '\?':
1728           return constCharacterVal ('\?', type);
1729         case '\'':
1730           return constCharacterVal ('\'', type);
1731         case '\"':
1732           return constCharacterVal ('\"', type);
1733 
1734         case '0':
1735         case '1':
1736         case '2':
1737         case '3':
1738         case '4':
1739         case '5':
1740         case '6':
1741         case '7':
1742           return constCharacterVal (octalEscape (&s), type);
1743 
1744         case 'x':
1745           return constCharacterVal (hexEscape (&s), type);
1746 
1747         case 'u':
1748           return constCharacterVal (universalEscape (&s, 4), type);
1749 
1750         case 'U':
1751           return constCharacterVal (universalEscape (&s, 8), type);
1752 
1753         default:
1754           return constCharacterVal (*s, type);
1755         }
1756     }
1757   else if (type) // Wide character constant
1758     {
1759       size_t ulen;
1760       const TYPE_UDWORD *ustr = utf_32_from_utf_8 (&ulen, s, strlen(s) - 1);
1761       value *val = constCharacterVal (*ustr, type);
1762       free ((void *)ustr);
1763       return (val);
1764     }
1765   else // Character constant that is not wide - compability with legacy encodings.
1766     return constCharacterVal (*s, 0);
1767 }
1768 
1769 /*------------------------------------------------------------------*/
1770 /* valFromType - creates a value from type given                    */
1771 /*------------------------------------------------------------------*/
1772 value *
valFromType(sym_link * type)1773 valFromType (sym_link * type)
1774 {
1775   value *val = newValue ();
1776   val->type = copyLinkChain (type);
1777   val->etype = getSpec (val->type);
1778   return val;
1779 }
1780 
1781 /*------------------------------------------------------------------*/
1782 /* floatFromVal - value to double float conversion                  */
1783 /*------------------------------------------------------------------*/
1784 double
floatFromVal(value * val)1785 floatFromVal (value * val)
1786 {
1787   if (!val)
1788     return 0;
1789 
1790   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1791     {
1792       werror (E_CONST_EXPECTED, val->name);
1793       return 0;
1794     }
1795 
1796   /* if it is not a specifier then we can assume that */
1797   /* it will be an unsigned long                      */
1798   if (!IS_SPEC (val->type))
1799     return SPEC_CVAL (val->etype).v_ulong;
1800 
1801   if (SPEC_NOUN (val->etype) == V_FLOAT)
1802     return SPEC_CVAL (val->etype).v_float;
1803 
1804   if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1805     return doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16);
1806 
1807   if (SPEC_LONGLONG (val->etype))
1808     {
1809       if (SPEC_USIGN (val->etype))
1810         return (double)SPEC_CVAL (val->etype).v_ulonglong;
1811       else
1812         return (double)SPEC_CVAL (val->etype).v_longlong;
1813     }
1814 
1815   if (SPEC_LONG (val->etype))
1816     {
1817       if (SPEC_USIGN (val->etype))
1818         return SPEC_CVAL (val->etype).v_ulong;
1819       else
1820         return SPEC_CVAL (val->etype).v_long;
1821     }
1822 
1823   if (SPEC_NOUN (val->etype) == V_INT)
1824     {
1825       if (SPEC_USIGN (val->etype))
1826         return SPEC_CVAL (val->etype).v_uint;
1827       else
1828         return SPEC_CVAL (val->etype).v_int;
1829     }
1830 
1831   if (SPEC_NOUN (val->etype) == V_CHAR)
1832     {
1833       if (SPEC_USIGN (val->etype))
1834         return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1835       else
1836         return (signed char) SPEC_CVAL (val->etype).v_int;
1837     }
1838 
1839   if (IS_BOOL (val->etype) || IS_BITVAR (val->etype))
1840     return SPEC_CVAL (val->etype).v_uint;
1841 
1842   if (SPEC_NOUN (val->etype) == V_VOID)
1843     return SPEC_CVAL (val->etype).v_ulong;
1844 
1845   if (SPEC_NOUN (val->etype) == V_STRUCT)
1846     return SPEC_CVAL (val->etype).v_ulong;
1847 
1848   /* we are lost ! */
1849   werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1850   return 0;
1851 }
1852 
1853 /*------------------------------------------------------------------*/
1854 /* ulFromVal - value to unsigned long conversion                    */
1855 /*------------------------------------------------------------------*/
1856 unsigned long
ulFromVal(value * val)1857 ulFromVal (value *val)
1858 {
1859   if (!val)
1860     return 0;
1861 
1862   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1863     {
1864       werror (E_CONST_EXPECTED, val->name);
1865       return 0;
1866     }
1867 
1868   /* if it is not a specifier then we can assume that */
1869   /* it will be an unsigned long                      */
1870   if (!IS_SPEC (val->type))
1871     return SPEC_CVAL (val->etype).v_ulong;
1872 
1873   if (SPEC_NOUN (val->etype) == V_FLOAT)
1874     return double2ul (SPEC_CVAL (val->etype).v_float);
1875 
1876   if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1877     return double2ul (doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16));
1878 
1879   if (SPEC_LONGLONG (val->etype))
1880     {
1881       if (SPEC_USIGN (val->etype))
1882         return (unsigned long)SPEC_CVAL (val->etype).v_ulonglong;
1883       else
1884         return (unsigned long)SPEC_CVAL (val->etype).v_longlong;
1885     }
1886 
1887   if (SPEC_LONG (val->etype))
1888     {
1889       if (SPEC_USIGN (val->etype))
1890         return SPEC_CVAL (val->etype).v_ulong;
1891       else
1892         return SPEC_CVAL (val->etype).v_long;
1893     }
1894 
1895   if (SPEC_NOUN (val->etype) == V_INT)
1896     {
1897       if (SPEC_USIGN (val->etype))
1898         return SPEC_CVAL (val->etype).v_uint;
1899       else
1900         return SPEC_CVAL (val->etype).v_int;
1901     }
1902 
1903   if (SPEC_NOUN (val->etype) == V_CHAR)
1904     {
1905       if (SPEC_USIGN (val->etype))
1906         return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1907       else
1908         return (signed char) SPEC_CVAL (val->etype).v_int;
1909     }
1910 
1911   if (IS_BOOL (val->etype) || IS_BITVAR (val->etype))
1912     return SPEC_CVAL (val->etype).v_uint;
1913 
1914   if (SPEC_NOUN (val->etype) == V_VOID)
1915     return SPEC_CVAL (val->etype).v_ulong;
1916 
1917   if (SPEC_NOUN (val->etype) == V_STRUCT)
1918     return SPEC_CVAL (val->etype).v_ulong;
1919 
1920   /* we are lost ! */
1921   werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1922   return 0;
1923 }
1924 
1925 /*------------------------------------------------------------------*/
1926 /* byteOfVal - extract a byte of a value                            */
1927 /*             offset = 0 (LSB) ... n-1 (MSB)                       */
1928 /*             higher offsets of signed ints will be sign extended, */
1929 /*             other types will be extended with zero padding       */
1930 /*------------------------------------------------------------------*/
1931 unsigned char
byteOfVal(value * val,int offset)1932 byteOfVal (value * val, int offset)
1933 {
1934   unsigned char *p;
1935   int shift = 8*offset;
1936 
1937   wassert (offset >= 0);
1938 
1939   if (!val)
1940     return 0;
1941 
1942   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1943     {
1944       werror (E_CONST_EXPECTED, val->name);
1945       return 0;
1946     }
1947 
1948   /* if it is not a specifier then we can assume that */
1949   /* it will be an unsigned long                      */
1950   /* 2012-Apr-30 EEP - Why is this true?              */
1951   if (!IS_SPEC (val->type))
1952     return offset < 4 ? (SPEC_CVAL (val->etype).v_ulong >> shift) & 0xff : 0;
1953 
1954   if (SPEC_NOUN (val->etype) == V_FLOAT)
1955     {
1956       float f = (float)SPEC_CVAL (val->etype).v_float;
1957 
1958       if (offset > 3)
1959         return 0;
1960       p = (unsigned char *)&f;
1961 #ifdef WORDS_BIGENDIAN
1962       p += 3 - offset;
1963 #else
1964       p += offset;
1965 #endif
1966       return *p;
1967     }
1968 
1969   if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1970     return offset < 4 ? (SPEC_CVAL (val->etype).v_fixed16x16 >> shift) & 0xff : 0;
1971 
1972   if (SPEC_LONGLONG (val->etype))
1973     {
1974       if (SPEC_USIGN (val->etype))
1975         return offset < 8 ? (SPEC_CVAL (val->etype).v_ulonglong >> shift) & 0xff : 0;
1976       else
1977         return offset < 8 ? (SPEC_CVAL (val->etype).v_longlong >> shift) & 0xff :
1978                (SPEC_CVAL (val->etype).v_longlong < 0 ? 0xff : 0);
1979     }
1980 
1981   if (SPEC_LONG (val->etype))
1982     {
1983       if (SPEC_USIGN (val->etype))
1984         return offset < 4 ? (SPEC_CVAL (val->etype).v_ulong >> shift) & 0xff : 0;
1985       else
1986         return offset < 4 ? (SPEC_CVAL (val->etype).v_long >> shift) & 0xff :
1987                (SPEC_CVAL (val->etype).v_long < 0 ? 0xff : 0);
1988     }
1989 
1990   if (SPEC_NOUN (val->etype) == V_INT)
1991     {
1992       if (SPEC_USIGN (val->etype))
1993         return offset < 2 ? (SPEC_CVAL (val->etype).v_uint >> shift) & 0xff : 0;
1994       else
1995         return offset < 2 ? (SPEC_CVAL (val->etype).v_int >> shift) & 0xff :
1996                (SPEC_CVAL (val->etype).v_int < 0 ? 0xff : 0);
1997     }
1998 
1999   if (SPEC_NOUN (val->etype) == V_CHAR)
2000     {
2001       if (SPEC_USIGN (val->etype))
2002         return offset < 1 ? SPEC_CVAL (val->etype).v_uint & 0xff : 0;
2003       else
2004         return offset < 1 ? SPEC_CVAL (val->etype).v_int & 0xff :
2005                (SPEC_CVAL (val->etype).v_int < 0 ? 0xff : 0);
2006     }
2007 
2008   if (IS_BOOL (val->etype) || IS_BITVAR (val->etype))
2009     return offset < 2 ? (SPEC_CVAL (val->etype).v_uint >> shift) & 0xff : 0;
2010 
2011   /* we are lost ! */
2012   werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "byteOfVal: unknown value");
2013   return 0;
2014 }
2015 
2016 /*------------------------------------------------------------------*/
2017 /* ullFromLit - literal to unsigned long long conversion            */
2018 /*------------------------------------------------------------------*/
2019 TYPE_TARGET_ULONGLONG
ullFromLit(sym_link * lit)2020 ullFromLit (sym_link * lit)
2021 {
2022   sym_link * etype = getSpec(lit);
2023 
2024   if (!lit)
2025     return 0;
2026 
2027   if (etype && SPEC_SCLS (etype) != S_LITERAL)
2028     {
2029       werror (E_CONST_EXPECTED, "");
2030       return 0;
2031     }
2032 
2033   /* if it is not a specifier then we can assume that */
2034   /* it will be an unsigned long                      */
2035   if (!IS_SPEC (lit))
2036     return SPEC_CVAL (etype).v_ulong;
2037 
2038   if (SPEC_NOUN (etype) == V_FLOAT)
2039     return double2ul (SPEC_CVAL (etype).v_float); /* FIXME: this loses bits */
2040 
2041   if (SPEC_NOUN (etype) == V_FIXED16X16)
2042     return double2ul (doubleFromFixed16x16 (SPEC_CVAL (etype).v_fixed16x16)); /* FIXME: this loses bits */
2043 
2044   if (SPEC_LONGLONG (etype))
2045     {
2046       if (SPEC_USIGN (etype))
2047         return SPEC_CVAL (etype).v_ulonglong;
2048       else
2049         return SPEC_CVAL (etype).v_longlong;
2050     }
2051 
2052   if (SPEC_LONG (etype))
2053     {
2054       if (SPEC_USIGN (etype))
2055         return SPEC_CVAL (etype).v_ulong;
2056       else
2057         return SPEC_CVAL (etype).v_long;
2058     }
2059 
2060   if (SPEC_NOUN (etype) == V_INT)
2061     {
2062       if (SPEC_USIGN (etype))
2063         return SPEC_CVAL (etype).v_uint;
2064       else
2065         return SPEC_CVAL (etype).v_int;
2066     }
2067 
2068   if (SPEC_NOUN (etype) == V_CHAR)
2069     {
2070       if (SPEC_USIGN (etype))
2071         return (unsigned char) SPEC_CVAL (etype).v_uint;
2072       else
2073         return (signed char) SPEC_CVAL (etype).v_int;
2074     }
2075 
2076   if (IS_BOOL (etype) || IS_BITVAR (etype))
2077     return SPEC_CVAL (etype).v_uint;
2078 
2079   if (SPEC_NOUN (etype) == V_VOID)
2080     return SPEC_CVAL (etype).v_ulong;
2081 
2082   if (SPEC_NOUN (etype) == V_STRUCT)  /* ??? Why ??? EEP - 23 Nov 2012 */
2083     return SPEC_CVAL (etype).v_ulong;
2084 
2085   /* we are lost ! */
2086   werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ullFromLit: unknown value");
2087   return 0;
2088 }
2089 
2090 /*------------------------------------------------------------------*/
2091 /* ullFromVal - value to unsigned long long conversion              */
2092 /*------------------------------------------------------------------*/
2093 unsigned long long
ullFromVal(value * val)2094 ullFromVal (value * val)
2095 {
2096   if (!val)
2097     return 0;
2098 
2099   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
2100     {
2101       werror (E_CONST_EXPECTED, val->name);
2102       return 0;
2103     }
2104   return (unsigned long long) ullFromLit (val->type);
2105 }
2106 
2107 /*------------------------------------------------------------------*/
2108 /* csdOfVal - return 0 if the value can be represented as csd       */
2109 /* topbit  - highest nonzero bit in csd                             */
2110 /* nonzero - number of nonzero bits in csd                          */
2111 /* csd_add - positive bits in csd                                   */
2112 /* csd_sub - negative bits in csd                                   */
2113 /*------------------------------------------------------------------*/
csdOfVal(int * topbit,int * nonzero,unsigned long long * csd_add,unsigned long long * csd_sub,value * val)2114 int csdOfVal (int *topbit, int *nonzero, unsigned long long *csd_add, unsigned long long *csd_sub, value *val)
2115 {
2116   unsigned long long binary = ullFromVal (val);
2117   bool gamma, theta, a;
2118   int bit, next;
2119 
2120   *topbit = 0;
2121   *nonzero = 0;
2122   *csd_add = 0;
2123   *csd_sub = 0;
2124 
2125   for (a = 0, gamma = 0, bit = 0; bit < 61; bit++)
2126     {
2127        theta = a ^ (binary & 1);
2128        gamma = !gamma && theta;
2129        next = (1 - 2 * (bool)(binary & 2)) * gamma;
2130        if (next > 0)
2131          *csd_add |= (1ull << bit);
2132        else if (next < 0)
2133          *csd_sub |= (1ull << bit);
2134        if (next)
2135          {
2136            (*nonzero)++;
2137            *topbit = bit;
2138          }
2139        a = (binary & 1);
2140        binary >>= 1;
2141     }
2142   return((bool)binary);
2143 }
2144 
2145 /*------------------------------------------------------------------*/
2146 /* isEqualVal - return 1 if value is equal to specified constant    */
2147 /*------------------------------------------------------------------*/
2148 int
isEqualVal(value * val,int k)2149 isEqualVal (value * val, int k)
2150 {
2151   if (IS_SPEC (val->type))
2152     {
2153       if (SPEC_NOUN (val->type) == V_FLOAT || SPEC_NOUN (val->type) == V_FIXED16X16)
2154         return floatFromVal (val) == k;
2155     }
2156   return ((TYPE_TARGET_LONGLONG) ullFromVal (val)) == k;
2157 }
2158 
2159 
2160 /*-----------------------------------------------------------------*/
2161 /* doubleFromFixed16x16 - convert a fixed16x16 to double           */
2162 /*-----------------------------------------------------------------*/
2163 double
doubleFromFixed16x16(TYPE_TARGET_ULONG value)2164 doubleFromFixed16x16 (TYPE_TARGET_ULONG value)
2165 {
2166 #if 0
2167   /* This version is incorrect negative values. */
2168   double tmp = 0, exp = 2;
2169 
2170   tmp = (value & 0xffff0000) >> 16;
2171 
2172   while (value)
2173     {
2174       value &= 0xffff;
2175       if (value & 0x8000)
2176         tmp += 1 / exp;
2177       exp *= 2;
2178       value <<= 1;
2179     }
2180 
2181   return (tmp);
2182 #else
2183   return ((double) (value * 1.0) / (double) (1UL << 16));
2184 #endif
2185 }
2186 
2187 TYPE_TARGET_ULONG
fixed16x16FromDouble(double value)2188 fixed16x16FromDouble (double value)
2189 {
2190 #if 0
2191   /* This version is incorrect negative values. */
2192   unsigned int tmp = 0, pos = 16;
2193   TYPE_TARGET_ULONG res;
2194 
2195   tmp = floor (value);
2196   res = tmp << 16;
2197   value -= tmp;
2198 
2199   tmp = 0;
2200   while (pos--)
2201     {
2202       value *= 2;
2203       if (value >= 1.0)
2204         tmp |= (1 << pos);
2205       value -= floor (value);
2206     }
2207 
2208   res |= tmp;
2209 
2210   return (res);
2211 #else
2212   return double2ul (value * (double) (1UL << 16));
2213 #endif
2214 }
2215 
2216 /*------------------------------------------------------------------*/
2217 /* valUnaryPM - does the unary +/- operation on a constant          */
2218 /*------------------------------------------------------------------*/
2219 value *
valUnaryPM(value * val)2220 valUnaryPM (value * val)
2221 {
2222   /* depending on type */
2223   if (SPEC_NOUN (val->etype) == V_FLOAT)
2224     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
2225   else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
2226     SPEC_CVAL (val->etype).v_fixed16x16 = (TYPE_TARGET_ULONG) - ((long) SPEC_CVAL (val->etype).v_fixed16x16);
2227   else if (SPEC_LONGLONG (val->etype))
2228     {
2229       if (SPEC_USIGN (val->etype))
2230         SPEC_CVAL (val->etype).v_ulonglong = 0 - SPEC_CVAL (val->etype).v_ulonglong;
2231       else
2232         SPEC_CVAL (val->etype).v_longlong = -SPEC_CVAL (val->etype).v_longlong;
2233     }
2234   else if (SPEC_LONG (val->etype))
2235     {
2236       if (SPEC_USIGN (val->etype))
2237         SPEC_CVAL (val->etype).v_ulong = 0 - SPEC_CVAL (val->etype).v_ulong;
2238       else
2239         SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
2240     }
2241   else
2242     {
2243       if (SPEC_USIGN (val->etype))
2244         SPEC_CVAL (val->etype).v_uint = 0 - SPEC_CVAL (val->etype).v_uint;
2245       else
2246         SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
2247 
2248       if (SPEC_NOUN (val->etype) == V_CHAR)
2249         {
2250           /* promote to 'signed int', cheapestVal() might reduce it again */
2251           SPEC_USIGN (val->etype) = 0;
2252           SPEC_NOUN (val->etype) = V_INT;
2253         }
2254       return cheapestVal (val);
2255     }
2256   return val;
2257 }
2258 
2259 /*------------------------------------------------------------------*/
2260 /* valueComplement - complements a constant                         */
2261 /*------------------------------------------------------------------*/
2262 value *
valComplement(value * val)2263 valComplement (value * val)
2264 {
2265   /* depending on type */
2266   if (SPEC_LONGLONG (val->etype))
2267     {
2268       if (SPEC_USIGN (val->etype))
2269         SPEC_CVAL (val->etype).v_ulonglong = ~SPEC_CVAL (val->etype).v_ulonglong;
2270       else
2271         SPEC_CVAL (val->etype).v_longlong = ~SPEC_CVAL (val->etype).v_longlong;
2272     }
2273   else if (SPEC_LONG (val->etype))
2274     {
2275       if (SPEC_USIGN (val->etype))
2276         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
2277       else
2278         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
2279     }
2280   else
2281     {
2282       if (SPEC_USIGN (val->etype))
2283         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
2284       else
2285         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
2286 
2287       if (SPEC_NOUN (val->etype) == V_CHAR)
2288         {
2289           /* promote to 'signed int', cheapestVal() might reduce it again */
2290           SPEC_USIGN (val->etype) = 0;
2291           SPEC_NOUN (val->etype) = V_INT;
2292         }
2293       return cheapestVal (val);
2294     }
2295   return val;
2296 }
2297 
2298 /*------------------------------------------------------------------*/
2299 /* valueNot - complements a constant                                */
2300 /*------------------------------------------------------------------*/
2301 value *
valNot(value * val)2302 valNot (value * val)
2303 {
2304   /* depending on type */
2305   if (SPEC_LONGLONG (val->etype))
2306     {
2307       if (SPEC_USIGN (val->etype))
2308         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulonglong;
2309       else
2310         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_longlong;
2311     }
2312   else if (SPEC_LONG (val->etype))
2313     {
2314       if (SPEC_USIGN (val->etype))
2315         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
2316       else
2317         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
2318     }
2319   else
2320     {
2321       if (SPEC_USIGN (val->etype))
2322         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
2323       else
2324         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
2325 
2326     }
2327   /* ANSI: result type is int, value is 0 or 1 */
2328   /* sdcc will hold this in an 'unsigned char' */
2329   SPEC_USIGN (val->etype) = 1;
2330   SPEC_LONG (val->etype) = 0;
2331   SPEC_LONGLONG (val->type) = 0;
2332   SPEC_NOUN (val->etype) = V_CHAR;
2333   return val;
2334 }
2335 
2336 /*------------------------------------------------------------------*/
2337 /* valMult - multiply constants                                     */
2338 /*------------------------------------------------------------------*/
2339 value *
valMult(value * lval,value * rval)2340 valMult (value * lval, value * rval)
2341 {
2342   value *val;
2343 
2344   /* create a new value */
2345   val = newValue ();
2346   val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '*');
2347   SPEC_SCLS (val->etype) = S_LITERAL;   /* will remain literal */
2348 
2349   if (IS_FLOAT (val->type))
2350     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
2351   else if (IS_FIXED16X16 (val->type))
2352     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) * floatFromVal (rval));
2353   /* signed and unsigned mul are the same, as long as the precision of the
2354      result isn't bigger than the precision of the operands. */
2355   else if (SPEC_LONGLONG (val->type))
2356     SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) * (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2357   else if (SPEC_LONG (val->type))
2358     SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) * (TYPE_TARGET_ULONG) ulFromVal (rval);
2359   else if (SPEC_USIGN (val->type))      /* unsigned int */
2360     {
2361       TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) * (TYPE_TARGET_UINT) ulFromVal (rval);
2362 
2363       SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
2364       if (ul != (TYPE_TARGET_UINT) ul)
2365         werror (W_INT_OVL);
2366     }
2367   else                          /* signed int */
2368     {
2369       TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) * (TYPE_TARGET_INT) floatFromVal (rval);
2370 
2371       SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
2372       if (l != (TYPE_TARGET_INT) l)
2373         werror (W_INT_OVL);
2374     }
2375   return cheapestVal (val);
2376 }
2377 
2378 /*------------------------------------------------------------------*/
2379 /* valDiv  - Divide   constants                                     */
2380 /*------------------------------------------------------------------*/
2381 value *
valDiv(value * lval,value * rval)2382 valDiv (value * lval, value * rval)
2383 {
2384   value *val;
2385 
2386   if (isEqualVal (rval, 0) && !IS_FLOAT (computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '/')))
2387     {
2388       werror (E_DIVIDE_BY_ZERO);
2389       return rval;
2390     }
2391 
2392   /* create a new value */
2393   val = newValue ();
2394   val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '/');
2395   SPEC_SCLS (val->etype) = S_LITERAL;   /* will remain literal */
2396 
2397   if (IS_FLOAT (val->type))
2398     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
2399   else if (IS_FIXED16X16 (val->type))
2400     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) / floatFromVal (rval));
2401   else if (SPEC_LONGLONG (val->type))
2402     {
2403       if (SPEC_USIGN (val->type))
2404         SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) / (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2405       else
2406         SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) / (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2407     }
2408   else if (SPEC_LONG (val->type))
2409     {
2410       if (SPEC_USIGN (val->type))
2411         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) / (TYPE_TARGET_ULONG) ulFromVal (rval);
2412       else
2413         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) / (TYPE_TARGET_LONG) ulFromVal (rval);
2414     }
2415   else
2416     {
2417       if (SPEC_USIGN (val->type))
2418         SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) / (TYPE_TARGET_UINT) ulFromVal (rval);
2419       else
2420         SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) / (TYPE_TARGET_INT) ulFromVal (rval);
2421     }
2422   return cheapestVal (val);
2423 }
2424 
2425 /*------------------------------------------------------------------*/
2426 /* valMod  - Modulus  constants                                     */
2427 /*------------------------------------------------------------------*/
2428 value *
valMod(value * lval,value * rval)2429 valMod (value * lval, value * rval)
2430 {
2431   value *val;
2432 
2433   if (isEqualVal (rval, 0))
2434     {
2435       werror (E_DIVIDE_BY_ZERO);
2436       return rval;
2437     }
2438 
2439   /* create a new value */
2440   val = newValue ();
2441   val->type = val->etype = computeType (lval->etype, rval->etype, RESULT_TYPE_INT, '%');
2442   SPEC_SCLS (val->etype) = S_LITERAL;   /* will remain literal */
2443 
2444   if (SPEC_LONGLONG (val->type))
2445     {
2446       if (SPEC_USIGN (val->type))
2447         SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) % (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2448       else
2449         SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) % (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2450     }
2451   else if (SPEC_LONG (val->type))
2452     {
2453       if (SPEC_USIGN (val->type))
2454         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) % (TYPE_TARGET_ULONG) ulFromVal (rval);
2455       else
2456         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) % (TYPE_TARGET_LONG) ulFromVal (rval);
2457     }
2458   else
2459     {
2460       if (SPEC_USIGN (val->type))
2461         SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) % (TYPE_TARGET_UINT) ulFromVal (rval);
2462       else
2463         SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) % (TYPE_TARGET_INT) ulFromVal (rval);
2464     }
2465   return cheapestVal (val);
2466 }
2467 
2468 /*------------------------------------------------------------------*/
2469 /* valPlus - Addition constants                                     */
2470 /*------------------------------------------------------------------*/
2471 value *
valPlus(value * lval,value * rval)2472 valPlus (value * lval, value * rval)
2473 {
2474   value *val;
2475 
2476   /* create a new value */
2477   val = newValue ();
2478   val->type = computeType (lval->type, rval->type, RESULT_TYPE_INT, '+');
2479   val->etype = getSpec (val->type);
2480   SPEC_SCLS (val->etype) = S_LITERAL;   /* will remain literal */
2481 
2482   if (!IS_SPEC (val->type))
2483     SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) + (TYPE_TARGET_ULONG) ulFromVal (rval);
2484   else if (IS_FLOAT (val->type))
2485     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
2486   else if (IS_FIXED16X16 (val->type))
2487     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) + floatFromVal (rval));
2488   else if (SPEC_LONGLONG (val->type))
2489     {
2490       if (SPEC_USIGN (val->type))
2491         SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) + (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2492       else
2493         SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) + (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2494     }
2495   else if (SPEC_LONG (val->type))
2496     {
2497       if (SPEC_USIGN (val->type))
2498         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) + (TYPE_TARGET_ULONG) ulFromVal (rval);
2499       else
2500         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) + (TYPE_TARGET_LONG) ulFromVal (rval);
2501     }
2502   else
2503     {
2504       if (SPEC_USIGN (val->type))
2505         SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) + (TYPE_TARGET_UINT) ulFromVal (rval);
2506       else
2507         SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) + (TYPE_TARGET_INT) ulFromVal (rval);
2508     }
2509   return cheapestVal (val);
2510 }
2511 
2512 /*------------------------------------------------------------------*/
2513 /* valMinus - Addition constants                                    */
2514 /*------------------------------------------------------------------*/
2515 value *
valMinus(value * lval,value * rval)2516 valMinus (value * lval, value * rval)
2517 {
2518   value *val;
2519 
2520   /* create a new value */
2521   val = newValue ();
2522   val->type = computeType (lval->type, rval->type, RESULT_TYPE_INT, '-');
2523   val->etype = getSpec (val->type);
2524   SPEC_SCLS (val->etype) = S_LITERAL;   /* will remain literal */
2525 
2526   if (!IS_SPEC (val->type))
2527     SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) - (TYPE_TARGET_ULONG) ulFromVal (rval);
2528   else if (IS_FLOAT (val->type))
2529     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
2530   else if (IS_FIXED16X16 (val->type))
2531     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble (floatFromVal (lval) - floatFromVal (rval));
2532   else if (SPEC_LONGLONG (val->type))
2533     {
2534       if (SPEC_USIGN (val->type))
2535         SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) - (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2536       else
2537         SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) - (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2538     }
2539   else if (SPEC_LONG (val->type))
2540     {
2541       if (SPEC_USIGN (val->type))
2542         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) - (TYPE_TARGET_ULONG) ulFromVal (rval);
2543       else
2544         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) - (TYPE_TARGET_LONG) ulFromVal (rval);
2545     }
2546   else
2547     {
2548       if (SPEC_USIGN (val->type))
2549         SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) - (TYPE_TARGET_UINT) ulFromVal (rval);
2550       else
2551         SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) - (TYPE_TARGET_INT) ulFromVal (rval);
2552     }
2553   return cheapestVal (val);
2554 }
2555 
2556 /*------------------------------------------------------------------*/
2557 /* valShift - Shift left or right                                   */
2558 /*------------------------------------------------------------------*/
2559 value *
valShift(value * lval,value * rval,int lr)2560 valShift (value * lval, value * rval, int lr)
2561 {
2562   value *val;
2563 
2564   /* create a new value */
2565   val = newValue ();
2566   val->type = val->etype = computeType (lval->etype, NULL, RESULT_TYPE_INT, 'S');
2567   SPEC_SCLS (val->etype) = S_LITERAL;   /* will remain literal */
2568 
2569   if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
2570       /* left shift */
2571       (lr ||
2572        /* right shift and unsigned */
2573        (!lr && SPEC_USIGN (rval->type))) &&
2574        ((TYPE_TARGET_ULONG) ulFromVal (lval) != (TYPE_TARGET_ULONG) 0))
2575     {
2576       werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
2577     }
2578 
2579   if (SPEC_LONGLONG (val->type))
2580     {
2581       if (SPEC_USIGN (val->type))
2582         {
2583           SPEC_CVAL (val->type).v_ulonglong = lr ?
2584             (TYPE_TARGET_ULONGLONG) ullFromVal (lval) << (TYPE_TARGET_ULONGLONG) ullFromVal (rval) :
2585             (TYPE_TARGET_ULONGLONG) ullFromVal (lval) >> (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2586         }
2587       else
2588         {
2589           SPEC_CVAL (val->type).v_longlong = lr ?
2590             (TYPE_TARGET_LONGLONG) ullFromVal (lval) << (TYPE_TARGET_ULONGLONG) ullFromVal (rval) :
2591             (TYPE_TARGET_LONGLONG) ullFromVal (lval) >> (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2592         }
2593     }
2594   else if (SPEC_LONG (val->type))
2595     {
2596       if (SPEC_USIGN (val->type))
2597         {
2598           SPEC_CVAL (val->type).v_ulong = lr ?
2599             (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2600             (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2601         }
2602       else
2603         {
2604           SPEC_CVAL (val->type).v_long = lr ?
2605             (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2606             (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2607         }
2608     }
2609   else
2610     {
2611       if (SPEC_USIGN (val->type))
2612         {
2613           SPEC_CVAL (val->type).v_uint = lr ?
2614             (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2615             (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2616         }
2617       else
2618         {
2619           SPEC_CVAL (val->type).v_int = lr ?
2620             (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) :
2621             (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
2622         }
2623     }
2624   return cheapestVal (val);
2625 }
2626 
2627 /*------------------------------------------------------------------*/
2628 /* valCompare - Compares two literal                                */
2629 /*------------------------------------------------------------------*/
2630 value *
valCompare(value * lval,value * rval,int ctype)2631 valCompare (value * lval, value * rval, int ctype)
2632 {
2633   value *val;
2634 
2635   /* create a new value */
2636   val = newValue ();
2637   val->type = val->etype = newCharLink ();
2638   val->type->xclass = SPECIFIER;
2639   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
2640   SPEC_USIGN (val->type) = 1;
2641   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
2642 
2643   switch (ctype)
2644     {
2645     /* FIXME: need to add long long support to inequalities */
2646     case '<':
2647       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
2648       break;
2649 
2650     case '>':
2651       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
2652       break;
2653 
2654     case LE_OP:
2655       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
2656       break;
2657 
2658     case GE_OP:
2659       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
2660       break;
2661 
2662     case EQ_OP:
2663       if (SPEC_NOUN (lval->type) == V_FLOAT || SPEC_NOUN (rval->type) == V_FLOAT)
2664         {
2665           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
2666         }
2667       else if (SPEC_NOUN (lval->type) == V_FIXED16X16 || SPEC_NOUN (rval->type) == V_FIXED16X16)
2668         {
2669           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
2670         }
2671       else
2672         {
2673           /* integrals: ignore signedness */
2674           TYPE_TARGET_ULONGLONG l, r;
2675 
2676           l = (TYPE_TARGET_ULONGLONG) ullFromVal (lval);
2677           r = (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2678           /* In order to correctly compare 'signed int' and 'unsigned int' it's
2679              neccessary to strip them to 16 bit.
2680              Literals are reduced to their cheapest type, therefore left and
2681              right might have different types. It's neccessary to find a
2682              common type: int (used for char too) or long */
2683           if (!IS_LONGLONG (lval->etype) && !IS_LONGLONG (rval->etype))
2684             {
2685               r = (TYPE_TARGET_ULONG) r;
2686               l = (TYPE_TARGET_ULONG) l;
2687             }
2688           if (!IS_LONG (lval->etype) && !IS_LONG (rval->etype))
2689             {
2690               r = (TYPE_TARGET_UINT) r;
2691               l = (TYPE_TARGET_UINT) l;
2692             }
2693           SPEC_CVAL (val->type).v_int = l == r;
2694         }
2695       break;
2696     case NE_OP:
2697       if (SPEC_NOUN (lval->type) == V_FLOAT || SPEC_NOUN (rval->type) == V_FLOAT)
2698         {
2699           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
2700         }
2701       else if (SPEC_NOUN (lval->type) == V_FIXED16X16 || SPEC_NOUN (rval->type) == V_FIXED16X16)
2702         {
2703           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
2704         }
2705       else
2706         {
2707           /* integrals: ignore signedness */
2708           TYPE_TARGET_ULONGLONG l, r;
2709 
2710           l = (TYPE_TARGET_ULONGLONG) ullFromVal (lval);
2711           r = (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2712           /* In order to correctly compare 'signed int' and 'unsigned int' it's
2713              neccessary to strip them to 16 bit.
2714              Literals are reduced to their cheapest type, therefore left and
2715              right might have different types. It's neccessary to find a
2716              common type: int (used for char too) or long */
2717           if (!IS_LONGLONG (lval->etype) && !IS_LONGLONG (rval->etype))
2718             {
2719               r = (TYPE_TARGET_ULONG) r;
2720               l = (TYPE_TARGET_ULONG) l;
2721             }
2722           if (!IS_LONG (lval->etype) && !IS_LONG (rval->etype))
2723             {
2724               r = (TYPE_TARGET_UINT) r;
2725               l = (TYPE_TARGET_UINT) l;
2726             }
2727           SPEC_CVAL (val->type).v_int = l != r;
2728         }
2729       break;
2730 
2731     }
2732 
2733   return val;
2734 }
2735 
2736 /*------------------------------------------------------------------*/
2737 /* valBitwise - Bitwise operation                                   */
2738 /*------------------------------------------------------------------*/
2739 value *
valBitwise(value * lval,value * rval,int op)2740 valBitwise (value * lval, value * rval, int op)
2741 {
2742   value *val;
2743 
2744   /* create a new value */
2745   val = newValue ();
2746   val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
2747   val->etype = getSpec (val->type);
2748   SPEC_SCLS (val->etype) = S_LITERAL;
2749 
2750   switch (op)
2751     {
2752     case '&':
2753       if (SPEC_LONGLONG (val->type))
2754         {
2755           if (SPEC_USIGN (val->type))
2756             SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) & (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2757           else
2758             SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) & (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2759         }
2760       else if (SPEC_LONG (val->type))
2761         {
2762           if (SPEC_USIGN (val->type))
2763             SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) & (TYPE_TARGET_ULONG) ulFromVal (rval);
2764           else
2765             SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) & (TYPE_TARGET_LONG) ulFromVal (rval);
2766         }
2767       else
2768         {
2769           if (SPEC_USIGN (val->type))
2770             SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) & (TYPE_TARGET_UINT) ulFromVal (rval);
2771           else
2772             SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) & (TYPE_TARGET_INT) ulFromVal (rval);
2773         }
2774       break;
2775 
2776     case '|':
2777       if (SPEC_LONGLONG (val->type))
2778         {
2779           if (SPEC_USIGN (val->type))
2780             SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) | (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2781           else
2782             SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) | (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2783         }
2784       else if (SPEC_LONG (val->type))
2785         {
2786           if (SPEC_USIGN (val->type))
2787             SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) | (TYPE_TARGET_ULONG) ulFromVal (rval);
2788           else
2789             SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) | (TYPE_TARGET_LONG) ulFromVal (rval);
2790         }
2791       else
2792         {
2793           if (SPEC_USIGN (val->type))
2794             SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) | (TYPE_TARGET_UINT) ulFromVal (rval);
2795           else
2796             SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
2797         }
2798 
2799       break;
2800 
2801     case '^':
2802       if (SPEC_LONGLONG (val->type))
2803         {
2804           if (SPEC_USIGN (val->type))
2805             SPEC_CVAL (val->type).v_ulonglong = (TYPE_TARGET_ULONGLONG) ullFromVal (lval) ^ (TYPE_TARGET_ULONGLONG) ullFromVal (rval);
2806           else
2807             SPEC_CVAL (val->type).v_longlong = (TYPE_TARGET_LONGLONG) ullFromVal (lval) ^ (TYPE_TARGET_LONGLONG) ullFromVal (rval);
2808         }
2809       else if (SPEC_LONG (val->type))
2810         {
2811           if (SPEC_USIGN (val->type))
2812             SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^ (TYPE_TARGET_ULONG) ulFromVal (rval);
2813           else
2814             SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^ (TYPE_TARGET_LONG) ulFromVal (rval);
2815         }
2816       else
2817         {
2818           if (SPEC_USIGN (val->type))
2819             SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^ (TYPE_TARGET_UINT) ulFromVal (rval);
2820           else
2821             SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
2822         }
2823       break;
2824     }
2825 
2826   return cheapestVal (val);
2827 }
2828 
2829 /*------------------------------------------------------------------*/
2830 /* valAndOr   - Generates code for and / or operation               */
2831 /*------------------------------------------------------------------*/
2832 value *
valLogicAndOr(value * lval,value * rval,int op)2833 valLogicAndOr (value * lval, value * rval, int op)
2834 {
2835   value *val;
2836 
2837   /* create a new value */
2838   val = newValue ();
2839   val->type = val->etype = newCharLink ();
2840   val->type->xclass = SPECIFIER;
2841   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
2842   SPEC_USIGN (val->type) = 1;
2843 
2844   switch (op)
2845     {
2846     case AND_OP:
2847       SPEC_CVAL (val->type).v_int = !isEqualVal (lval, 0) && !isEqualVal (rval, 0);
2848       break;
2849 
2850     case OR_OP:
2851       SPEC_CVAL (val->type).v_int = !isEqualVal (lval, 0) || !isEqualVal (rval, 0);
2852       break;
2853     }
2854 
2855   return val;
2856 }
2857 
2858 /*------------------------------------------------------------------*/
2859 /* valCastLiteral - casts a literal value to another type           */
2860 /*------------------------------------------------------------------*/
2861 value *
valCastLiteral(sym_link * dtype,double fval,TYPE_TARGET_ULONGLONG llval)2862 valCastLiteral (sym_link * dtype, double fval, TYPE_TARGET_ULONGLONG llval)
2863 {
2864   value *val;
2865   unsigned long l = double2ul (fval);
2866 
2867   if (!dtype)
2868     return NULL;
2869 
2870   val = newValue ();
2871   if (dtype)
2872     val->etype = getSpec (val->type = copyLinkChain (dtype));
2873   else
2874     {
2875       val->etype = val->type = newLink (SPECIFIER);
2876       SPEC_NOUN (val->etype) = V_VOID;
2877     }
2878   SPEC_SCLS (val->etype) = S_LITERAL;
2879 
2880   /* if it is not a specifier then we can assume that */
2881   /* it will be an unsigned long                      */
2882   if (!IS_SPEC (val->type))
2883     {
2884       SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
2885       return val;
2886     }
2887 
2888   switch (SPEC_NOUN (val->etype))
2889     {
2890     case V_FLOAT:
2891       SPEC_CVAL (val->etype).v_float = fval;
2892       break;
2893 
2894     case V_FIXED16X16:
2895       SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
2896       break;
2897 
2898     case V_BOOL:
2899     case V_BIT:
2900     case V_SBIT:
2901       SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
2902       break;
2903 
2904     case V_BITFIELD:
2905       l &= (0xffffffffu >> (32 - SPEC_BLEN (val->etype)));
2906       if (SPEC_USIGN (val->etype))
2907         SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
2908       else
2909         SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
2910       break;
2911 
2912     case V_CHAR:
2913       if (SPEC_USIGN (val->etype))
2914         SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
2915       else
2916         SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
2917       break;
2918 
2919     default:
2920       if (SPEC_LONGLONG (val->etype))
2921         {
2922           if (SPEC_USIGN (val->etype))
2923             SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_ULONGLONG) llval;
2924           else
2925             SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_LONGLONG) llval;
2926         }
2927       else if (SPEC_LONG (val->etype))
2928         {
2929           if (SPEC_USIGN (val->etype))
2930             SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
2931           else
2932             SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
2933         }
2934       else
2935         {
2936           if (SPEC_USIGN (val->etype))
2937             SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
2938           else
2939             SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
2940         }
2941     }
2942 
2943   return val;
2944 }
2945 
2946 /*-------------------------------------------------------------------*/
2947 /* valRecastLitVal - changes type of a literal value to another type */
2948 /*-------------------------------------------------------------------*/
2949 value *
valRecastLitVal(sym_link * dtype,value * val)2950 valRecastLitVal (sym_link * dtype, value * val)
2951 {
2952   sym_link * otype = val->type;
2953   double fval;
2954   TYPE_TARGET_ULONGLONG ull;
2955 
2956   if (IS_SPEC (otype) && (SPEC_NOUN (otype) == V_FIXED16X16 || SPEC_NOUN (otype) == V_FLOAT))
2957     {
2958       fval = floatFromVal (val);
2959       ull = (TYPE_TARGET_ULONGLONG)fval;
2960     }
2961   else
2962     {
2963       ull = (TYPE_TARGET_ULONGLONG) ullFromVal (val);
2964       fval = (double)ull;
2965     }
2966 
2967   if (dtype)
2968     val->etype = getSpec (val->type = copyLinkChain (dtype));
2969   else
2970     {
2971       val->etype = val->type = newLink (SPECIFIER);
2972       SPEC_NOUN (val->etype) = V_VOID;
2973     }
2974   SPEC_SCLS (val->etype) = S_LITERAL;
2975 
2976   /* if it is not a specifier then we can assume that */
2977   /* it will be an unsigned long                      */
2978   if (!IS_SPEC (val->type))
2979     {
2980       SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ull;
2981       return val;
2982     }
2983 
2984   switch (SPEC_NOUN (val->etype))
2985     {
2986     case V_FLOAT:
2987       SPEC_CVAL (val->etype).v_float = fval;
2988       break;
2989 
2990     case V_FIXED16X16:
2991       SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
2992       break;
2993 
2994     case V_BOOL:
2995     case V_BIT:
2996     case V_SBIT:
2997       SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
2998       break;
2999 
3000     case V_BITFIELD:
3001       ull &= (0xffffffffu >> (32 - SPEC_BLEN (val->etype)));
3002       if (SPEC_USIGN (val->etype))
3003         SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) ull;
3004       else
3005         SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) ull;
3006       break;
3007 
3008     case V_CHAR:
3009       if (SPEC_USIGN (val->etype))
3010         SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) ull;
3011       else
3012         SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) ull;
3013       break;
3014 
3015     default:
3016       if (SPEC_LONGLONG (val->etype))
3017         {
3018           if (SPEC_USIGN (val->etype))
3019             SPEC_CVAL (val->etype).v_ulonglong = (TYPE_TARGET_ULONGLONG) ull;
3020           else
3021             SPEC_CVAL (val->etype).v_longlong = (TYPE_TARGET_LONGLONG) ull;
3022         }
3023       else if (SPEC_LONG (val->etype))
3024         {
3025           if (SPEC_USIGN (val->etype))
3026             SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) ull;
3027           else
3028             SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) ull;
3029         }
3030       else
3031         {
3032           if (SPEC_USIGN (val->etype))
3033             SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) ull;
3034           else
3035             SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) ull;
3036         }
3037     }
3038 
3039   return val;
3040 }
3041 
3042 /*------------------------------------------------------------------*/
3043 /* getNelements - determines # of elements from init list           */
3044 /*------------------------------------------------------------------*/
3045 int
getNelements(sym_link * type,initList * ilist)3046 getNelements (sym_link * type, initList * ilist)
3047 {
3048   int i, size;
3049 
3050   if (!ilist)
3051     return 0;
3052 
3053   if (ilist->type == INIT_DEEP)
3054     ilist = ilist->init.deep;
3055 
3056   /* if type is a character array and there is only one
3057      (string) initialiser then get the length of the string */
3058   if (IS_ARRAY (type) && (IS_CHAR (type->next) || IS_INT (type->next) && IS_UNSIGNED (type->next)) && !ilist->next)
3059     {
3060       ast *iast = ilist->init.node;
3061       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
3062 
3063       if (v && IS_ARRAY (v->type) && (IS_CHAR (v->etype) || IS_INT (v->etype) && IS_UNSIGNED (v->etype) && IS_LONG (type->next) == IS_LONG (v->etype)))
3064         /* yep, it's a string */
3065         {
3066           return DCL_ELEM (v->type);
3067         }
3068     }
3069 
3070   size = 0;
3071   i = 0;
3072   while (ilist)
3073     {
3074       if (ilist->designation)
3075         {
3076           if (ilist->designation->type != DESIGNATOR_ARRAY)
3077             {
3078               // structure designator for array, boo.
3079               werrorfl (ilist->filename, ilist->lineno, E_BAD_DESIGNATOR);
3080             }
3081           else
3082             {
3083               i = ilist->designation->designator.elemno;
3084             }
3085         }
3086       if (size <= i)
3087         {
3088           size = i + 1; /* array size is one larger than array init element */
3089         }
3090       i++;
3091       ilist = ilist->next;
3092     }
3093   return size;
3094 }
3095 
3096 /*-----------------------------------------------------------------*/
3097 /* valForArray - returns a value with name of array index          */
3098 /*-----------------------------------------------------------------*/
3099 value *
valForArray(ast * arrExpr)3100 valForArray (ast * arrExpr)
3101 {
3102   value *val, *lval = NULL;
3103   int size = getSize (arrExpr->left->ftype->next);
3104 
3105   /* if the right or left is an array
3106      resolve it first */
3107   if (IS_AST_OP (arrExpr->left))
3108     {
3109       if (arrExpr->left->opval.op == '[')
3110         lval = valForArray (arrExpr->left);
3111       else if (arrExpr->left->opval.op == '.')
3112         lval = valForStructElem (arrExpr->left->left, arrExpr->left->right);
3113       else if (arrExpr->left->opval.op == PTR_OP)
3114         {
3115           if (IS_ADDRESS_OF_OP (arrExpr->left->left))
3116             lval = valForStructElem (arrExpr->left->left->left, arrExpr->left->right);
3117           else if (IS_AST_VALUE (arrExpr->left->left) && IS_PTR (arrExpr->left->left->ftype))
3118             lval = valForStructElem (arrExpr->left->left, arrExpr->left->right);
3119         }
3120       else
3121         return NULL;
3122     }
3123   else if (!IS_AST_SYM_VALUE (arrExpr->left))
3124     return NULL;
3125 
3126   if (!IS_AST_LIT_VALUE (arrExpr->right))
3127     return NULL;
3128 
3129   val = newValue ();
3130   val->type = newLink (DECLARATOR);
3131   if (IS_AST_LIT_VALUE (arrExpr->left) && IS_PTR (arrExpr->left->ftype))
3132     {
3133       SNPRINTF (val->name, sizeof (val->name), "0x%X",
3134                 AST_ULONG_VALUE (arrExpr->left) + AST_ULONG_VALUE (arrExpr->right) * size);
3135       memcpy (val->type, arrExpr->left->ftype, sizeof (sym_link));
3136     }
3137   else if (lval)
3138     {
3139       SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", lval->name, AST_ULONG_VALUE (arrExpr->right) * size);
3140       memcpy (val->type, lval->type, sizeof (sym_link));
3141     }
3142   else
3143     {
3144       SNPRINTF (val->name, sizeof (val->name), "(%s + %d)",
3145                 AST_SYMBOL (arrExpr->left)->rname, AST_ULONG_VALUE (arrExpr->right) * size);
3146       if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
3147         DCL_TYPE (val->type) = CPOINTER;
3148       else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
3149         DCL_TYPE (val->type) = FPOINTER;
3150       else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
3151         DCL_TYPE (val->type) = PPOINTER;
3152       else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
3153         DCL_TYPE (val->type) = IPOINTER;
3154       else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
3155         DCL_TYPE (val->type) = EEPPOINTER;
3156       else
3157         DCL_TYPE (val->type) = POINTER;
3158     }
3159 
3160   val->type->next = arrExpr->left->ftype->next;
3161   val->etype = getSpec (val->type);
3162   return val;
3163 }
3164 
3165 /*-----------------------------------------------------------------*/
3166 /* valForStructElem - returns value with name of struct element    */
3167 /*-----------------------------------------------------------------*/
3168 value *
valForStructElem(ast * structT,ast * elemT)3169 valForStructElem (ast * structT, ast * elemT)
3170 {
3171   value *val, *lval = NULL;
3172   symbol *sym;
3173   int idxoff = 0;
3174   ast *sast = NULL;
3175 
3176   /* left could be further derefed */
3177   if (IS_AST_OP (structT))
3178     {
3179       if (structT->opval.op == '[')
3180         lval = valForArray (structT);
3181       else if (structT->opval.op == '+')
3182         {
3183           if (IS_AST_LIT_VALUE (structT->right) && !IS_AST_OP (structT->left))
3184             {
3185               idxoff = (int) (AST_ULONG_VALUE (structT->right) * getSize (structT->left->ftype->next));
3186               sast = structT->left;
3187             }
3188           else if (IS_AST_LIT_VALUE (structT->left) && !IS_AST_OP (structT->right))
3189             {
3190               idxoff = (int) (AST_ULONG_VALUE (structT->left) * getSize (structT->right->ftype->next));
3191               sast = structT->right;
3192             }
3193           else
3194             return NULL;
3195         }
3196       else if (structT->opval.op == '-')
3197         {
3198           if (IS_AST_LIT_VALUE (structT->right) && !IS_AST_OP (structT->left))
3199             {
3200               idxoff = 0 - (int) (AST_ULONG_VALUE (structT->right) * getSize (structT->left->ftype->next));
3201               sast = structT->left;
3202             }
3203           else
3204             return NULL;
3205         }
3206       else if (structT->opval.op == '.')
3207         lval = valForStructElem (structT->left, structT->right);
3208       else if (structT->opval.op == PTR_OP)
3209         {
3210           if (IS_ADDRESS_OF_OP (structT->left))
3211             lval = valForStructElem (structT->left->left, structT->right);
3212           else if (IS_AST_VALUE (structT->left) && IS_PTR (structT->left->ftype))
3213             lval = valForStructElem (structT->left, structT->right);
3214         }
3215       else
3216         return NULL;
3217     }
3218 
3219   if (!IS_AST_SYM_VALUE (elemT))
3220     return NULL;
3221 
3222   if (!structT || !IS_STRUCT (structT->etype))
3223     return NULL;
3224 
3225   if ((sym = getStructElement (SPEC_STRUCT (structT->etype), AST_SYMBOL (elemT))) == NULL)
3226     {
3227       return NULL;
3228     }
3229 
3230   val = newValue ();
3231   val->type = newLink (DECLARATOR);
3232   if (IS_AST_LIT_VALUE (structT) && IS_PTR (structT->ftype))
3233     {
3234       SNPRINTF (val->name, sizeof (val->name), "0x%X", AST_ULONG_VALUE (structT) + (int) sym->offset);
3235       memcpy (val->type, structT->ftype, sizeof (sym_link));
3236     }
3237   else if (lval)
3238     {
3239       SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", lval->name, (int) sym->offset);
3240       memcpy (val->type, lval->type, sizeof (sym_link));
3241     }
3242   else
3243     {
3244       if (sast)
3245         SNPRINTF (val->name, sizeof (val->name), "(%s + (%d))", AST_SYMBOL (sast)->rname, ((int) sym->offset) + idxoff);
3246       else
3247         SNPRINTF (val->name, sizeof (val->name), "(%s + %d)", AST_SYMBOL (structT)->rname, (int) sym->offset);
3248 
3249       if (SPEC_SCLS (structT->etype) == S_CODE)
3250         DCL_TYPE (val->type) = CPOINTER;
3251       else if (SPEC_SCLS (structT->etype) == S_XDATA)
3252         DCL_TYPE (val->type) = FPOINTER;
3253       else if (SPEC_SCLS (structT->etype) == S_XSTACK)
3254         DCL_TYPE (val->type) = PPOINTER;
3255       else if (SPEC_SCLS (structT->etype) == S_IDATA)
3256         DCL_TYPE (val->type) = IPOINTER;
3257       else if (SPEC_SCLS (structT->etype) == S_EEPROM)
3258         DCL_TYPE (val->type) = EEPPOINTER;
3259       else
3260         DCL_TYPE (val->type) = POINTER;
3261     }
3262 
3263   val->type->next = sym->type;
3264   val->etype = getSpec (val->type);
3265   return val;
3266 }
3267 
3268 /*-----------------------------------------------------------------*/
3269 /* valForCastAggr - will return value for a cast of an aggregate   */
3270 /*                  plus minus a constant                          */
3271 /*-----------------------------------------------------------------*/
3272 value *
valForCastAggr(ast * aexpr,sym_link * type,ast * cnst,int op)3273 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
3274 {
3275   value *val;
3276 
3277   if (!IS_AST_SYM_VALUE (aexpr))
3278     return NULL;
3279   if (!IS_AST_LIT_VALUE (cnst))
3280     return NULL;
3281 
3282   val = newValue ();
3283 
3284   SNPRINTF (val->name, sizeof (val->name), "(%s %c %d)",
3285             AST_SYMBOL (aexpr)->rname, op, getSize (type->next) * AST_ULONG_VALUE (cnst));
3286 
3287   val->type = type;
3288   val->etype = getSpec (val->type);
3289   return val;
3290 }
3291 
3292 /*-----------------------------------------------------------------*/
3293 /* valForCastArr - will return value for a cast of an aggregate    */
3294 /*                 with no constant                                */
3295 /*-----------------------------------------------------------------*/
3296 value *
valForCastArr(ast * aexpr,sym_link * type)3297 valForCastArr (ast * aexpr, sym_link * type)
3298 {
3299   value *val;
3300 
3301   if (!IS_AST_SYM_VALUE (aexpr))
3302     return NULL;
3303 
3304   val = newValue ();
3305 
3306   SNPRINTF (val->name, sizeof (val->name), "(%s)", AST_SYMBOL (aexpr)->rname);
3307 
3308   val->type = type;
3309   val->etype = getSpec (val->type);
3310   return val;
3311 }
3312