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