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