* src/SDCCval.c (cheapestVal): changed behaviour to the same as constVal()
[fw/sdcc] / src / SDCCval.c
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 "newalloc.h"
31
32 int cNestLevel;
33
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value        */
36 /*-----------------------------------------------------------------*/
37 value *
38 newValue ()
39 {
40   value *val;
41
42   val = Safe_alloc (sizeof (value));
43
44   return val;
45 }
46
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list                                 */
49 /*-----------------------------------------------------------------*/
50 initList *
51 newiList (int type, void *ilist)
52 {
53   initList *nilist;
54
55
56   nilist = Safe_alloc (sizeof (initList));
57
58   nilist->type = type;
59   nilist->lineno = mylineno;
60
61   switch (type)
62     {
63     case INIT_NODE:
64       nilist->init.node = (struct ast *) ilist;
65       break;
66
67     case INIT_DEEP:
68       nilist->init.deep = (struct initList *) ilist;
69       break;
70     }
71
72   return nilist;
73 }
74
75 /*------------------------------------------------------------------*/
76 /* revinit   - reverses the initial values for a value  chain        */
77 /*------------------------------------------------------------------*/
78 initList *
79 revinit (initList * val)
80 {
81   initList *prev, *curr, *next;
82
83   if (!val)
84     return NULL;
85
86   prev = val;
87   curr = val->next;
88
89   while (curr)
90     {
91       next = curr->next;
92       curr->next = prev;
93       prev = curr;
94       curr = next;
95     }
96   val->next = (void *) NULL;
97   return prev;
98 }
99
100 bool
101 convertIListToConstList(initList *src, literalList **lList)
102 {
103     initList    *iLoop;
104     literalList *head, *last, *newL;
105     
106     head = last = NULL;
107     
108     if (!src || src->type != INIT_DEEP)
109     {
110         return FALSE;
111     }
112     
113     iLoop =  src->init.deep;
114     
115     while (iLoop)
116     {
117         if (iLoop->type != INIT_NODE)
118         {
119             return FALSE;
120         }
121         
122         if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
123         {
124             return FALSE;
125         }
126         iLoop = iLoop->next;
127     }
128     
129     // We've now established that the initializer list contains only literal values.
130     
131     iLoop = src->init.deep;
132     while (iLoop)
133     {
134         double val = AST_LIT_VALUE(iLoop->init.node);
135         
136         if (last && last->literalValue == val)
137         {
138             last->count++;
139         }
140         else
141         {
142             newL = Safe_alloc(sizeof(literalList));
143             newL->literalValue = val;
144             newL->count = 1;
145             newL->next = NULL;
146             
147             if (last)
148             {
149                 last->next = newL;
150             }
151             else
152             {
153                 head = newL;
154             }
155             last = newL;
156         }
157         iLoop = iLoop->next;
158     }
159     
160     if (!head)    
161     {
162         return FALSE;
163     }
164     
165     *lList = head;
166     return TRUE;
167 }
168
169 literalList *
170 copyLiteralList(literalList *src)
171 {
172     literalList *head, *prev, *newL;
173     
174     head = prev = NULL;
175     
176     while (src)
177     {
178         newL = Safe_alloc(sizeof(literalList));
179         
180         newL->literalValue = src->literalValue;
181         newL->count = src->count;
182         newL->next = NULL;
183         
184         if (prev)
185         {
186             prev->next = newL;
187         }
188         else
189         {
190             head = newL;
191         }
192         prev = newL;
193         src = src->next;
194     }
195     
196     return head;
197 }
198
199
200
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list            */
203 /*------------------------------------------------------------------*/
204 initList *
205 copyIlist (initList * src)
206 {
207   initList *dest = NULL;
208
209   if (!src)
210     return NULL;
211
212   switch (src->type)
213     {
214     case INIT_DEEP:
215       dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
216       break;
217     case INIT_NODE:
218       dest = newiList (INIT_NODE, copyAst (src->init.node));
219       break;
220     }
221
222   if (src->next)
223     dest->next = copyIlist (src->next);
224
225   return dest;
226 }
227
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value       */
230 /*------------------------------------------------------------------*/
231 double 
232 list2int (initList * val)
233 {
234   initList *i = val;
235
236   if (i->type == INIT_DEEP)
237     return list2int (val->init.deep);
238
239   return floatFromVal (constExprValue (val->init.node, TRUE));
240 }
241
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value       */
244 /*------------------------------------------------------------------*/
245 value *
246 list2val (initList * val)
247 {
248   if (!val)
249     return NULL;
250
251   if (val->type == INIT_DEEP)
252     return list2val (val->init.deep);
253
254   return constExprValue (val->init.node, TRUE);
255 }
256
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
260 ast *
261 list2expr (initList * ilist)
262 {
263   if (ilist->type == INIT_DEEP)
264     return list2expr (ilist->init.deep);
265   return ilist->init.node;
266 }
267
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values               */
270 /*------------------------------------------------------------------*/
271 void 
272 resolveIvalSym (initList * ilist)
273 {
274   if (!ilist)
275     return;
276
277   if (ilist->type == INIT_NODE)
278     ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
279
280   if (ilist->type == INIT_DEEP)
281     resolveIvalSym (ilist->init.deep);
282
283   resolveIvalSym (ilist->next);
284 }
285
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol              */
288 /*-----------------------------------------------------------------*/
289 value *
290 symbolVal (symbol * sym)
291 {
292   value *val;
293
294   if (!sym)
295     return NULL;
296
297   val = newValue ();
298   val->sym = sym;
299
300   if (sym->type)
301     {
302       val->type = sym->type;
303       val->etype = getSpec (val->type);
304     }
305
306   if (*sym->rname)
307     {
308         SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
309     }
310   else
311     {
312         SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
313     }
314
315   return val;
316 }
317
318 /*--------------------------------------------------------------------*/
319 /* cheapestVal - convert a val to the cheapest as possible value      */
320 /*--------------------------------------------------------------------*/
321 static value *cheapestVal (value *val) {
322   TYPE_DWORD  sval=0;
323   TYPE_UDWORD uval=0;
324
325   if (IS_FLOAT(val->type) || IS_CHAR(val->type))
326     return val;
327
328   if (SPEC_LONG(val->type)) {
329     if (SPEC_USIGN(val->type)) {
330       uval=SPEC_CVAL(val->type).v_ulong;
331     } else {
332       sval=SPEC_CVAL(val->type).v_long;
333     }
334   } else {
335     if (SPEC_USIGN(val->type)) {
336       uval=SPEC_CVAL(val->type).v_uint;
337     } else {
338       sval=SPEC_CVAL(val->type).v_int;
339     }
340   }
341
342   if (SPEC_USIGN(val->type)) {
343     if (uval<=0xffff) {
344       SPEC_LONG(val->type)=0;
345       SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval;
346       if (uval<=0xff) {
347         SPEC_NOUN(val->type)=V_CHAR;
348       }
349     }
350   } else { // not unsigned
351     if (sval<0) {
352       if (sval>=-32768) {
353         SPEC_LONG(val->type)=0;
354         SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
355         if (sval>=-128) {
356           SPEC_NOUN(val->type)=V_CHAR;
357         }
358       }
359     } else { // sval>=0
360       if (sval<=32767) {
361         SPEC_LONG(val->type)=0;
362         SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
363         if (sval<=127) {
364           SPEC_NOUN(val->type)=V_CHAR;
365         }
366       }
367     }
368   }
369   return val;
370 }
371
372 /*-----------------------------------------------------------------*/
373 /* valueFromLit - creates a value from a literal                   */
374 /*-----------------------------------------------------------------*/
375 value *
376 valueFromLit (double lit)
377 {
378   char buffer[50];
379
380   if ((((TYPE_DWORD) lit) - lit) == 0)
381     {
382       SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
383       return constVal (buffer);
384     }
385
386   SNPRINTF (buffer, sizeof(buffer), "%f", lit);
387   return constFloatVal (buffer);
388 }
389
390 /*-----------------------------------------------------------------*/
391 /* constFloatVal - converts a FLOAT constant to value              */
392 /*-----------------------------------------------------------------*/
393 value *
394 constFloatVal (char *s)
395 {
396   value *val = newValue ();
397   double sval;
398
399   if (sscanf (s, "%lf", &sval) != 1)
400     {
401       werror (E_INVALID_FLOAT_CONST, s);
402       return constVal ("0");
403     }
404
405   val->type = val->etype = newLink (SPECIFIER);
406   SPEC_NOUN (val->type) = V_FLOAT;
407   SPEC_SCLS (val->type) = S_LITERAL;
408   SPEC_CVAL (val->type).v_float = sval;
409
410   return val;
411 }
412
413 /*-----------------------------------------------------------------*/
414 /* constVal - converts an INTEGER constant into a cheapest value   */
415 /*-----------------------------------------------------------------*/
416 value *constVal (char *s)
417 {
418   value *val;
419   short hex = 0, octal = 0;
420   char scanFmt[10];
421   int scI = 0;
422   double dval;
423
424   val = newValue ();            /* alloc space for value   */
425
426   val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
427   SPEC_SCLS (val->type) = S_LITERAL;
428   // let's start with an unsigned char
429   SPEC_NOUN (val->type) = V_CHAR;
430   SPEC_USIGN (val->type) = 0;
431
432   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
433
434   /* set the octal flag   */
435   if (!hex && *s == '0' && *(s + 1))
436     octal = 1;
437
438   /* create the scan string */
439   scanFmt[scI++] = '%';
440
441   scanFmt[scI++] = 'l';
442
443   if (octal)
444     scanFmt[scI++] = 'o';
445   else if (hex)
446     scanFmt[scI++] = 'x';
447   else
448     scanFmt[scI++] = 'f';
449
450   scanFmt[scI++] = '\0';
451
452   if (octal || hex) {
453     unsigned long sval;
454     sscanf (s, scanFmt, &sval);
455     dval=sval;
456     SPEC_USIGN (val->type) = 1;
457   } else {
458     sscanf (s, scanFmt, &dval);
459   }
460
461   /* Setup the flags first */
462   /* set the _long flag if 'lL' is found */
463   if (strchr (s, 'l') || strchr (s, 'L')) {
464     SPEC_NOUN (val->type) = V_INT;
465     SPEC_LONG (val->type) = 1;
466   }
467
468   /* set the unsigned flag if 'uU' is found */
469   if (strchr (s, 'u') || strchr (s, 'U')) {
470     SPEC_USIGN (val->type) = 1;
471   }
472
473   if (dval<0) { // "-28u" will still be signed and negative
474     if (dval<-128) { // check if we have to promote to int
475       SPEC_NOUN (val->type) = V_INT;
476     }
477     if (dval<-32768) { // check if we have to promote to long int
478       SPEC_LONG (val->type) = 1;
479     }
480   } else { // >=0
481     if (dval>0xff && SPEC_USIGN (val->type)) { // check if we have to promote to int
482       SPEC_NOUN (val->type) = V_INT;
483     }
484     else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
485       SPEC_NOUN (val->type) = V_INT;
486     }
487     if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
488       SPEC_LONG (val->type) = 1;
489     }
490     else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
491       SPEC_LONG (val->type) = 1;
492     }
493   }
494
495   if (SPEC_LONG (val->type))
496     {
497       if (SPEC_USIGN (val->type))
498         {
499           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
500         }
501       else
502         {
503           SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
504         }
505     }
506   else
507     {
508       if (SPEC_USIGN (val->type))
509         {
510           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
511         }
512       else
513         {
514           SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
515         }
516     }
517
518   return val;
519 }
520
521 /*! /fn char hexEscape(char **src)
522
523     /param src Pointer to 'x' from start of hex character value
524 */
525
526 unsigned char hexEscape(char **src)
527 {
528   char *s ;
529   unsigned long value ;
530   
531   (*src)++ ;    /* Skip over the 'x' */
532   s = *src ;    /* Save for error detection */
533   
534   value = strtol (*src, src, 16);
535   
536   if (s == *src) {
537       // no valid hex found
538       werror(E_INVALID_HEX);
539   } else {
540     if (value > 255) {
541       werror(W_ESC_SEQ_OOR_FOR_CHAR);
542     }
543   }
544   return (char) value;
545 }
546
547 /*------------------------------------------------------------------*/
548 /* octalEscape - process an octal constant of max three digits      */
549 /* return the octal value, throw a warning for illegal octal        */
550 /* adjust src to point at the last proccesed char                   */
551 /*------------------------------------------------------------------*/
552
553 unsigned char octalEscape (char **str) {
554   int digits;
555   unsigned value=0;
556
557   for (digits=0; digits<3; digits++) {
558     if (**str>='0' && **str<='7') {
559       value = value*8 + (**str-'0');
560       (*str)++;
561     } else {
562       break;
563     }
564   }
565   if (digits) {
566     if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
567       werror (W_ESC_SEQ_OOR_FOR_CHAR);
568     }
569   }
570   return value;
571 }
572
573 /*! 
574   /fn int copyStr (char *dest, char *src)
575   
576   Copies a source string to a dest buffer interpreting escape sequences
577   and special characters
578
579   /param dest Buffer to receive the resultant string
580   /param src  Buffer containing the source string with escape sequecnes
581   /return Number of characters in output string
582
583 */
584
585 int 
586 copyStr (char *dest, char *src)
587
588 {
589   char *OriginalDest = dest ;
590
591   while (*src)
592     {
593       if (*src == '\"')
594         src++;
595       else if (*src == '\\')
596         {
597           src++;
598           switch (*src)
599             {
600             case 'n':
601               *dest++ = '\n';
602               break;
603             case 't':
604               *dest++ = '\t';
605               break;
606             case 'v':
607               *dest++ = '\v';
608               break;
609             case 'b':
610               *dest++ = '\b';
611               break;
612             case 'r':
613               *dest++ = '\r';
614               break;
615             case 'f':
616               *dest++ = '\f';
617               break;
618             case 'a':
619               *dest++ = '\a';
620               break;
621
622             case '0':
623             case '1':
624             case '2':
625             case '3':
626             case '4':
627             case '5':
628             case '6':
629             case '7':
630               *dest++ = octalEscape(&src);
631               src-- ;
632               break;
633
634             case 'x': 
635               *dest++ = hexEscape(&src) ;
636               src-- ;
637               break ;
638
639             case '\\':
640               *dest++ = '\\';
641               break;
642             case '\?':
643               *dest++ = '\?';
644               break;
645             case '\'':
646               *dest++ = '\'';
647               break;
648             case '\"':
649               *dest++ = '\"';
650               break;
651             default:
652               *dest++ = *src;
653             }
654           src++;
655         }
656       else
657         *dest++ = *src++;
658     }
659
660   *dest++ = '\0';
661
662   return dest - OriginalDest ;
663 }
664
665 /*------------------------------------------------------------------*/
666 /* strVal - converts a string constant to a value       */
667 /*------------------------------------------------------------------*/
668 value *
669 strVal (char *s)
670 {
671   value *val;
672
673   val = newValue ();            /* get a new one */
674
675   /* get a declarator */
676   val->type = newLink (DECLARATOR);
677   DCL_TYPE (val->type) = ARRAY;
678   val->type->next = val->etype = newLink (SPECIFIER);
679   SPEC_NOUN (val->etype) = V_CHAR;
680   SPEC_SCLS (val->etype) = S_LITERAL;
681
682   SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
683   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
684
685   return val;
686 }
687
688
689 /*------------------------------------------------------------------*/
690 /* reverseValWithType - reverses value chain with type & etype      */
691 /*------------------------------------------------------------------*/
692 value *
693 reverseValWithType (value * val)
694 {
695   sym_link *type;
696   sym_link *etype;
697
698   if (!val)
699     return NULL;
700
701   /* save the type * etype chains */
702   type = val->type;
703   etype = val->etype;
704
705   /* set the current one 2b null */
706   val->type = val->etype = NULL;
707   val = reverseVal (val);
708
709   /* restore type & etype */
710   val->type = type;
711   val->etype = etype;
712
713   return val;
714 }
715
716 /*------------------------------------------------------------------*/
717 /* reverseVal - reverses the values for a value  chain        */
718 /*------------------------------------------------------------------*/
719 value *
720 reverseVal (value * val)
721 {
722   value *prev, *curr, *next;
723
724   if (!val)
725     return NULL;
726
727   prev = val;
728   curr = val->next;
729
730   while (curr)
731     {
732       next = curr->next;
733       curr->next = prev;
734       prev = curr;
735       curr = next;
736     }
737   val->next = (void *) NULL;
738   return prev;
739 }
740
741 /*------------------------------------------------------------------*/
742 /* copyValueChain - will copy a chain of values                     */
743 /*------------------------------------------------------------------*/
744 value *
745 copyValueChain (value * src)
746 {
747   value *dest;
748
749   if (!src)
750     return NULL;
751
752   dest = copyValue (src);
753   dest->next = copyValueChain (src->next);
754
755   return dest;
756 }
757
758 /*------------------------------------------------------------------*/
759 /* copyValue - copies contents of a value to a fresh one            */
760 /*------------------------------------------------------------------*/
761 value *
762 copyValue (value * src)
763 {
764   value *dest;
765
766   dest = newValue ();
767   dest->sym = copySymbol (src->sym);
768   strncpyz (dest->name, src->name, SDCC_NAME_MAX);
769   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
770   dest->etype = (src->type ? getSpec (dest->type) : NULL);
771
772   return dest;
773 }
774
775 /*------------------------------------------------------------------*/
776 /* charVal - converts a character constant to a value       */
777 /*------------------------------------------------------------------*/
778 value *
779 charVal (char *s)
780 {
781   value *val;
782
783   val = newValue ();
784
785   val->type = val->etype = newLink (SPECIFIER);
786   SPEC_NOUN (val->type) = V_CHAR;
787   SPEC_USIGN(val->type) = 1;
788   SPEC_SCLS (val->type) = S_LITERAL;
789
790   s++;                          /* get rid of quotation */
791   /* if \ then special processing */
792   if (*s == '\\')
793     {
794       s++;                      /* go beyond the backslash  */
795       switch (*s)
796         {
797         case 'n':
798           SPEC_CVAL (val->type).v_uint = '\n';
799           break;
800         case 't':
801           SPEC_CVAL (val->type).v_uint = '\t';
802           break;
803         case 'v':
804           SPEC_CVAL (val->type).v_uint = '\v';
805           break;
806         case 'b':
807           SPEC_CVAL (val->type).v_uint = '\b';
808           break;
809         case 'r':
810           SPEC_CVAL (val->type).v_uint = '\r';
811           break;
812         case 'f':
813           SPEC_CVAL (val->type).v_uint = '\f';
814           break;
815         case 'a':
816           SPEC_CVAL (val->type).v_uint = '\a';
817           break;
818         case '\\':
819           SPEC_CVAL (val->type).v_uint = '\\';
820           break;
821         case '\?':
822           SPEC_CVAL (val->type).v_uint = '\?';
823           break;
824         case '\'':
825           SPEC_CVAL (val->type).v_uint = '\'';
826           break;
827         case '\"':
828           SPEC_CVAL (val->type).v_uint = '\"';
829           break;
830
831         case '0' :
832         case '1' :
833         case '2' :
834         case '3' :
835         case '4' :
836         case '5' :
837         case '6' :
838         case '7' :
839           SPEC_CVAL (val->type).v_uint = octalEscape(&s);
840           break;
841
842         case 'x':
843           SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
844           break;
845
846         default:
847           SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
848           break;
849         }
850     }
851   else                          /* not a backslash */
852     SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
853
854   return val;
855 }
856
857 /*------------------------------------------------------------------*/
858 /* valFromType - creates a value from type given                    */
859 /*------------------------------------------------------------------*/
860 value *
861 valFromType (sym_link * type)
862 {
863   value *val = newValue ();
864   val->type = copyLinkChain (type);
865   val->etype = getSpec (val->type);
866   return val;
867 }
868
869 /*------------------------------------------------------------------*/
870 /* floatFromVal - value to double float conversion                  */
871 /*------------------------------------------------------------------*/
872 double 
873 floatFromVal (value * val)
874 {
875   if (!val)
876     return 0;
877
878   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
879     {
880       werror (E_CONST_EXPECTED, val->name);
881       return 0;
882     }
883
884   /* if it is not a specifier then we can assume that */
885   /* it will be an unsigned long                      */
886   if (!IS_SPEC (val->type))
887     return (double) SPEC_CVAL (val->etype).v_ulong;
888
889   if (SPEC_NOUN (val->etype) == V_FLOAT)
890     return (double) SPEC_CVAL (val->etype).v_float;
891
892   if (SPEC_LONG (val->etype))
893     {
894       if (SPEC_USIGN (val->etype))
895         return (double) SPEC_CVAL (val->etype).v_ulong;
896       else
897         return (double) SPEC_CVAL (val->etype).v_long;
898     }
899   
900   if (SPEC_NOUN (val->etype) == V_INT) {
901     if (SPEC_USIGN (val->etype))
902       return (double) SPEC_CVAL (val->etype).v_uint;
903     else
904       return (double) SPEC_CVAL (val->etype).v_int;
905   }
906
907   if (SPEC_NOUN (val->etype) == V_CHAR) {
908     if (SPEC_USIGN (val->etype))
909       return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
910     else
911       return (double) (signed char)SPEC_CVAL (val->etype).v_int;
912   }
913
914   if (IS_BITVAR(val->etype)) {
915     return (double) SPEC_CVAL (val->etype).v_uint;
916   }
917
918   if (SPEC_NOUN (val->etype) == V_VOID) {
919     return (double) SPEC_CVAL (val->etype).v_ulong;
920   }
921
922   // we are lost !
923   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
924           "floatFromVal: unknown value");
925   return 0;
926 }
927
928
929 /*------------------------------------------------------------------*/
930 /* valUnaryPM - does the unary +/- operation on a constant          */
931 /*------------------------------------------------------------------*/
932 value *
933 valUnaryPM (value * val)
934 {
935   /* depending on type */
936   if (SPEC_NOUN (val->etype) == V_FLOAT)
937     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
938   else
939     {
940       if (SPEC_LONG (val->etype))
941         {
942           if (SPEC_USIGN (val->etype))
943             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
944           else
945             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
946         }
947       else
948         {
949           if (SPEC_USIGN (val->etype))
950             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
951           else
952             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
953         }
954     }
955   // -(unsigned 3) now really is signed
956   SPEC_USIGN(val->etype)=0;
957   // -(unsigned char)135 now really is an int
958   if (SPEC_NOUN(val->etype) == V_CHAR) {
959     if (SPEC_CVAL(val->etype).v_int < -128) {
960       SPEC_NOUN(val->etype) = V_INT;
961     }
962   }
963   return val;
964 }
965
966 /*------------------------------------------------------------------*/
967 /* valueComplement - complements a constant                         */
968 /*------------------------------------------------------------------*/
969 value *
970 valComplement (value * val)
971 {
972   /* depending on type */
973   if (SPEC_LONG (val->etype))
974     {
975       if (SPEC_USIGN (val->etype))
976         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
977       else
978         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
979     }
980   else
981     {
982       if (SPEC_USIGN (val->etype))
983         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
984       else
985         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
986     }
987   // ~(unsigned 3) now really is signed
988   SPEC_USIGN(val->etype)=0;
989   return val;
990 }
991
992 /*------------------------------------------------------------------*/
993 /* valueNot - complements a constant                                */
994 /*------------------------------------------------------------------*/
995 value *
996 valNot (value * val)
997 {
998   /* depending on type */
999   if (SPEC_LONG (val->etype))
1000     {
1001       if (SPEC_USIGN (val->etype))
1002         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1003       else
1004         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1005     }
1006   else
1007     {
1008       if (SPEC_USIGN (val->etype))
1009         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1010       else
1011         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1012     }
1013   return val;
1014 }
1015
1016 /*------------------------------------------------------------------*/
1017 /* valMult - multiply constants                                     */
1018 /*------------------------------------------------------------------*/
1019 value *
1020 valMult (value * lval, value * rval)
1021 {
1022   value *val;
1023
1024   /* create a new value */
1025   val = newValue ();
1026   val->type = val->etype = newLink (SPECIFIER);
1027   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1028                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1029   SPEC_SCLS  (val->type) = S_LITERAL;   /* will remain literal */
1030   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1031   SPEC_LONG  (val->type) = (SPEC_LONG  (lval->etype) | SPEC_LONG  (rval->etype));
1032
1033   if (IS_FLOAT (val->type))
1034     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1035   else
1036     {
1037       /* signed and unsigned mul are the same, as long as the precision of the
1038          result isn't bigger than the precision of the operands. */
1039       if (SPEC_LONG (val->type))
1040         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1041                                         (TYPE_UDWORD) floatFromVal (rval);
1042       else
1043         {
1044           TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1045                            (TYPE_UWORD) floatFromVal (rval);
1046           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1047           if (!options.lessPedantic)
1048             {
1049               if (SPEC_USIGN (val->type))
1050                 {
1051                   if (ul != SPEC_CVAL (val->type).v_uint)
1052                     werror (W_INT_OVL);
1053                 }
1054               else /* signed result */
1055                 {
1056                   if ((TYPE_DWORD) ul != SPEC_CVAL (val->type).v_int)
1057                     werror (W_INT_OVL);
1058                 }
1059             }
1060         }
1061     }
1062   return cheapestVal(val);
1063 }
1064
1065 /*------------------------------------------------------------------*/
1066 /* valDiv  - Divide   constants                                     */
1067 /*------------------------------------------------------------------*/
1068 value *
1069 valDiv (value * lval, value * rval)
1070 {
1071   value *val;
1072
1073   if (floatFromVal (rval) == 0)
1074     {
1075       werror (E_DIVIDE_BY_ZERO);
1076       return rval;
1077     }
1078
1079   /* create a new value */
1080   val = newValue ();
1081   val->type = val->etype = newLink(SPECIFIER);
1082   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1083                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1084   SPEC_SCLS (val->etype) = S_LITERAL;
1085   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1086   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1087
1088   if (IS_FLOAT (val->type))
1089     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1090   else
1091     {
1092       if (SPEC_LONG (val->type))
1093         {
1094           if (SPEC_USIGN (val->type))
1095             SPEC_CVAL (val->type).v_ulong = 
1096               (unsigned long) floatFromVal (lval) /
1097               (unsigned long) floatFromVal (rval);
1098           else
1099             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1100               (long) floatFromVal (rval);
1101         }
1102       else
1103         {
1104           if (SPEC_USIGN (val->type)) {
1105             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1106               (unsigned) floatFromVal (rval);
1107           } else {
1108             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1109               (int) floatFromVal (rval);
1110           }
1111         }
1112     }
1113   return cheapestVal(val);
1114 }
1115
1116 /*------------------------------------------------------------------*/
1117 /* valMod  - Modulus  constants                                     */
1118 /*------------------------------------------------------------------*/
1119 value *
1120 valMod (value * lval, value * rval)
1121 {
1122   value *val;
1123
1124   /* create a new value */
1125   val = newValue ();
1126   val->type = val->etype = newLink (SPECIFIER);
1127   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1128   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1129   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1130   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1131
1132   if (SPEC_LONG (val->type))
1133     {
1134       if (SPEC_USIGN (val->type))
1135         SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1136           (unsigned long) floatFromVal (rval);
1137       else
1138         SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1139           (unsigned long) floatFromVal (rval);
1140     }
1141   else
1142     {
1143       if (SPEC_USIGN (val->type)) {
1144         SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1145           (unsigned) floatFromVal (rval);
1146       } else {
1147         SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1148           (unsigned) floatFromVal (rval);
1149       }
1150     }
1151
1152   return cheapestVal(val);
1153 }
1154
1155 /*------------------------------------------------------------------*/
1156 /* valPlus - Addition constants                                     */
1157 /*------------------------------------------------------------------*/
1158 value *
1159 valPlus (value * lval, value * rval)
1160 {
1161   value *val;
1162
1163   /* create a new value */
1164   val = newValue ();
1165   val->type = val->etype = newLink (SPECIFIER);
1166   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1167                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1168   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1169   SPEC_USIGN (val->type) = 
1170     SPEC_USIGN (lval->etype) &&
1171     SPEC_USIGN (rval->etype) &&
1172     (floatFromVal(lval)+floatFromVal(rval))>=0;
1173     
1174   SPEC_LONG (val->type) = 1;
1175
1176   if (IS_FLOAT (val->type))
1177     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1178   else
1179     {
1180       if (SPEC_LONG (val->type))
1181         {
1182           if (SPEC_USIGN (val->type))
1183             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1184               (unsigned long) floatFromVal (rval);
1185           else
1186             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1187               (long) floatFromVal (rval);
1188         }
1189     }
1190   return cheapestVal(val);
1191 }
1192
1193 /*------------------------------------------------------------------*/
1194 /* valMinus - Addition constants                                    */
1195 /*------------------------------------------------------------------*/
1196 value *
1197 valMinus (value * lval, value * rval)
1198 {
1199   value *val;
1200
1201   /* create a new value */
1202   val = newValue ();
1203   val->type = val->etype = newLink (SPECIFIER);
1204   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1205                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1206   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1207   SPEC_USIGN (val->type) = 
1208     SPEC_USIGN (lval->etype) &&
1209     SPEC_USIGN (rval->etype) &&
1210     (floatFromVal(lval)-floatFromVal(rval))>=0;
1211
1212   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1213
1214   if (IS_FLOAT (val->type))
1215     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1216   else
1217     {
1218       if (SPEC_LONG (val->type))
1219         {
1220           if (SPEC_USIGN (val->type)) {
1221             SPEC_CVAL (val->type).v_ulong = 
1222               (unsigned long) floatFromVal (lval) -
1223               (unsigned long) floatFromVal (rval);
1224           } else {
1225             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1226               (long) floatFromVal (rval);
1227           }
1228         }
1229       else
1230         {
1231           if (SPEC_USIGN (val->type)) {
1232             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1233               (unsigned) floatFromVal (rval);
1234           } else {
1235             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - 
1236               (int) floatFromVal (rval);
1237           }
1238         }
1239     }
1240   return cheapestVal(val);
1241 }
1242
1243 /*------------------------------------------------------------------*/
1244 /* valShift - Shift left or right                                   */
1245 /*------------------------------------------------------------------*/
1246 value *
1247 valShift (value * lval, value * rval, int lr)
1248 {
1249   value *val;
1250
1251   /* create a new value */
1252   val = newValue ();
1253   val->type = val->etype = newIntLink ();
1254   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1255   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1256   SPEC_LONG (val->type) = 1;
1257
1258   if (SPEC_LONG (val->type))
1259     {
1260       if (SPEC_USIGN (val->type))
1261         SPEC_CVAL (val->type).v_ulong = lr ? 
1262           (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1263           (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1264       else
1265         SPEC_CVAL (val->type).v_long = lr ?
1266           (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1267           (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1268     }
1269
1270   return cheapestVal(val);
1271 }
1272
1273 /*------------------------------------------------------------------*/
1274 /* valCompare- Compares two literal                                 */
1275 /*------------------------------------------------------------------*/
1276 value *
1277 valCompare (value * lval, value * rval, int ctype)
1278 {
1279   value *val;
1280
1281   /* create a new value */
1282   val = newValue ();
1283   val->type = val->etype = newCharLink ();
1284   val->type->class = SPECIFIER;
1285   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1286   SPEC_USIGN (val->type) = 1;
1287   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1288
1289   switch (ctype)
1290     {
1291     case '<':
1292       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1293       break;
1294
1295     case '>':
1296       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1297       break;
1298
1299     case LE_OP:
1300       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1301       break;
1302
1303     case GE_OP:
1304       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1305       break;
1306
1307     case EQ_OP:
1308       SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1309       break;
1310
1311     case NE_OP:
1312       SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1313       break;
1314
1315     }
1316
1317   return val;
1318 }
1319
1320 /*------------------------------------------------------------------*/
1321 /* valBitwise - Bitwise operation                                   */
1322 /*------------------------------------------------------------------*/
1323 value *
1324 valBitwise (value * lval, value * rval, int op)
1325 {
1326   value *val;
1327
1328   /* create a new value */
1329   val = newValue ();
1330   val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1331                              rval->type : lval->type);
1332   val->etype = getSpec (val->type);
1333
1334   switch (op)
1335     {
1336     case '&':
1337       if (SPEC_LONG (val->type))
1338         {
1339           if (SPEC_USIGN (val->type))
1340             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1341               (unsigned long) floatFromVal (rval);
1342           else
1343             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1344               (long) floatFromVal (rval);
1345         }
1346       else
1347         {
1348           if (SPEC_USIGN (val->type))
1349             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1350               (unsigned) floatFromVal (rval);
1351           else
1352             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1353         }
1354       break;
1355
1356     case '|':
1357       if (SPEC_LONG (val->type))
1358         {
1359           if (SPEC_USIGN (val->type))
1360             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1361               (unsigned long) floatFromVal (rval);
1362           else
1363             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1364               (long) floatFromVal (rval);
1365         }
1366       else
1367         {
1368           if (SPEC_USIGN (val->type))
1369             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1370               (unsigned) floatFromVal (rval);
1371           else
1372             SPEC_CVAL (val->type).v_int =
1373               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1374         }
1375
1376       break;
1377
1378     case '^':
1379       if (SPEC_LONG (val->type))
1380         {
1381           if (SPEC_USIGN (val->type))
1382             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1383               (unsigned long) floatFromVal (rval);
1384           else
1385             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1386               (long) floatFromVal (rval);
1387         }
1388       else
1389         {
1390           if (SPEC_USIGN (val->type))
1391             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1392               (unsigned) floatFromVal (rval);
1393           else
1394             SPEC_CVAL (val->type).v_int =
1395               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1396         }
1397       break;
1398     }
1399
1400   return cheapestVal(val);
1401 }
1402
1403 /*------------------------------------------------------------------*/
1404 /* valAndOr   - Generates code for and / or operation               */
1405 /*------------------------------------------------------------------*/
1406 value *
1407 valLogicAndOr (value * lval, value * rval, int op)
1408 {
1409   value *val;
1410
1411   /* create a new value */
1412   val = newValue ();
1413   val->type = val->etype = newCharLink ();
1414   val->type->class = SPECIFIER;
1415   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1416   SPEC_USIGN (val->type) = 0;
1417
1418   switch (op)
1419     {
1420     case AND_OP:
1421       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1422       break;
1423
1424     case OR_OP:
1425       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1426       break;
1427     }
1428
1429
1430   return val;
1431 }
1432
1433 /*------------------------------------------------------------------*/
1434 /* valCastLiteral - casts a literal value to another type           */
1435 /*------------------------------------------------------------------*/
1436 value *
1437 valCastLiteral (sym_link * dtype, double fval)
1438 {
1439   value *val;
1440
1441   if (!dtype)
1442     return NULL;
1443
1444   val = newValue ();
1445   val->etype = getSpec (val->type = copyLinkChain (dtype));
1446   SPEC_SCLS (val->etype) = S_LITERAL;
1447   /* if it is not a specifier then we can assume that */
1448   /* it will be an unsigned long                      */
1449   if (!IS_SPEC (val->type)) {
1450       SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1451       return val;
1452   }
1453
1454   if (SPEC_NOUN (val->etype) == V_FLOAT)
1455       SPEC_CVAL (val->etype).v_float = fval;
1456   else {
1457       unsigned long l = (unsigned long)fval;
1458       if (SPEC_LONG (val->etype)) {
1459           if (SPEC_USIGN (val->etype))
1460               SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1461           else
1462               SPEC_CVAL (val->etype).v_long = (long) l;
1463       } else {
1464           if (SPEC_USIGN (val->etype))
1465               SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1466           else
1467               SPEC_CVAL (val->etype).v_int = (short)l;
1468       }
1469   }
1470   return val;
1471 }
1472
1473 /*------------------------------------------------------------------*/
1474 /* getNelements - determines # of elements from init list           */
1475 /*------------------------------------------------------------------*/
1476 int 
1477 getNelements (sym_link * type, initList * ilist)
1478 {
1479   int i;
1480
1481   if (!ilist)
1482     return 0;
1483
1484   if (ilist->type == INIT_DEEP)
1485     ilist = ilist->init.deep;
1486
1487   /* if type is a character array and there is only one
1488      (string) initialiser then get the length of the string */
1489   if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1490     {
1491       ast *iast = ilist->init.node;
1492       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1493       if (!v)
1494         {
1495           werror (E_CONST_EXPECTED);
1496           return 0;
1497         }
1498
1499       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1500         // yep, it's a string
1501         {
1502           return DCL_ELEM (v->type);
1503         }
1504     }
1505
1506   i = 0;
1507   while (ilist)
1508     {
1509       i++;
1510       ilist = ilist->next;
1511     }
1512   return i;
1513 }
1514
1515 /*-----------------------------------------------------------------*/
1516 /* valForArray - returns a value with name of array index          */
1517 /*-----------------------------------------------------------------*/
1518 value *
1519 valForArray (ast * arrExpr)
1520 {
1521   value *val, *lval = NULL;
1522   char buffer[128];
1523   int size = getSize (arrExpr->left->ftype->next);
1524   /* if the right or left is an array
1525      resolve it first */
1526   if (IS_AST_OP (arrExpr->left))
1527     {
1528       if (arrExpr->left->opval.op == '[')
1529         lval = valForArray (arrExpr->left);
1530       else if (arrExpr->left->opval.op == '.')
1531         lval = valForStructElem (arrExpr->left->left,
1532                                  arrExpr->left->right);
1533       else if (arrExpr->left->opval.op == PTR_OP &&
1534                IS_ADDRESS_OF_OP (arrExpr->left->left))
1535         lval = valForStructElem (arrExpr->left->left->left,
1536                                  arrExpr->left->right);
1537       else
1538         return NULL;
1539
1540     }
1541   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1542     return NULL;
1543
1544   if (!IS_AST_LIT_VALUE (arrExpr->right))
1545     return NULL;
1546
1547   val = newValue ();
1548   if (!lval)
1549     {
1550         SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1551     }
1552   else
1553     {
1554         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1555     }
1556
1557   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1558            (int) AST_LIT_VALUE (arrExpr->right) * size);
1559
1560   val->type = newLink (DECLARATOR);
1561   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1562     {
1563       DCL_TYPE (val->type) = CPOINTER;
1564       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1565     }
1566   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1567     DCL_TYPE (val->type) = FPOINTER;
1568   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1569     DCL_TYPE (val->type) = PPOINTER;
1570   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1571     DCL_TYPE (val->type) = IPOINTER;
1572   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1573     DCL_TYPE (val->type) = EEPPOINTER;
1574   else
1575     DCL_TYPE (val->type) = POINTER;
1576   val->type->next = arrExpr->left->ftype;
1577   val->etype = getSpec (val->type);
1578   return val;
1579 }
1580
1581 /*-----------------------------------------------------------------*/
1582 /* valForStructElem - returns value with name of struct element    */
1583 /*-----------------------------------------------------------------*/
1584 value *
1585 valForStructElem (ast * structT, ast * elemT)
1586 {
1587   value *val, *lval = NULL;
1588   char buffer[128];
1589   symbol *sym;
1590
1591   /* left could be furthur derefed */
1592   if (IS_AST_OP (structT))
1593     {
1594       if (structT->opval.op == '[')
1595         lval = valForArray (structT);
1596       else if (structT->opval.op == '.')
1597         lval = valForStructElem (structT->left, structT->right);
1598       else if (structT->opval.op == PTR_OP &&
1599                IS_ADDRESS_OF_OP (structT->left))
1600         lval = valForStructElem (structT->left->left,
1601                                  structT->right);
1602       else
1603         return NULL;
1604     }
1605
1606   if (!IS_AST_SYM_VALUE (elemT))
1607     return NULL;
1608
1609   if (!IS_STRUCT (structT->etype))
1610     return NULL;
1611
1612   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1613                                AST_SYMBOL (elemT))) == NULL)
1614     {
1615       return NULL;
1616     }
1617
1618   val = newValue ();
1619   if (!lval)
1620     {
1621         SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1622     }
1623   else
1624     {
1625         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1626     }
1627
1628   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1629            (int) sym->offset);
1630
1631   val->type = newLink (DECLARATOR);
1632   if (SPEC_SCLS (structT->etype) == S_CODE)
1633     {
1634       DCL_TYPE (val->type) = CPOINTER;
1635       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1636     }
1637   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1638     DCL_TYPE (val->type) = FPOINTER;
1639   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1640     DCL_TYPE (val->type) = PPOINTER;
1641   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1642     DCL_TYPE (val->type) = IPOINTER;
1643   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1644     DCL_TYPE (val->type) = EEPPOINTER;
1645   else
1646     DCL_TYPE (val->type) = POINTER;
1647   val->type->next = sym->type;
1648   val->etype = getSpec (val->type);
1649   return val;
1650 }
1651
1652 /*-----------------------------------------------------------------*/
1653 /* valForCastAggr - will return value for a cast of an aggregate   */
1654 /*                  plus minus a constant                          */
1655 /*-----------------------------------------------------------------*/
1656 value *
1657 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1658 {
1659   value *val;
1660
1661   if (!IS_AST_SYM_VALUE (aexpr))
1662     return NULL;
1663   if (!IS_AST_LIT_VALUE (cnst))
1664     return NULL;
1665
1666   val = newValue ();
1667
1668   SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1669            AST_SYMBOL (aexpr)->rname, op,
1670            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1671
1672   val->type = type;
1673   val->etype = getSpec (val->type);
1674   return val;
1675 }
1676
1677 /*-----------------------------------------------------------------*/
1678 /* valForCastAggr - will return value for a cast of an aggregate   */
1679 /*                  with no constant                               */
1680 /*-----------------------------------------------------------------*/
1681 value *
1682 valForCastArr (ast * aexpr, sym_link * type)
1683 {
1684   value *val;
1685
1686   if (!IS_AST_SYM_VALUE (aexpr))
1687     return NULL;
1688
1689   val = newValue ();
1690
1691   SNPRINTF (val->name, sizeof(val->name), "(%s)",
1692            AST_SYMBOL (aexpr)->rname);
1693
1694   val->type = type;
1695   val->etype = getSpec (val->type);
1696   return val;
1697 }