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