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