86de5525be63e892b658735dfee21d855529e1d0
[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_USIGN (val->etype))
893     return (double) SPEC_CVAL (val->etype).v_uint;
894   else
895     return (double) SPEC_CVAL (val->etype).v_int;
896 }
897
898
899 /*------------------------------------------------------------------*/
900 /* valUnaryPM - does the unary +/- operation on a constant          */
901 /*------------------------------------------------------------------*/
902 value *
903 valUnaryPM (value * val)
904 {
905   /* depending on type */
906   if (SPEC_NOUN (val->etype) == V_FLOAT)
907     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
908   else
909     {
910       if (SPEC_LONG (val->etype))
911         {
912           if (SPEC_USIGN (val->etype))
913             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
914           else
915             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
916         }
917       else
918         {
919           if (SPEC_USIGN (val->etype))
920             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
921           else
922             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
923         }
924     }
925   // -(unsigned 3) now really is signed
926   SPEC_USIGN(val->etype)=0;
927   return val;
928 }
929
930 /*------------------------------------------------------------------*/
931 /* valueComplement - complements a constant                         */
932 /*------------------------------------------------------------------*/
933 value *
934 valComplement (value * val)
935 {
936   /* depending on type */
937   if (SPEC_LONG (val->etype))
938     {
939       if (SPEC_USIGN (val->etype))
940         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
941       else
942         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
943     }
944   else
945     {
946       if (SPEC_USIGN (val->etype))
947         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
948       else
949         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
950     }
951   return val;
952 }
953
954 /*------------------------------------------------------------------*/
955 /* valueNot - complements a constant                                */
956 /*------------------------------------------------------------------*/
957 value *
958 valNot (value * val)
959 {
960   /* depending on type */
961   if (SPEC_LONG (val->etype))
962     {
963       if (SPEC_USIGN (val->etype))
964         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
965       else
966         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
967     }
968   else
969     {
970       if (SPEC_USIGN (val->etype))
971         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
972       else
973         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
974     }
975   return val;
976 }
977
978 /*------------------------------------------------------------------*/
979 /* valMult - multiply constants                                     */
980 /*------------------------------------------------------------------*/
981 value *
982 valMult (value * lval, value * rval)
983 {
984   value *val;
985
986   /* create a new value */
987   val = newValue ();
988   val->type = val->etype = newLink ();
989   val->type->class = SPECIFIER;
990   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
991                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
992   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
993   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
994   SPEC_LONG (val->type) = 1;
995
996   if (IS_FLOAT (val->type))
997     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
998   else
999     {
1000       if (SPEC_LONG (val->type))
1001         {
1002           if (SPEC_USIGN (val->type))
1003             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1004               (unsigned long) floatFromVal (rval);
1005           else
1006             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1007               (long) floatFromVal (rval);
1008         }
1009     }
1010   return cheapestVal(val);
1011 }
1012
1013 /*------------------------------------------------------------------*/
1014 /* valDiv  - Divide   constants                                     */
1015 /*------------------------------------------------------------------*/
1016 value *
1017 valDiv (value * lval, value * rval)
1018 {
1019   value *val;
1020
1021   if (floatFromVal (rval) == 0)
1022     {
1023       werror (E_DIVIDE_BY_ZERO);
1024       return rval;
1025     }
1026
1027   /* create a new value */
1028   val = newValue ();
1029   val->type = val->etype = newLink();
1030   val->type->class = SPECIFIER;
1031   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1032                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1033   SPEC_SCLS (val->etype) = S_LITERAL;
1034   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1035   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1036
1037   if (IS_FLOAT (val->type))
1038     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1039   else
1040     {
1041       if (SPEC_LONG (val->type))
1042         {
1043           if (SPEC_USIGN (val->type))
1044             SPEC_CVAL (val->type).v_ulong = 
1045               (unsigned long) floatFromVal (lval) /
1046               (unsigned long) floatFromVal (rval);
1047           else
1048             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1049               (long) floatFromVal (rval);
1050         }
1051       else
1052         {
1053           if (SPEC_USIGN (val->type)) {
1054             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1055               (unsigned) floatFromVal (rval);
1056           } else {
1057             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1058               (int) floatFromVal (rval);
1059           }
1060         }
1061     }
1062   return cheapestVal(val);
1063 }
1064
1065 /*------------------------------------------------------------------*/
1066 /* valMod  - Modulus  constants                                     */
1067 /*------------------------------------------------------------------*/
1068 value *
1069 valMod (value * lval, value * rval)
1070 {
1071   value *val;
1072
1073   /* create a new value */
1074   val = newValue ();
1075   val->type = val->etype = newLink ();
1076   val->type->class = SPECIFIER;
1077   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1078   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1079   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1080   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1081
1082   if (SPEC_LONG (val->type))
1083     {
1084       if (SPEC_USIGN (val->type))
1085         SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1086           (unsigned long) floatFromVal (rval);
1087       else
1088         SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1089           (unsigned long) floatFromVal (rval);
1090     }
1091   else
1092     {
1093       if (SPEC_USIGN (val->type)) {
1094         SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1095           (unsigned) floatFromVal (rval);
1096       } else {
1097         SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1098           (unsigned) floatFromVal (rval);
1099       }
1100     }
1101
1102   return cheapestVal(val);
1103 }
1104
1105 /*------------------------------------------------------------------*/
1106 /* valPlus - Addition constants                                     */
1107 /*------------------------------------------------------------------*/
1108 value *
1109 valPlus (value * lval, value * rval)
1110 {
1111   value *val;
1112
1113   /* create a new value */
1114   val = newValue ();
1115   val->type = val->etype = newLink ();
1116   val->type->class = SPECIFIER;
1117   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1118                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1119   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1120   SPEC_USIGN (val->type) = 
1121     SPEC_USIGN (lval->etype) &&
1122     SPEC_USIGN (rval->etype) &&
1123     (floatFromVal(lval)+floatFromVal(rval))>=0;
1124     
1125   SPEC_LONG (val->type) = 1;
1126
1127   if (IS_FLOAT (val->type))
1128     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1129   else
1130     {
1131       if (SPEC_LONG (val->type))
1132         {
1133           if (SPEC_USIGN (val->type))
1134             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1135               (unsigned long) floatFromVal (rval);
1136           else
1137             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1138               (long) floatFromVal (rval);
1139         }
1140     }
1141   return cheapestVal(val);
1142 }
1143
1144 /*------------------------------------------------------------------*/
1145 /* valMinus - Addition constants                                    */
1146 /*------------------------------------------------------------------*/
1147 value *
1148 valMinus (value * lval, value * rval)
1149 {
1150   value *val;
1151
1152   /* create a new value */
1153   val = newValue ();
1154   val->type = val->etype = newLink ();
1155   val->type->class = SPECIFIER;
1156   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1157                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1158   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1159   SPEC_USIGN (val->type) = 
1160     SPEC_USIGN (lval->etype) &&
1161     SPEC_USIGN (rval->etype) &&
1162     (floatFromVal(lval)-floatFromVal(rval))>=0;
1163
1164   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1165
1166   if (IS_FLOAT (val->type))
1167     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1168   else
1169     {
1170       if (SPEC_LONG (val->type))
1171         {
1172           if (SPEC_USIGN (val->type)) {
1173             SPEC_CVAL (val->type).v_ulong = 
1174               (unsigned long) floatFromVal (lval) -
1175               (unsigned long) floatFromVal (rval);
1176           } else {
1177             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1178               (long) floatFromVal (rval);
1179           }
1180         }
1181       else
1182         {
1183           if (SPEC_USIGN (val->type)) {
1184             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1185               (unsigned) floatFromVal (rval);
1186           } else {
1187             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - 
1188               (int) floatFromVal (rval);
1189           }
1190         }
1191     }
1192   return cheapestVal(val);
1193 }
1194
1195 /*------------------------------------------------------------------*/
1196 /* valShift - Shift left or right                                   */
1197 /*------------------------------------------------------------------*/
1198 value *
1199 valShift (value * lval, value * rval, int lr)
1200 {
1201   value *val;
1202
1203   /* create a new value */
1204   val = newValue ();
1205   val->type = val->etype = newIntLink ();
1206   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1207   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1208   SPEC_LONG (val->type) = 1;
1209
1210   if (SPEC_LONG (val->type))
1211     {
1212       if (SPEC_USIGN (val->type))
1213         SPEC_CVAL (val->type).v_ulong = lr ? 
1214           (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1215           (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1216       else
1217         SPEC_CVAL (val->type).v_long = lr ?
1218           (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1219           (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1220     }
1221
1222   return cheapestVal(val);
1223 }
1224
1225 /*------------------------------------------------------------------*/
1226 /* valCompare- Compares two literal                                 */
1227 /*------------------------------------------------------------------*/
1228 value *
1229 valCompare (value * lval, value * rval, int ctype)
1230 {
1231   value *val;
1232
1233   /* create a new value */
1234   val = newValue ();
1235   val->type = val->etype = newCharLink ();
1236   val->type->class = SPECIFIER;
1237   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1238   SPEC_USIGN (val->type) = 1;
1239   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1240
1241   switch (ctype)
1242     {
1243     case '<':
1244       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1245       break;
1246
1247     case '>':
1248       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1249       break;
1250
1251     case LE_OP:
1252       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1253       break;
1254
1255     case GE_OP:
1256       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1257       break;
1258
1259     case EQ_OP:
1260       SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1261       break;
1262
1263     case NE_OP:
1264       SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1265       break;
1266
1267     }
1268
1269   return val;
1270 }
1271
1272 /*------------------------------------------------------------------*/
1273 /* valBitwise - Bitwise operation                                   */
1274 /*------------------------------------------------------------------*/
1275 value *
1276 valBitwise (value * lval, value * rval, int op)
1277 {
1278   value *val;
1279
1280   /* create a new value */
1281   val = newValue ();
1282   val->type = copyLinkChain (lval->type);
1283   val->etype = getSpec (val->type);
1284
1285   switch (op)
1286     {
1287     case '&':
1288       if (SPEC_LONG (val->type))
1289         {
1290           if (SPEC_USIGN (val->type))
1291             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1292               (unsigned long) floatFromVal (rval);
1293           else
1294             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1295               (long) floatFromVal (rval);
1296         }
1297       else
1298         {
1299           if (SPEC_USIGN (val->type))
1300             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1301               (unsigned) floatFromVal (rval);
1302           else
1303             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1304         }
1305       break;
1306
1307     case '|':
1308       if (SPEC_LONG (val->type))
1309         {
1310           if (SPEC_USIGN (val->type))
1311             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1312               (unsigned long) floatFromVal (rval);
1313           else
1314             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1315               (long) floatFromVal (rval);
1316         }
1317       else
1318         {
1319           if (SPEC_USIGN (val->type))
1320             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1321               (unsigned) floatFromVal (rval);
1322           else
1323             SPEC_CVAL (val->type).v_int =
1324               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1325         }
1326
1327       break;
1328
1329     case '^':
1330       if (SPEC_LONG (val->type))
1331         {
1332           if (SPEC_USIGN (val->type))
1333             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1334               (unsigned long) floatFromVal (rval);
1335           else
1336             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1337               (long) floatFromVal (rval);
1338         }
1339       else
1340         {
1341           if (SPEC_USIGN (val->type))
1342             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1343               (unsigned) floatFromVal (rval);
1344           else
1345             SPEC_CVAL (val->type).v_int =
1346               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1347         }
1348       break;
1349     }
1350
1351   return cheapestVal(val);
1352 }
1353
1354 /*------------------------------------------------------------------*/
1355 /* valAndOr   - Generates code for and / or operation               */
1356 /*------------------------------------------------------------------*/
1357 value *
1358 valLogicAndOr (value * lval, value * rval, int op)
1359 {
1360   value *val;
1361
1362   /* create a new value */
1363   val = newValue ();
1364   val->type = val->etype = newCharLink ();
1365   val->type->class = SPECIFIER;
1366   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1367   SPEC_USIGN (val->type) = 0;
1368
1369   switch (op)
1370     {
1371     case AND_OP:
1372       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1373       break;
1374
1375     case OR_OP:
1376       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1377       break;
1378     }
1379
1380
1381   return val;
1382 }
1383
1384 /*------------------------------------------------------------------*/
1385 /* valCastLiteral - casts a literal value to another type           */
1386 /*------------------------------------------------------------------*/
1387 value *
1388 valCastLiteral (sym_link * dtype, double fval)
1389 {
1390   value *val;
1391
1392   if (!dtype)
1393     return NULL;
1394
1395   val = newValue ();
1396   val->etype = getSpec (val->type = copyLinkChain (dtype));
1397   SPEC_SCLS (val->etype) = S_LITERAL;
1398   /* if it is not a specifier then we can assume that */
1399   /* it will be an unsigned long                      */
1400   if (!IS_SPEC (val->type)) {
1401       SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1402       return val;
1403   }
1404
1405   if (SPEC_NOUN (val->etype) == V_FLOAT)
1406       SPEC_CVAL (val->etype).v_float = fval;
1407   else {
1408       unsigned long l = fval;
1409       if (SPEC_LONG (val->etype)) {
1410           if (SPEC_USIGN (val->etype))
1411               SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1412           else
1413               SPEC_CVAL (val->etype).v_long = (long) l;
1414       } else {
1415           if (SPEC_USIGN (val->etype))
1416               SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1417           else
1418               SPEC_CVAL (val->etype).v_int = (short)l;
1419       }
1420   }
1421   return val;
1422 }
1423
1424 /*------------------------------------------------------------------*/
1425 /* getNelements - determines # of elements from init list           */
1426 /*------------------------------------------------------------------*/
1427 int 
1428 getNelements (sym_link * type, initList * ilist)
1429 {
1430   sym_link *etype = getSpec (type);
1431   int i;
1432
1433   if (!ilist)
1434     return 0;
1435
1436   if (ilist->type == INIT_DEEP)
1437     ilist = ilist->init.deep;
1438
1439   /* if type is a character array and there is only one
1440      (string) initialiser then get the length of the string */
1441   if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1442     {
1443       ast *iast = ilist->init.node;
1444       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1445       if (!v)
1446         {
1447           werror (W_INIT_WRONG);
1448           return 0;
1449         }
1450
1451       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1452         // yep, it's a string
1453         {
1454           return DCL_ELEM (v->type);
1455         }
1456     }
1457
1458   i = 0;
1459   while (ilist)
1460     {
1461       i++;
1462       ilist = ilist->next;
1463     }
1464
1465   return i;
1466 }
1467
1468 /*-----------------------------------------------------------------*/
1469 /* valForArray - returns a value with name of array index          */
1470 /*-----------------------------------------------------------------*/
1471 value *
1472 valForArray (ast * arrExpr)
1473 {
1474   value *val, *lval = NULL;
1475   char buffer[128];
1476   int size = getSize (arrExpr->left->ftype->next);
1477   /* if the right or left is an array
1478      resolve it first */
1479   if (IS_AST_OP (arrExpr->left))
1480     {
1481       if (arrExpr->left->opval.op == '[')
1482         lval = valForArray (arrExpr->left);
1483       else if (arrExpr->left->opval.op == '.')
1484         lval = valForStructElem (arrExpr->left->left,
1485                                  arrExpr->left->right);
1486       else if (arrExpr->left->opval.op == PTR_OP &&
1487                IS_ADDRESS_OF_OP (arrExpr->left->left))
1488         lval = valForStructElem (arrExpr->left->left->left,
1489                                  arrExpr->left->right);
1490       else
1491         return NULL;
1492
1493     }
1494   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1495     return NULL;
1496
1497   if (!IS_AST_LIT_VALUE (arrExpr->right))
1498     return NULL;
1499
1500   val = newValue ();
1501   if (!lval)
1502     sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1503   else
1504     sprintf (buffer, "%s", lval->name);
1505
1506   sprintf (val->name, "(%s + %d)", buffer,
1507            (int) AST_LIT_VALUE (arrExpr->right) * size);
1508
1509   val->type = newLink ();
1510   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1511     {
1512       DCL_TYPE (val->type) = CPOINTER;
1513       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1514     }
1515   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1516     DCL_TYPE (val->type) = FPOINTER;
1517   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1518     DCL_TYPE (val->type) = PPOINTER;
1519   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1520     DCL_TYPE (val->type) = IPOINTER;
1521   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1522     DCL_TYPE (val->type) = EEPPOINTER;
1523   else
1524     DCL_TYPE (val->type) = POINTER;
1525   val->type->next = arrExpr->left->ftype;
1526   val->etype = getSpec (val->type);
1527   return val;
1528 }
1529
1530 /*-----------------------------------------------------------------*/
1531 /* valForStructElem - returns value with name of struct element    */
1532 /*-----------------------------------------------------------------*/
1533 value *
1534 valForStructElem (ast * structT, ast * elemT)
1535 {
1536   value *val, *lval = NULL;
1537   char buffer[128];
1538   symbol *sym;
1539
1540   /* left could be furthur derefed */
1541   if (IS_AST_OP (structT))
1542     {
1543       if (structT->opval.op == '[')
1544         lval = valForArray (structT);
1545       else if (structT->opval.op == '.')
1546         lval = valForStructElem (structT->left, structT->right);
1547       else if (structT->opval.op == PTR_OP &&
1548                IS_ADDRESS_OF_OP (structT->left))
1549         lval = valForStructElem (structT->left->left,
1550                                  structT->right);
1551       else
1552         return NULL;
1553     }
1554
1555   if (!IS_AST_SYM_VALUE (elemT))
1556     return NULL;
1557
1558   if (!IS_STRUCT (structT->etype))
1559     return NULL;
1560
1561   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1562                                AST_SYMBOL (elemT))) == NULL)
1563     {
1564       return NULL;
1565     }
1566
1567   val = newValue ();
1568   if (!lval)
1569     sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1570   else
1571     sprintf (buffer, "%s", lval->name);
1572
1573   sprintf (val->name, "(%s + %d)", buffer,
1574            (int) sym->offset);
1575
1576   val->type = newLink ();
1577   if (SPEC_SCLS (structT->etype) == S_CODE)
1578     {
1579       DCL_TYPE (val->type) = CPOINTER;
1580       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1581     }
1582   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1583     DCL_TYPE (val->type) = FPOINTER;
1584   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1585     DCL_TYPE (val->type) = PPOINTER;
1586   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1587     DCL_TYPE (val->type) = IPOINTER;
1588   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1589     DCL_TYPE (val->type) = EEPPOINTER;
1590   else
1591     DCL_TYPE (val->type) = POINTER;
1592   val->type->next = sym->type;
1593   val->etype = getSpec (val->type);
1594   return val;
1595 }
1596
1597 /*-----------------------------------------------------------------*/
1598 /* valForCastAggr - will return value for a cast of an aggregate   */
1599 /*                  plus minus a constant                          */
1600 /*-----------------------------------------------------------------*/
1601 value *
1602 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1603 {
1604   value *val;
1605
1606   if (!IS_AST_SYM_VALUE (aexpr))
1607     return NULL;
1608   if (!IS_AST_LIT_VALUE (cnst))
1609     return NULL;
1610
1611   val = newValue ();
1612
1613   sprintf (val->name, "(%s %c %d)",
1614            AST_SYMBOL (aexpr)->rname, op,
1615            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1616
1617   val->type = type;
1618   val->etype = getSpec (val->type);
1619   return val;
1620 }
1621
1622 /*-----------------------------------------------------------------*/
1623 /* valForCastAggr - will return value for a cast of an aggregate   */
1624 /*                  with no constant                               */
1625 /*-----------------------------------------------------------------*/
1626 value *
1627 valForCastArr (ast * aexpr, sym_link * type)
1628 {
1629   value *val;
1630
1631   if (!IS_AST_SYM_VALUE (aexpr))
1632     return NULL;
1633
1634   val = newValue ();
1635
1636   sprintf (val->name, "(%s)",
1637            AST_SYMBOL (aexpr)->rname);
1638
1639   val->type = type;
1640   val->etype = getSpec (val->type);
1641   return val;
1642 }