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