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