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