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