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