62ffcec2a1670ff07d3443ab3fc7a03778b6d5b8
[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 /* int */
1043         {
1044           TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1045                            (TYPE_UWORD) floatFromVal (rval);
1046
1047           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1048           if (!options.lessPedantic)
1049             {
1050               if (SPEC_USIGN (val->type))
1051                 {
1052                   if (ul != SPEC_CVAL (val->type).v_uint)
1053                     werror (W_INT_OVL);
1054                 }
1055               else /* signed result */
1056                 {
1057                   TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1058                                  (TYPE_WORD) floatFromVal (rval);
1059
1060                   if (l != SPEC_CVAL (val->type).v_int)
1061                     werror (W_INT_OVL);
1062                 }
1063             }
1064         }
1065     }
1066   return cheapestVal(val);
1067 }
1068
1069 /*------------------------------------------------------------------*/
1070 /* valDiv  - Divide   constants                                     */
1071 /*------------------------------------------------------------------*/
1072 value *
1073 valDiv (value * lval, value * rval)
1074 {
1075   value *val;
1076
1077   if (floatFromVal (rval) == 0)
1078     {
1079       werror (E_DIVIDE_BY_ZERO);
1080       return rval;
1081     }
1082
1083   /* create a new value */
1084   val = newValue ();
1085   val->type = val->etype = newLink(SPECIFIER);
1086   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1087                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1088   SPEC_SCLS (val->etype) = S_LITERAL;
1089   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1090   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1091
1092   if (IS_FLOAT (val->type))
1093     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1094   else
1095     {
1096       if (SPEC_LONG (val->type))
1097         {
1098           if (SPEC_USIGN (val->type))
1099             SPEC_CVAL (val->type).v_ulong = 
1100               (unsigned long) floatFromVal (lval) /
1101               (unsigned long) floatFromVal (rval);
1102           else
1103             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1104               (long) floatFromVal (rval);
1105         }
1106       else
1107         {
1108           if (SPEC_USIGN (val->type)) {
1109             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1110               (unsigned) floatFromVal (rval);
1111           } else {
1112             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1113               (int) floatFromVal (rval);
1114           }
1115         }
1116     }
1117   return cheapestVal(val);
1118 }
1119
1120 /*------------------------------------------------------------------*/
1121 /* valMod  - Modulus  constants                                     */
1122 /*------------------------------------------------------------------*/
1123 value *
1124 valMod (value * lval, value * rval)
1125 {
1126   value *val;
1127
1128   /* create a new value */
1129   val = newValue ();
1130   val->type = val->etype = newLink (SPECIFIER);
1131   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1132   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1133   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1134   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1135
1136   if (SPEC_LONG (val->type))
1137     {
1138       if (SPEC_USIGN (val->type))
1139         SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1140           (unsigned long) floatFromVal (rval);
1141       else
1142         SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1143           (unsigned long) floatFromVal (rval);
1144     }
1145   else
1146     {
1147       if (SPEC_USIGN (val->type)) {
1148         SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1149           (unsigned) floatFromVal (rval);
1150       } else {
1151         SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1152           (unsigned) floatFromVal (rval);
1153       }
1154     }
1155
1156   return cheapestVal(val);
1157 }
1158
1159 /*------------------------------------------------------------------*/
1160 /* valPlus - Addition constants                                     */
1161 /*------------------------------------------------------------------*/
1162 value *
1163 valPlus (value * lval, value * rval)
1164 {
1165   value *val;
1166
1167   /* create a new value */
1168   val = newValue ();
1169   val->type = val->etype = newLink (SPECIFIER);
1170   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1171                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1172   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1173   SPEC_USIGN (val->type) = 
1174     SPEC_USIGN (lval->etype) &&
1175     SPEC_USIGN (rval->etype) &&
1176     (floatFromVal(lval)+floatFromVal(rval))>=0;
1177     
1178   SPEC_LONG (val->type) = 1;
1179
1180   if (IS_FLOAT (val->type))
1181     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1182   else
1183     {
1184       if (SPEC_LONG (val->type))
1185         {
1186           if (SPEC_USIGN (val->type))
1187             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1188               (unsigned long) floatFromVal (rval);
1189           else
1190             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1191               (long) floatFromVal (rval);
1192         }
1193     }
1194   return cheapestVal(val);
1195 }
1196
1197 /*------------------------------------------------------------------*/
1198 /* valMinus - Addition constants                                    */
1199 /*------------------------------------------------------------------*/
1200 value *
1201 valMinus (value * lval, value * rval)
1202 {
1203   value *val;
1204
1205   /* create a new value */
1206   val = newValue ();
1207   val->type = val->etype = newLink (SPECIFIER);
1208   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1209                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1210   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1211   SPEC_USIGN (val->type) = 
1212     SPEC_USIGN (lval->etype) &&
1213     SPEC_USIGN (rval->etype) &&
1214     (floatFromVal(lval)-floatFromVal(rval))>=0;
1215
1216   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1217
1218   if (IS_FLOAT (val->type))
1219     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1220   else
1221     {
1222       if (SPEC_LONG (val->type))
1223         {
1224           if (SPEC_USIGN (val->type)) {
1225             SPEC_CVAL (val->type).v_ulong = 
1226               (unsigned long) floatFromVal (lval) -
1227               (unsigned long) floatFromVal (rval);
1228           } else {
1229             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1230               (long) floatFromVal (rval);
1231           }
1232         }
1233       else
1234         {
1235           if (SPEC_USIGN (val->type)) {
1236             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1237               (unsigned) floatFromVal (rval);
1238           } else {
1239             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - 
1240               (int) floatFromVal (rval);
1241           }
1242         }
1243     }
1244   return cheapestVal(val);
1245 }
1246
1247 /*------------------------------------------------------------------*/
1248 /* valShift - Shift left or right                                   */
1249 /*------------------------------------------------------------------*/
1250 value *
1251 valShift (value * lval, value * rval, int lr)
1252 {
1253   value *val;
1254
1255   /* create a new value */
1256   val = newValue ();
1257   val->type = val->etype = newIntLink ();
1258   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1259   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1260   SPEC_LONG (val->type) = 1;
1261
1262   if (SPEC_LONG (val->type))
1263     {
1264       if (SPEC_USIGN (val->type))
1265         SPEC_CVAL (val->type).v_ulong = lr ? 
1266           (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1267           (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1268       else
1269         SPEC_CVAL (val->type).v_long = lr ?
1270           (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1271           (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1272     }
1273
1274   return cheapestVal(val);
1275 }
1276
1277 /*------------------------------------------------------------------*/
1278 /* valCompare- Compares two literal                                 */
1279 /*------------------------------------------------------------------*/
1280 value *
1281 valCompare (value * lval, value * rval, int ctype)
1282 {
1283   value *val;
1284
1285   /* create a new value */
1286   val = newValue ();
1287   val->type = val->etype = newCharLink ();
1288   val->type->class = SPECIFIER;
1289   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1290   SPEC_USIGN (val->type) = 1;
1291   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1292
1293   switch (ctype)
1294     {
1295     case '<':
1296       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1297       break;
1298
1299     case '>':
1300       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1301       break;
1302
1303     case LE_OP:
1304       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1305       break;
1306
1307     case GE_OP:
1308       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1309       break;
1310
1311     case EQ_OP:
1312       SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1313       break;
1314
1315     case NE_OP:
1316       SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1317       break;
1318
1319     }
1320
1321   return val;
1322 }
1323
1324 /*------------------------------------------------------------------*/
1325 /* valBitwise - Bitwise operation                                   */
1326 /*------------------------------------------------------------------*/
1327 value *
1328 valBitwise (value * lval, value * rval, int op)
1329 {
1330   value *val;
1331
1332   /* create a new value */
1333   val = newValue ();
1334   val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1335                              rval->type : lval->type);
1336   val->etype = getSpec (val->type);
1337
1338   switch (op)
1339     {
1340     case '&':
1341       if (SPEC_LONG (val->type))
1342         {
1343           if (SPEC_USIGN (val->type))
1344             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1345               (unsigned long) floatFromVal (rval);
1346           else
1347             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1348               (long) floatFromVal (rval);
1349         }
1350       else
1351         {
1352           if (SPEC_USIGN (val->type))
1353             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1354               (unsigned) floatFromVal (rval);
1355           else
1356             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1357         }
1358       break;
1359
1360     case '|':
1361       if (SPEC_LONG (val->type))
1362         {
1363           if (SPEC_USIGN (val->type))
1364             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1365               (unsigned long) floatFromVal (rval);
1366           else
1367             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1368               (long) floatFromVal (rval);
1369         }
1370       else
1371         {
1372           if (SPEC_USIGN (val->type))
1373             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1374               (unsigned) floatFromVal (rval);
1375           else
1376             SPEC_CVAL (val->type).v_int =
1377               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1378         }
1379
1380       break;
1381
1382     case '^':
1383       if (SPEC_LONG (val->type))
1384         {
1385           if (SPEC_USIGN (val->type))
1386             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1387               (unsigned long) floatFromVal (rval);
1388           else
1389             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1390               (long) floatFromVal (rval);
1391         }
1392       else
1393         {
1394           if (SPEC_USIGN (val->type))
1395             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1396               (unsigned) floatFromVal (rval);
1397           else
1398             SPEC_CVAL (val->type).v_int =
1399               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1400         }
1401       break;
1402     }
1403
1404   return cheapestVal(val);
1405 }
1406
1407 /*------------------------------------------------------------------*/
1408 /* valAndOr   - Generates code for and / or operation               */
1409 /*------------------------------------------------------------------*/
1410 value *
1411 valLogicAndOr (value * lval, value * rval, int op)
1412 {
1413   value *val;
1414
1415   /* create a new value */
1416   val = newValue ();
1417   val->type = val->etype = newCharLink ();
1418   val->type->class = SPECIFIER;
1419   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1420   SPEC_USIGN (val->type) = 0;
1421
1422   switch (op)
1423     {
1424     case AND_OP:
1425       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1426       break;
1427
1428     case OR_OP:
1429       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1430       break;
1431     }
1432
1433
1434   return val;
1435 }
1436
1437 /*------------------------------------------------------------------*/
1438 /* valCastLiteral - casts a literal value to another type           */
1439 /*------------------------------------------------------------------*/
1440 value *
1441 valCastLiteral (sym_link * dtype, double fval)
1442 {
1443   value *val;
1444
1445   if (!dtype)
1446     return NULL;
1447
1448   val = newValue ();
1449   val->etype = getSpec (val->type = copyLinkChain (dtype));
1450   SPEC_SCLS (val->etype) = S_LITERAL;
1451   /* if it is not a specifier then we can assume that */
1452   /* it will be an unsigned long                      */
1453   if (!IS_SPEC (val->type)) {
1454       SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1455       return val;
1456   }
1457
1458   if (SPEC_NOUN (val->etype) == V_FLOAT)
1459       SPEC_CVAL (val->etype).v_float = fval;
1460   else {
1461       unsigned long l = (unsigned long)fval;
1462       if (SPEC_LONG (val->etype)) {
1463           if (SPEC_USIGN (val->etype))
1464               SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1465           else
1466               SPEC_CVAL (val->etype).v_long = (long) l;
1467       } else {
1468           if (SPEC_USIGN (val->etype))
1469               SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1470           else
1471               SPEC_CVAL (val->etype).v_int = (short)l;
1472       }
1473   }
1474   return val;
1475 }
1476
1477 /*------------------------------------------------------------------*/
1478 /* getNelements - determines # of elements from init list           */
1479 /*------------------------------------------------------------------*/
1480 int 
1481 getNelements (sym_link * type, initList * ilist)
1482 {
1483   int i;
1484
1485   if (!ilist)
1486     return 0;
1487
1488   if (ilist->type == INIT_DEEP)
1489     ilist = ilist->init.deep;
1490
1491   /* if type is a character array and there is only one
1492      (string) initialiser then get the length of the string */
1493   if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1494     {
1495       ast *iast = ilist->init.node;
1496       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1497       if (!v)
1498         {
1499           werror (E_CONST_EXPECTED);
1500           return 0;
1501         }
1502
1503       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1504         // yep, it's a string
1505         {
1506           return DCL_ELEM (v->type);
1507         }
1508     }
1509
1510   i = 0;
1511   while (ilist)
1512     {
1513       i++;
1514       ilist = ilist->next;
1515     }
1516   return i;
1517 }
1518
1519 /*-----------------------------------------------------------------*/
1520 /* valForArray - returns a value with name of array index          */
1521 /*-----------------------------------------------------------------*/
1522 value *
1523 valForArray (ast * arrExpr)
1524 {
1525   value *val, *lval = NULL;
1526   char buffer[128];
1527   int size = getSize (arrExpr->left->ftype->next);
1528   /* if the right or left is an array
1529      resolve it first */
1530   if (IS_AST_OP (arrExpr->left))
1531     {
1532       if (arrExpr->left->opval.op == '[')
1533         lval = valForArray (arrExpr->left);
1534       else if (arrExpr->left->opval.op == '.')
1535         lval = valForStructElem (arrExpr->left->left,
1536                                  arrExpr->left->right);
1537       else if (arrExpr->left->opval.op == PTR_OP &&
1538                IS_ADDRESS_OF_OP (arrExpr->left->left))
1539         lval = valForStructElem (arrExpr->left->left->left,
1540                                  arrExpr->left->right);
1541       else
1542         return NULL;
1543
1544     }
1545   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1546     return NULL;
1547
1548   if (!IS_AST_LIT_VALUE (arrExpr->right))
1549     return NULL;
1550
1551   val = newValue ();
1552   if (!lval)
1553     {
1554         SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1555     }
1556   else
1557     {
1558         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1559     }
1560
1561   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1562            (int) AST_LIT_VALUE (arrExpr->right) * size);
1563
1564   val->type = newLink (DECLARATOR);
1565   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1566     {
1567       DCL_TYPE (val->type) = CPOINTER;
1568       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1569     }
1570   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1571     DCL_TYPE (val->type) = FPOINTER;
1572   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1573     DCL_TYPE (val->type) = PPOINTER;
1574   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1575     DCL_TYPE (val->type) = IPOINTER;
1576   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1577     DCL_TYPE (val->type) = EEPPOINTER;
1578   else
1579     DCL_TYPE (val->type) = POINTER;
1580   val->type->next = arrExpr->left->ftype;
1581   val->etype = getSpec (val->type);
1582   return val;
1583 }
1584
1585 /*-----------------------------------------------------------------*/
1586 /* valForStructElem - returns value with name of struct element    */
1587 /*-----------------------------------------------------------------*/
1588 value *
1589 valForStructElem (ast * structT, ast * elemT)
1590 {
1591   value *val, *lval = NULL;
1592   char buffer[128];
1593   symbol *sym;
1594
1595   /* left could be furthur derefed */
1596   if (IS_AST_OP (structT))
1597     {
1598       if (structT->opval.op == '[')
1599         lval = valForArray (structT);
1600       else if (structT->opval.op == '.')
1601         lval = valForStructElem (structT->left, structT->right);
1602       else if (structT->opval.op == PTR_OP &&
1603                IS_ADDRESS_OF_OP (structT->left))
1604         lval = valForStructElem (structT->left->left,
1605                                  structT->right);
1606       else
1607         return NULL;
1608     }
1609
1610   if (!IS_AST_SYM_VALUE (elemT))
1611     return NULL;
1612
1613   if (!IS_STRUCT (structT->etype))
1614     return NULL;
1615
1616   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1617                                AST_SYMBOL (elemT))) == NULL)
1618     {
1619       return NULL;
1620     }
1621
1622   val = newValue ();
1623   if (!lval)
1624     {
1625         SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1626     }
1627   else
1628     {
1629         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1630     }
1631
1632   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1633            (int) sym->offset);
1634
1635   val->type = newLink (DECLARATOR);
1636   if (SPEC_SCLS (structT->etype) == S_CODE)
1637     {
1638       DCL_TYPE (val->type) = CPOINTER;
1639       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1640     }
1641   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1642     DCL_TYPE (val->type) = FPOINTER;
1643   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1644     DCL_TYPE (val->type) = PPOINTER;
1645   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1646     DCL_TYPE (val->type) = IPOINTER;
1647   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1648     DCL_TYPE (val->type) = EEPPOINTER;
1649   else
1650     DCL_TYPE (val->type) = POINTER;
1651   val->type->next = sym->type;
1652   val->etype = getSpec (val->type);
1653   return val;
1654 }
1655
1656 /*-----------------------------------------------------------------*/
1657 /* valForCastAggr - will return value for a cast of an aggregate   */
1658 /*                  plus minus a constant                          */
1659 /*-----------------------------------------------------------------*/
1660 value *
1661 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1662 {
1663   value *val;
1664
1665   if (!IS_AST_SYM_VALUE (aexpr))
1666     return NULL;
1667   if (!IS_AST_LIT_VALUE (cnst))
1668     return NULL;
1669
1670   val = newValue ();
1671
1672   SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1673            AST_SYMBOL (aexpr)->rname, op,
1674            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1675
1676   val->type = type;
1677   val->etype = getSpec (val->type);
1678   return val;
1679 }
1680
1681 /*-----------------------------------------------------------------*/
1682 /* valForCastAggr - will return value for a cast of an aggregate   */
1683 /*                  with no constant                               */
1684 /*-----------------------------------------------------------------*/
1685 value *
1686 valForCastArr (ast * aexpr, sym_link * type)
1687 {
1688   value *val;
1689
1690   if (!IS_AST_SYM_VALUE (aexpr))
1691     return NULL;
1692
1693   val = newValue ();
1694
1695   SNPRINTF (val->name, sizeof(val->name), "(%s)",
1696            AST_SYMBOL (aexpr)->rname);
1697
1698   val->type = type;
1699   val->etype = getSpec (val->type);
1700   return val;
1701 }