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