* src/SDCCast.c (decorateType): fixed bug introduced today
[fw/sdcc] / src / SDCCast.c
1 /*-------------------------------------------------------------------------
2   SDCCast.c - source file for parser support & all ast related routines
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
24
25 #include "common.h"
26
27 int currLineno = 0;
28 set *astList = NULL;
29 set *operKeyReset = NULL;
30 ast *staticAutos = NULL;
31 int labelKey = 1;
32
33 #define LRVAL(x) x->left->rvalue
34 #define RRVAL(x) x->right->rvalue
35 #define TRVAL(x) x->rvalue
36 #define LLVAL(x) x->left->lvalue
37 #define RLVAL(x) x->right->lvalue
38 #define TLVAL(x) x->lvalue
39 #define RTYPE(x) x->right->ftype
40 #define RETYPE(x) x->right->etype
41 #define LTYPE(x) x->left->ftype
42 #define LETYPE(x) x->left->etype
43 #define TTYPE(x) x->ftype
44 #define TETYPE(x) x->etype
45 #define ALLOCATE 1
46 #define DEALLOCATE 2
47
48 int noLineno = 0;
49 int noAlloc = 0;
50 symbol *currFunc=NULL;
51 static ast *createIval (ast *, sym_link *, initList *, ast *);
52 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
53 static ast *optimizeCompare (ast *);
54 ast *optimizeRRCRLC (ast *);
55 ast *optimizeSWAP (ast *);
56 ast *optimizeGetHbit (ast *);
57 ast *backPatchLabels (ast *, symbol *, symbol *);
58 void PA(ast *t);
59 int inInitMode = 0;
60 memmap *GcurMemmap=NULL;  /* points to the memmap that's currently active */
61 FILE *codeOutFile;
62 int 
63 ptt (ast * tree)
64 {
65   printTypeChain (tree->ftype, stdout);
66   return 0;
67 }
68
69
70 /*-----------------------------------------------------------------*/
71 /* newAst - creates a fresh node for an expression tree            */
72 /*-----------------------------------------------------------------*/
73 static ast *
74 newAst_ (unsigned type)
75 {
76   ast *ex;
77   static int oldLineno = 0;
78
79   ex = Safe_alloc ( sizeof (ast));
80
81   ex->type = type;
82   ex->lineno = (noLineno ? oldLineno : mylineno);
83   ex->filename = currFname;
84   ex->level = NestLevel;
85   ex->block = currBlockno;
86   ex->initMode = inInitMode;
87   ex->seqPoint = seqPointNo;
88   return ex;
89 }
90
91 ast *
92 newAst_VALUE (value * val)
93 {
94   ast *ex = newAst_ (EX_VALUE);
95   ex->opval.val = val;
96   return ex;
97 }
98
99 ast *
100 newAst_OP (unsigned op)
101 {
102   ast *ex = newAst_ (EX_OP);
103   ex->opval.op = op;
104   return ex;
105 }
106
107 ast *
108 newAst_LINK (sym_link * val)
109 {
110   ast *ex = newAst_ (EX_LINK);
111   ex->opval.lnk = val;
112   return ex;
113 }
114
115 /*-----------------------------------------------------------------*/
116 /* newNode - creates a new node                                    */
117 /*-----------------------------------------------------------------*/
118 ast *
119 newNode (long op, ast * left, ast * right)
120 {
121   ast *ex;
122
123   ex = newAst_OP (op);
124   ex->left = left;
125   ex->right = right;
126
127   return ex;
128 }
129
130 /*-----------------------------------------------------------------*/
131 /* newIfxNode - creates a new Ifx Node                             */
132 /*-----------------------------------------------------------------*/
133 ast *
134 newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
135 {
136   ast *ifxNode;
137
138   /* if this is a literal then we already know the result */
139   if (condAst->etype && IS_LITERAL (condAst->etype))
140     {
141       /* then depending on the expression value */
142       if (floatFromVal (condAst->opval.val))
143         ifxNode = newNode (GOTO,
144                            newAst_VALUE (symbolVal (trueLabel)),
145                            NULL);
146       else
147         ifxNode = newNode (GOTO,
148                            newAst_VALUE (symbolVal (falseLabel)),
149                            NULL);
150     }
151   else
152     {
153       ifxNode = newNode (IFX, condAst, NULL);
154       ifxNode->trueLabel = trueLabel;
155       ifxNode->falseLabel = falseLabel;
156     }
157
158   return ifxNode;
159 }
160
161 /*-----------------------------------------------------------------*/
162 /* copyAstValues - copies value portion of ast if needed     */
163 /*-----------------------------------------------------------------*/
164 void
165 copyAstValues (ast * dest, ast * src)
166 {
167   switch (src->opval.op)
168     {
169     case BLOCK:
170       dest->values.sym = copySymbolChain (src->values.sym);
171       break;
172
173     case SWITCH:
174       dest->values.switchVals.swVals =
175         copyValue (src->values.switchVals.swVals);
176       dest->values.switchVals.swDefault =
177         src->values.switchVals.swDefault;
178       dest->values.switchVals.swNum =
179         src->values.switchVals.swNum;
180       break;
181
182     case INLINEASM:
183       dest->values.inlineasm =  Safe_strdup(src->values.inlineasm);
184       break;
185
186     case ARRAYINIT:
187         dest->values.constlist = copyLiteralList(src->values.constlist);
188         break;
189
190     case FOR:
191       AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
192       AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
193       AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel));
194       AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel));
195       AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr));
196       AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr));
197       AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr));
198     }
199
200 }
201
202 /*-----------------------------------------------------------------*/
203 /* copyAst - makes a copy of a given astession                     */
204 /*-----------------------------------------------------------------*/
205 ast *
206 copyAst (ast * src)
207 {
208   ast *dest;
209
210   if (!src)
211     return NULL;
212
213   dest = Safe_alloc ( sizeof (ast));
214
215   dest->type = src->type;
216   dest->lineno = src->lineno;
217   dest->level = src->level;
218   dest->funcName = src->funcName;
219
220   if (src->ftype)
221     dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype));
222
223   /* if this is a leaf */
224   /* if value */
225   if (src->type == EX_VALUE)
226     {
227       dest->opval.val = copyValue (src->opval.val);
228       goto exit;
229     }
230
231   /* if link */
232   if (src->type == EX_LINK)
233     {
234       dest->opval.lnk = copyLinkChain (src->opval.lnk);
235       goto exit;
236     }
237
238   dest->opval.op = src->opval.op;
239
240   /* if this is a node that has special values */
241   copyAstValues (dest, src);
242
243   dest->trueLabel = copySymbol (src->trueLabel);
244   dest->falseLabel = copySymbol (src->falseLabel);
245   dest->left = copyAst (src->left);
246   dest->right = copyAst (src->right);
247 exit:
248   return dest;
249
250 }
251
252 /*-----------------------------------------------------------------*/
253 /* removeIncDecOps: remove for side effects in *_ASSIGN's          */
254 /*                  "*s++ += 3" -> "*s++ = *s++ + 3"               */
255 /*-----------------------------------------------------------------*/
256 ast *removeIncDecOps (ast * tree) {
257
258   // traverse the tree and remove inc/dec ops
259
260   if (!tree)
261     return NULL;
262
263   if (tree->type == EX_OP &&
264       (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
265     if (tree->left)
266       tree=tree->left;
267     else
268       tree=tree->right;
269   }
270
271   tree->left=removeIncDecOps(tree->left);
272   tree->right=removeIncDecOps(tree->right);
273
274  return tree;
275 }
276
277 /*-----------------------------------------------------------------*/
278 /* removePreIncDecOps: remove for side effects in *_ASSIGN's       */
279 /*                  "*++s += 3" -> "*++s = *++s + 3"               */
280 /*-----------------------------------------------------------------*/
281 ast *removePreIncDecOps (ast * tree) {
282
283   // traverse the tree and remove pre-inc/dec ops
284
285   if (!tree)
286     return NULL;
287
288   if (tree->type == EX_OP &&
289       (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
290     if (tree->right)
291       tree=tree->right;
292   }
293
294   tree->left=removePreIncDecOps(tree->left);
295   tree->right=removePreIncDecOps(tree->right);
296
297  return tree;
298 }
299
300 /*-----------------------------------------------------------------*/
301 /* removePostIncDecOps: remove for side effects in *_ASSIGN's      */
302 /*                  "*s++ += 3" -> "*s++ = *s++ + 3"               */
303 /*-----------------------------------------------------------------*/
304 ast *removePostIncDecOps (ast * tree) {
305
306   // traverse the tree and remove pre-inc/dec ops
307
308   if (!tree)
309     return NULL;
310
311   if (tree->type == EX_OP &&
312       (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
313     if (tree->left)
314       tree=tree->left;
315   }
316
317   tree->left=removePostIncDecOps(tree->left);
318   tree->right=removePostIncDecOps(tree->right);
319
320  return tree;
321 }
322
323 /*-----------------------------------------------------------------*/
324 /* hasSEFcalls - returns TRUE if tree has a function call          */
325 /*-----------------------------------------------------------------*/
326 bool
327 hasSEFcalls (ast * tree)
328 {
329   if (!tree)
330     return FALSE;
331
332   if (tree->type == EX_OP &&
333       (tree->opval.op == CALL ||
334        tree->opval.op == PCALL ||
335        tree->opval.op == '=' ||
336        tree->opval.op == INC_OP ||
337        tree->opval.op == DEC_OP))
338     return TRUE;
339
340   return (hasSEFcalls (tree->left) |
341           hasSEFcalls (tree->right));
342 }
343
344 /*-----------------------------------------------------------------*/
345 /* isAstEqual - compares two asts & returns 1 if they are equal    */
346 /*-----------------------------------------------------------------*/
347 static int
348 isAstEqual (ast * t1, ast * t2)
349 {
350   if (!t1 && !t2)
351     return 1;
352
353   if (!t1 || !t2)
354     return 0;
355
356   /* match type */
357   if (t1->type != t2->type)
358     return 0;
359
360   switch (t1->type)
361     {
362     case EX_OP:
363       if (t1->opval.op != t2->opval.op)
364         return 0;
365       return (isAstEqual (t1->left, t2->left) &&
366               isAstEqual (t1->right, t2->right));
367       break;
368
369     case EX_VALUE:
370       if (t1->opval.val->sym)
371         {
372           if (!t2->opval.val->sym)
373             return 0;
374           else
375             return isSymbolEqual (t1->opval.val->sym,
376                                   t2->opval.val->sym);
377         }
378       else
379         {
380           if (t2->opval.val->sym)
381             return 0;
382           else
383             return (floatFromVal (t1->opval.val) ==
384                     floatFromVal (t2->opval.val));
385         }
386       break;
387
388       /* only compare these two types */
389     default:
390       return 0;
391     }
392
393   return 0;
394 }
395
396 /*-----------------------------------------------------------------*/
397 /* resolveSymbols - resolve symbols from the symbol table          */
398 /*-----------------------------------------------------------------*/
399 ast *
400 resolveSymbols (ast * tree)
401 {
402   /* walk the entire tree and check for values */
403   /* with symbols if we find one then replace  */
404   /* symbol with that from the symbol table    */
405
406   if (tree == NULL)
407     return tree;
408
409 #if 0
410   /* print the line          */
411   /* if not block & function */
412   if (tree->type == EX_OP &&
413       (tree->opval.op != FUNCTION &&
414        tree->opval.op != BLOCK &&
415        tree->opval.op != NULLOP))
416     {
417       filename = tree->filename;
418       lineno = tree->lineno;
419     }
420 #endif
421
422   /* make sure we resolve the true & false labels for ifx */
423   if (tree->type == EX_OP && tree->opval.op == IFX)
424     {
425       symbol *csym;
426
427       if (tree->trueLabel)
428         {
429           if ((csym = findSym (LabelTab, tree->trueLabel,
430                                tree->trueLabel->name)))
431             tree->trueLabel = csym;
432           else
433             werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
434                       tree->trueLabel->name);
435         }
436
437       if (tree->falseLabel)
438         {
439           if ((csym = findSym (LabelTab,
440                                tree->falseLabel,
441                                tree->falseLabel->name)))
442             tree->falseLabel = csym;
443           else
444             werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
445                       tree->falseLabel->name);
446         }
447
448     }
449
450   /* if this is a label resolve it from the labelTab */
451   if (IS_AST_VALUE (tree) &&
452       tree->opval.val->sym &&
453       tree->opval.val->sym->islbl)
454     {
455
456       symbol *csym = findSym (LabelTab, tree->opval.val->sym,
457                               tree->opval.val->sym->name);
458
459       if (!csym)
460         werrorfl (tree->filename, tree->lineno, E_LABEL_UNDEF,
461                   tree->opval.val->sym->name);
462       else
463         tree->opval.val->sym = csym;
464
465       goto resolveChildren;
466     }
467
468   /* do only for leafs */
469   if (IS_AST_VALUE (tree) &&
470       tree->opval.val->sym &&
471       !tree->opval.val->sym->implicit)
472     {
473
474       symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym);
475
476       /* if found in the symbol table & they r not the same */
477       if (csym && tree->opval.val->sym != csym)
478         {
479           tree->opval.val->sym = csym;
480           tree->opval.val->type = csym->type;
481           tree->opval.val->etype = csym->etype;
482         }
483
484       /* if not found in the symbol table */
485       /* mark it as undefined assume it is */
486       /* an integer in data space         */
487       if (!csym && !tree->opval.val->sym->implicit)
488         {
489
490           /* if this is a function name then */
491           /* mark it as returning an int     */
492           if (tree->funcName)
493             {
494               tree->opval.val->sym->type = newLink (DECLARATOR);
495               DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
496               tree->opval.val->sym->type->next =
497                 tree->opval.val->sym->etype = newIntLink ();
498               tree->opval.val->etype = tree->opval.val->etype;
499               tree->opval.val->type = tree->opval.val->sym->type;
500               werrorfl (tree->filename, tree->lineno, W_IMPLICIT_FUNC,
501                         tree->opval.val->sym->name);
502               //tree->opval.val->sym->undefined = 1;
503               allocVariables (tree->opval.val->sym);
504             }
505           else
506             {
507               tree->opval.val->sym->undefined = 1;
508               tree->opval.val->type =
509                 tree->opval.val->etype = newIntLink ();
510               tree->opval.val->sym->type =
511                 tree->opval.val->sym->etype = newIntLink ();
512             }
513         }
514     }
515
516 resolveChildren:
517   resolveSymbols (tree->left);
518   resolveSymbols (tree->right);
519
520   return tree;
521 }
522
523 /*-----------------------------------------------------------------*/
524 /* setAstLineno - walks a ast tree & sets the line number          */
525 /*-----------------------------------------------------------------*/
526 int setAstLineno (ast * tree, int lineno)
527 {
528   if (!tree)
529     return 0;
530
531   tree->lineno = lineno;
532   setAstLineno (tree->left, lineno);
533   setAstLineno (tree->right, lineno);
534   return 0;
535 }
536
537 /*-----------------------------------------------------------------*/
538 /* funcOfType :- function of type with name                        */
539 /*-----------------------------------------------------------------*/
540 symbol *
541 funcOfType (char *name, sym_link * type, sym_link * argType,
542             int nArgs, int rent)
543 {
544   symbol *sym;
545   /* create the symbol */
546   sym = newSymbol (name, 0);
547
548   /* setup return value */
549   sym->type = newLink (DECLARATOR);
550   DCL_TYPE (sym->type) = FUNCTION;
551   sym->type->next = copyLinkChain (type);
552   sym->etype = getSpec (sym->type);
553   FUNC_ISREENT(sym->type) = rent ? 1 : 0;
554
555   /* if arguments required */
556   if (nArgs)
557     {
558       value *args;
559       args = FUNC_ARGS(sym->type) = newValue ();
560
561       while (nArgs--)
562         {
563           args->type = copyLinkChain (argType);
564           args->etype = getSpec (args->type);
565           SPEC_EXTR(args->etype)=1;
566           if (!nArgs)
567             break;
568           args = args->next = newValue ();
569         }
570     }
571
572   /* save it */
573   addSymChain (sym);
574   sym->cdef = 1;
575   allocVariables (sym);
576   return sym;
577
578 }
579
580 /*-----------------------------------------------------------------*/
581 /* funcOfTypeVarg :- function of type with name and argtype        */
582 /*-----------------------------------------------------------------*/
583 symbol *
584 funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
585 {
586   
587     symbol *sym;
588     int i ;
589     /* create the symbol */
590     sym = newSymbol (name, 0);
591     
592     /* setup return value */
593     sym->type = newLink (DECLARATOR);
594     DCL_TYPE (sym->type) = FUNCTION;
595     sym->type->next = typeFromStr(rtype);
596     sym->etype = getSpec (sym->type);
597     
598     /* if arguments required */
599     if (nArgs) {
600         value *args;
601         args = FUNC_ARGS(sym->type) = newValue ();
602         
603         for ( i = 0 ; i < nArgs ; i++ ) {
604             args->type = typeFromStr(atypes[i]);
605             args->etype = getSpec (args->type);
606             SPEC_EXTR(args->etype)=1;
607             if ((i + 1) == nArgs) break;
608             args = args->next = newValue ();
609         }
610     }
611
612     /* save it */
613     addSymChain (sym);
614     sym->cdef = 1;
615     allocVariables (sym);
616     return sym;
617
618 }
619
620 /*-----------------------------------------------------------------*/
621 /* reverseParms - will reverse a parameter tree                    */
622 /*-----------------------------------------------------------------*/
623 static void
624 reverseParms (ast * ptree)
625 {
626   ast *ttree;
627   if (!ptree)
628     return;
629
630   /* top down if we find a nonParm tree then quit */
631   if (ptree->type == EX_OP && ptree->opval.op == PARAM)
632     {
633       ttree = ptree->left;
634       ptree->left = ptree->right;
635       ptree->right = ttree;
636       reverseParms (ptree->left);
637       reverseParms (ptree->right);
638     }
639
640   return;
641 }
642
643 /*-----------------------------------------------------------------*/
644 /* processParms  - makes sure the parameters are okay and do some  */
645 /*                 processing with them                            */
646 /*-----------------------------------------------------------------*/
647 int 
648 processParms (ast * func,
649               value *defParm,
650               ast * actParm,
651               int *parmNumber, // unused, although updated
652               bool rightmost)
653 {
654   /* if none of them exist */
655   if (!defParm && !actParm)
656     return 0;
657
658   if (defParm) {
659     if (getenv("DEBUG_SANITY")) {
660       fprintf (stderr, "processParms: %s ", defParm->name);
661     }
662     /* make sure the type is complete and sane */
663     checkTypeSanity(defParm->etype, defParm->name);
664   }
665
666   /* if the function is being called via a pointer &   */
667   /* it has not been defined a reentrant then we cannot */
668   /* have parameters                                   */
669   if (func->type != EX_VALUE && !IFFUNC_ISREENT (func->ftype) && !options.stackAuto)
670     {
671       werror (W_NONRENT_ARGS);
672       return 1;
673     }
674
675   /* if defined parameters ended but actual parameters */
676   /* exist and this is not defined as a variable arg   */
677   if (!defParm && actParm && !IFFUNC_HASVARARGS(func->ftype))
678     {
679       //if (func->type==EX_VALUE && func->opval.val->sym->undefined)
680       //  return 1; /* Already gave them an undefined function error */
681       werror (E_TOO_MANY_PARMS);
682       return 1;
683     }
684
685   /* if defined parameters present but no actual parameters */
686   if (defParm && !actParm)
687     {
688       werror (E_TOO_FEW_PARMS);
689       return 1;
690     }
691
692   if (IS_VOID(actParm->ftype)) {
693     werror (E_VOID_VALUE_USED);
694     return 1;
695   }
696
697   /* If this is a varargs function... */
698   if (!defParm && actParm && IFFUNC_HASVARARGS(func->ftype))
699     {
700       ast *newType = NULL;
701       sym_link *ftype;
702
703       if (IS_CAST_OP (actParm)
704           || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
705         {
706           /* Parameter was explicitly typecast; don't touch it. */
707           return 0;
708         }
709
710       ftype = actParm->ftype;
711           
712       /* If it's a small integer, upcast to int. */
713       if (IS_INTEGRAL (ftype)
714           && (getSize (ftype) < (unsigned) INTSIZE))
715         {
716           if (IS_AST_OP(actParm) &&
717               (actParm->opval.op == LEFT_OP ||
718                actParm->opval.op == '*' ||
719                actParm->opval.op == '+' ||
720                actParm->opval.op == '-') &&
721               actParm->right) {
722             // we should cast an operand instead of the result
723             actParm->decorated = 0;
724             actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
725                                          actParm->left);
726             actParm = decorateType(actParm);
727           } else {
728             newType = newAst_LINK(INTTYPE);
729           }
730         }
731
732       if (IS_PTR(ftype) && !IS_GENPTR(ftype))
733         {
734           newType = newAst_LINK (copyLinkChain(ftype));
735           DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
736         }
737
738       if (IS_AGGREGATE (ftype))
739         {
740           newType = newAst_LINK (copyLinkChain (ftype));
741           DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer;
742         }
743       if (newType)
744         {
745           /* cast required; change this op to a cast. */
746           ast *parmCopy = decorateType(resolveSymbols (copyAst (actParm)));
747
748           actParm->type = EX_OP;
749           actParm->opval.op = CAST;
750           actParm->left = newType;
751           actParm->right = parmCopy;
752           decorateType (actParm);
753         }
754       else if (actParm->type == EX_OP && actParm->opval.op == PARAM)
755         {
756           return (processParms (func, NULL, actParm->left, parmNumber, FALSE) ||
757           processParms (func, NULL, actParm->right, parmNumber, rightmost));
758         }
759       return 0;
760     }
761
762   /* if defined parameters ended but actual has not & */
763   /* reentrant */
764   if (!defParm && actParm &&
765       (options.stackAuto || IFFUNC_ISREENT (func->ftype)))
766     return 0;
767
768   resolveSymbols (actParm);
769   /* if this is a PARAM node then match left & right */
770   if (actParm->type == EX_OP && actParm->opval.op == PARAM)
771     {
772       return (processParms (func, defParm, actParm->left, parmNumber, FALSE) ||
773               processParms (func, defParm->next, actParm->right, parmNumber, rightmost));
774     }
775   else
776     {
777       /* If we have found a value node by following only right-hand links,
778        * then we know that there are no more values after us.
779        *
780        * Therefore, if there are more defined parameters, the caller didn't
781        * supply enough.
782        */
783       if (rightmost && defParm->next)
784         {
785           werror (E_TOO_FEW_PARMS);
786           return 1;
787         }
788     }
789
790   /* the parameter type must be at least castable */
791   if (compareType (defParm->type, actParm->ftype) == 0) {
792     werror (E_INCOMPAT_TYPES);
793     printFromToType (actParm->ftype, defParm->type);
794     return 1;
795   }
796
797   /* if the parameter is castable then add the cast */
798   if (compareType (defParm->type, actParm->ftype) < 0)
799     {
800       ast *pTree = decorateType(resolveSymbols (copyAst (actParm)));
801
802       /* now change the current one to a cast */
803       actParm->type = EX_OP;
804       actParm->opval.op = CAST;
805       actParm->left = newAst_LINK (defParm->type);
806       actParm->right = pTree;
807       actParm->etype = defParm->etype;
808       actParm->ftype = defParm->type;
809       actParm->decorated=0; /* force typechecking */
810       decorateType (actParm);
811     }
812
813   /* make a copy and change the regparm type to the defined parm */
814   actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype));
815   SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype);
816   SPEC_ARGREG  (actParm->etype) = SPEC_ARGREG (defParm->etype);
817   (*parmNumber)++;
818   return 0;
819 }
820 /*-----------------------------------------------------------------*/
821 /* createIvalType - generates ival for basic types                 */
822 /*-----------------------------------------------------------------*/
823 static ast *
824 createIvalType (ast * sym, sym_link * type, initList * ilist)
825 {
826   ast *iExpr;
827
828   /* if initList is deep */
829   if (ilist->type == INIT_DEEP)
830     ilist = ilist->init.deep;
831
832   iExpr = decorateType (resolveSymbols (list2expr (ilist)));
833   return decorateType (newNode ('=', sym, iExpr));
834 }
835
836 /*-----------------------------------------------------------------*/
837 /* createIvalStruct - generates initial value for structures       */
838 /*-----------------------------------------------------------------*/
839 static ast *
840 createIvalStruct (ast * sym, sym_link * type, initList * ilist)
841 {
842   ast *rast = NULL;
843   ast *lAst;
844   symbol *sflds;
845   initList *iloop;
846
847   sflds = SPEC_STRUCT (type)->fields;
848   if (ilist->type != INIT_DEEP)
849     {
850       werror (E_INIT_STRUCT, "");
851       return NULL;
852     }
853
854   iloop = ilist->init.deep;
855
856   for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
857     {
858       /* if we have come to end */
859       if (!iloop)
860         break;
861       sflds->implicit = 1;
862       lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds)));
863       lAst = decorateType (resolveSymbols (lAst));
864       rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast)));
865     }
866
867   if (iloop) {
868     werrorfl (filename, sym->opval.val->sym->lineDef,
869               W_EXCESS_INITIALIZERS, "struct", 
870               sym->opval.val->sym->name);
871   }
872
873   return rast;
874 }
875
876
877 /*-----------------------------------------------------------------*/
878 /* createIvalArray - generates code for array initialization       */
879 /*-----------------------------------------------------------------*/
880 static ast *
881 createIvalArray (ast * sym, sym_link * type, initList * ilist)
882 {
883   ast *rast = NULL;
884   initList *iloop;
885   int lcnt = 0, size = 0;
886   literalList *literalL;
887
888   /* take care of the special   case  */
889   /* array of characters can be init  */
890   /* by a string                      */
891   if (IS_CHAR (type->next))
892     if ((rast = createIvalCharPtr (sym,
893                                    type,
894                         decorateType (resolveSymbols (list2expr (ilist))))))
895
896       return decorateType (resolveSymbols (rast));
897
898     /* not the special case             */
899     if (ilist->type != INIT_DEEP)
900     {
901         werror (E_INIT_STRUCT, "");
902         return NULL;
903     }
904
905     iloop = ilist->init.deep;
906     lcnt = DCL_ELEM (type);
907
908     if (port->arrayInitializerSuppported && convertIListToConstList(ilist, &literalL))
909     {
910         ast *aSym;
911
912         aSym = decorateType (resolveSymbols(sym));
913         
914         rast = newNode(ARRAYINIT, aSym, NULL);
915         rast->values.constlist = literalL;
916         
917         // Make sure size is set to length of initializer list.
918         while (iloop)
919         {
920             size++;
921             iloop = iloop->next;
922         }
923         
924         if (lcnt && size > lcnt)
925         {
926             // Array size was specified, and we have more initializers than needed.
927             char *name=sym->opval.val->sym->name;
928             int lineno=sym->opval.val->sym->lineDef;
929             
930             werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
931         }
932     }
933     else
934     {
935         for (;;)
936         {
937             ast *aSym;
938             
939             aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size++))));
940             aSym = decorateType (resolveSymbols (aSym));
941             rast = createIval (aSym, type->next, iloop, rast);
942             iloop = (iloop ? iloop->next : NULL);
943             if (!iloop)
944             {
945                 break;
946             }
947             
948             /* no of elements given and we    */
949             /* have generated for all of them */
950             if (!--lcnt) 
951             {
952                 // there has to be a better way
953                 char *name=sym->opval.val->sym->name;
954                 int lineno=sym->opval.val->sym->lineDef;
955                 werrorfl (filename, lineno, W_EXCESS_INITIALIZERS, "array", name);
956                 
957                 break;
958             }
959         }
960     }
961
962     /* if we have not been given a size  */
963     if (!DCL_ELEM (type))
964     {
965         DCL_ELEM (type) = size;
966     }
967
968     return decorateType (resolveSymbols (rast));
969 }
970
971
972 /*-----------------------------------------------------------------*/
973 /* createIvalCharPtr - generates initial values for char pointers  */
974 /*-----------------------------------------------------------------*/
975 static ast *
976 createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
977 {
978   ast *rast = NULL;
979
980   /* if this is a pointer & right is a literal array then */
981   /* just assignment will do                              */
982   if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) ||
983                          SPEC_SCLS (iexpr->etype) == S_CODE)
984                         && IS_ARRAY (iexpr->ftype)))
985     return newNode ('=', sym, iexpr);
986
987   /* left side is an array so we have to assign each */
988   /* element                                         */
989   if ((IS_LITERAL (iexpr->etype) ||
990        SPEC_SCLS (iexpr->etype) == S_CODE)
991       && IS_ARRAY (iexpr->ftype))
992     {
993       /* for each character generate an assignment */
994       /* to the array element */
995       char *s = SPEC_CVAL (iexpr->etype).v_char;
996       int i = 0;
997       int size = getSize (iexpr->ftype);
998       int symsize = getSize (type);
999       
1000       if (size>symsize)
1001         {
1002           if (size>(symsize+1))
1003             werrorfl (iexpr->filename, iexpr->lineno, W_EXCESS_INITIALIZERS,
1004                       "string", sym->opval.val->sym->name);
1005           size = symsize;
1006         }
1007
1008       for (i=0;i<size;i++)
1009         {
1010           rast = newNode (NULLOP,
1011                           rast,
1012                           newNode ('=',
1013                                    newNode ('[', sym,
1014                                    newAst_VALUE (valueFromLit ((float) i))),
1015                                    newAst_VALUE (valueFromLit (*s))));
1016           s++;
1017         }
1018
1019       // now WE don't need iexpr's symbol anymore
1020       freeStringSymbol(AST_SYMBOL(iexpr));
1021
1022       return decorateType (resolveSymbols (rast));
1023     }
1024
1025   return NULL;
1026 }
1027
1028 /*-----------------------------------------------------------------*/
1029 /* createIvalPtr - generates initial value for pointers            */
1030 /*-----------------------------------------------------------------*/
1031 static ast *
1032 createIvalPtr (ast * sym, sym_link * type, initList * ilist)
1033 {
1034   ast *rast;
1035   ast *iexpr;
1036
1037   /* if deep then   */
1038   if (ilist->type == INIT_DEEP)
1039     ilist = ilist->init.deep;
1040
1041   iexpr = decorateType (resolveSymbols (list2expr (ilist)));
1042
1043   /* if character pointer */
1044   if (IS_CHAR (type->next))
1045     if ((rast = createIvalCharPtr (sym, type, iexpr)))
1046       return rast;
1047
1048   return newNode ('=', sym, iexpr);
1049 }
1050
1051 /*-----------------------------------------------------------------*/
1052 /* createIval - generates code for initial value                   */
1053 /*-----------------------------------------------------------------*/
1054 static ast *
1055 createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
1056 {
1057   ast *rast = NULL;
1058
1059   if (!ilist)
1060     return NULL;
1061
1062   /* if structure then    */
1063   if (IS_STRUCT (type))
1064     rast = createIvalStruct (sym, type, ilist);
1065   else
1066     /* if this is a pointer */
1067   if (IS_PTR (type))
1068     rast = createIvalPtr (sym, type, ilist);
1069   else
1070     /* if this is an array   */
1071   if (IS_ARRAY (type))
1072     rast = createIvalArray (sym, type, ilist);
1073   else
1074     /* if type is SPECIFIER */
1075   if (IS_SPEC (type))
1076     rast = createIvalType (sym, type, ilist);
1077
1078   if (wid)
1079     return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
1080   else
1081     return decorateType (resolveSymbols (rast));
1082 }
1083
1084 /*-----------------------------------------------------------------*/
1085 /* initAggregates - initialises aggregate variables with initv     */
1086 /*-----------------------------------------------------------------*/
1087 ast * initAggregates (symbol * sym, initList * ival, ast * wid) {
1088   return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid);
1089 }
1090
1091 /*-----------------------------------------------------------------*/
1092 /* gatherAutoInit - creates assignment expressions for initial     */
1093 /*    values                 */
1094 /*-----------------------------------------------------------------*/
1095 static ast *
1096 gatherAutoInit (symbol * autoChain)
1097 {
1098   ast *init = NULL;
1099   ast *work;
1100   symbol *sym;
1101
1102   inInitMode = 1;
1103   for (sym = autoChain; sym; sym = sym->next)
1104     {
1105
1106       /* resolve the symbols in the ival */
1107       if (sym->ival)
1108         resolveIvalSym (sym->ival);
1109
1110       /* if this is a static variable & has an */
1111       /* initial value the code needs to be lifted */
1112       /* here to the main portion since they can be */
1113       /* initialised only once at the start    */
1114       if (IS_STATIC (sym->etype) && sym->ival &&
1115           SPEC_SCLS (sym->etype) != S_CODE)
1116         {
1117           symbol *newSym;
1118           
1119           /* insert the symbol into the symbol table */
1120           /* with level = 0 & name = rname       */
1121           newSym = copySymbol (sym);
1122           addSym (SymbolTab, newSym, newSym->rname, 0, 0, 1);
1123
1124           /* now lift the code to main */
1125           if (IS_AGGREGATE (sym->type)) {
1126             work = initAggregates (sym, sym->ival, NULL);
1127           } else {
1128             if (getNelements(sym->type, sym->ival)>1) {
1129               werrorfl (filename, sym->lineDef,
1130                         W_EXCESS_INITIALIZERS, "scalar", 
1131                         sym->name);
1132             }
1133             work = newNode ('=', newAst_VALUE (symbolVal (newSym)),
1134                             list2expr (sym->ival));
1135           }
1136
1137           setAstLineno (work, sym->lineDef);
1138
1139           sym->ival = NULL;
1140           if (staticAutos)
1141             staticAutos = newNode (NULLOP, staticAutos, work);
1142           else
1143             staticAutos = work;
1144
1145           continue;
1146         }
1147
1148       /* if there is an initial value */
1149       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
1150         {
1151           initList *ilist=sym->ival;
1152           
1153           while (ilist->type == INIT_DEEP) {
1154             ilist = ilist->init.deep;
1155           }
1156
1157           /* update lineno for error msg */
1158           lineno=sym->lineDef;
1159           setAstLineno (ilist->init.node, lineno);
1160           
1161           if (IS_AGGREGATE (sym->type)) {
1162             work = initAggregates (sym, sym->ival, NULL);
1163           } else {
1164             if (getNelements(sym->type, sym->ival)>1) {
1165               werrorfl (filename, sym->lineDef,
1166                         W_EXCESS_INITIALIZERS, "scalar", 
1167                         sym->name);
1168             }
1169             work = newNode ('=', newAst_VALUE (symbolVal (sym)),
1170                             list2expr (sym->ival));
1171           }
1172           
1173           // just to be sure
1174           setAstLineno (work, sym->lineDef);
1175
1176           sym->ival = NULL;
1177           if (init)
1178             init = newNode (NULLOP, init, work);
1179           else
1180             init = work;
1181         }
1182     }
1183   inInitMode = 0;
1184   return init;
1185 }
1186
1187 /*-----------------------------------------------------------------*/
1188 /* freeStringSymbol - delete a literal string if no more usage     */
1189 /*-----------------------------------------------------------------*/
1190 void freeStringSymbol(symbol *sym) {
1191   /* make sure this is a literal string */
1192   assert (sym->isstrlit);
1193   if (--sym->isstrlit == 0) { // lower the usage count
1194     memmap *segment=SPEC_OCLS(sym->etype);
1195     if (segment) {
1196       deleteSetItem(&segment->syms, sym);
1197     }
1198   }
1199 }
1200   
1201 /*-----------------------------------------------------------------*/
1202 /* stringToSymbol - creates a symbol from a literal string         */
1203 /*-----------------------------------------------------------------*/
1204 static value *
1205 stringToSymbol (value * val)
1206 {
1207   char name[SDCC_NAME_MAX + 1];
1208   static int charLbl = 0;
1209   symbol *sym;
1210   set *sp;
1211   int size;
1212
1213   // have we heard this before?
1214   for (sp=statsg->syms; sp; sp=sp->next) {
1215     sym=sp->item;
1216     size = getSize (sym->type);
1217     if (sym->isstrlit && size == getSize (val->type) &&
1218         !memcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char, size)) {
1219       // yes, this is old news. Don't publish it again.
1220       sym->isstrlit++; // but raise the usage count
1221       return symbolVal(sym);
1222     }
1223   }
1224
1225   SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
1226   sym = newSymbol (name, 0);    /* make it @ level 0 */
1227   strncpyz (sym->rname, name, SDCC_NAME_MAX);
1228
1229   /* copy the type from the value passed */
1230   sym->type = copyLinkChain (val->type);
1231   sym->etype = getSpec (sym->type);
1232   /* change to storage class & output class */
1233   SPEC_SCLS (sym->etype) = S_CODE;
1234   SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char;
1235   SPEC_STAT (sym->etype) = 1;
1236   /* make the level & block = 0 */
1237   sym->block = sym->level = 0;
1238   sym->isstrlit = 1;
1239   /* create an ival */
1240   sym->ival = newiList (INIT_NODE, newAst_VALUE (val));
1241   if (noAlloc == 0)
1242     {
1243       /* allocate it */
1244       addSymChain (sym);
1245       allocVariables (sym);
1246     }
1247   sym->ival = NULL;
1248   return symbolVal (sym);
1249
1250 }
1251
1252 /*-----------------------------------------------------------------*/
1253 /* processBlockVars - will go thru the ast looking for block if    */
1254 /*                    a block is found then will allocate the syms */
1255 /*                    will also gather the auto inits present      */
1256 /*-----------------------------------------------------------------*/
1257 ast *
1258 processBlockVars (ast * tree, int *stack, int action)
1259 {
1260   if (!tree)
1261     return NULL;
1262
1263   /* if this is a block */
1264   if (tree->type == EX_OP && tree->opval.op == BLOCK)
1265     {
1266       ast *autoInit;
1267
1268       if (action == ALLOCATE)
1269         {
1270           *stack += allocVariables (tree->values.sym);
1271           autoInit = gatherAutoInit (tree->values.sym);
1272         
1273           /* if there are auto inits then do them */
1274           if (autoInit)
1275             tree->left = newNode (NULLOP, autoInit, tree->left);
1276         }
1277       else                      /* action is deallocate */
1278         deallocLocal (tree->values.sym);
1279     }
1280
1281   processBlockVars (tree->left, stack, action);
1282   processBlockVars (tree->right, stack, action);
1283   return tree;
1284 }
1285
1286
1287 /*-------------------------------------------------------------*/
1288 /* constExprTree - returns TRUE if this tree is a constant     */
1289 /*                 expression                                  */
1290 /*-------------------------------------------------------------*/
1291 bool constExprTree (ast *cexpr) {
1292
1293   if (!cexpr) {
1294     return TRUE;
1295   }
1296
1297   cexpr = decorateType (resolveSymbols (cexpr));
1298
1299   switch (cexpr->type) 
1300     {
1301     case EX_VALUE:
1302       if (IS_AST_LIT_VALUE(cexpr)) {
1303         // this is a literal
1304         return TRUE;
1305       }
1306       if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
1307         // a function's address will never change
1308         return TRUE;
1309       }
1310       if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
1311         // an array's address will never change
1312         return TRUE;
1313       }
1314       if (IS_AST_SYM_VALUE(cexpr) && 
1315           IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
1316         // a symbol in code space will never change
1317         // This is only for the 'char *s="hallo"' case and will have to leave
1318         //printf(" code space symbol");
1319         return TRUE;
1320       }
1321       return FALSE;
1322     case EX_LINK:
1323       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1324               "unexpected link in expression tree\n");
1325       return FALSE;
1326     case EX_OP:
1327       if (cexpr->opval.op==ARRAYINIT) {
1328         // this is a list of literals
1329         return TRUE;
1330       }
1331       if (cexpr->opval.op=='=') {
1332         return constExprTree(cexpr->right);
1333       }
1334       if (cexpr->opval.op==CAST) {
1335         // cast ignored, maybe we should throw a warning here?
1336         return constExprTree(cexpr->right);
1337       }
1338       if (cexpr->opval.op=='&') { 
1339         return TRUE;
1340       }
1341       if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
1342         return FALSE;
1343       }
1344       if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
1345         return TRUE;
1346       }
1347       return FALSE;
1348     case EX_OPERAND:
1349       return IS_CONSTANT(operandType(cexpr->opval.oprnd));
1350     }
1351   return FALSE;
1352 }
1353     
1354 /*-----------------------------------------------------------------*/
1355 /* constExprValue - returns the value of a constant expression     */
1356 /*                  or NULL if it is not a constant expression     */
1357 /*-----------------------------------------------------------------*/
1358 value *
1359 constExprValue (ast * cexpr, int check)
1360 {
1361   cexpr = decorateType (resolveSymbols (cexpr));
1362
1363   /* if this is not a constant then */
1364   if (!IS_LITERAL (cexpr->ftype))
1365     {
1366       /* then check if this is a literal array
1367          in code segment */
1368       if (SPEC_SCLS (cexpr->etype) == S_CODE &&
1369           SPEC_CVAL (cexpr->etype).v_char &&
1370           IS_ARRAY (cexpr->ftype))
1371         {
1372           value *val = valFromType (cexpr->ftype);
1373           SPEC_SCLS (val->etype) = S_LITERAL;
1374           val->sym = cexpr->opval.val->sym;
1375           val->sym->type = copyLinkChain (cexpr->ftype);
1376           val->sym->etype = getSpec (val->sym->type);
1377           strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
1378           return val;
1379         }
1380
1381       /* if we are casting a literal value then */
1382       if (IS_AST_OP (cexpr) &&
1383           cexpr->opval.op == CAST &&
1384           IS_LITERAL (cexpr->right->ftype))
1385         {
1386         return valCastLiteral (cexpr->ftype,
1387                                floatFromVal (cexpr->right->opval.val));
1388         }
1389
1390       if (IS_AST_VALUE (cexpr))
1391         {
1392         return cexpr->opval.val;
1393         }
1394
1395       if (check)
1396         werror (E_CONST_EXPECTED, "found expression");
1397
1398       return NULL;
1399     }
1400
1401   /* return the value */
1402   return cexpr->opval.val;
1403
1404 }
1405
1406 /*-----------------------------------------------------------------*/
1407 /* isLabelInAst - will return true if a given label is found       */
1408 /*-----------------------------------------------------------------*/
1409 bool 
1410 isLabelInAst (symbol * label, ast * tree)
1411 {
1412   if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree))
1413     return FALSE;
1414
1415   if (IS_AST_OP (tree) &&
1416       tree->opval.op == LABEL &&
1417       isSymbolEqual (AST_SYMBOL (tree->left), label))
1418     return TRUE;
1419
1420   return isLabelInAst (label, tree->right) &&
1421     isLabelInAst (label, tree->left);
1422
1423 }
1424
1425 /*-----------------------------------------------------------------*/
1426 /* isLoopCountable - return true if the loop count can be determi- */
1427 /* -ned at compile time .                                          */
1428 /*-----------------------------------------------------------------*/
1429 bool 
1430 isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr,
1431                  symbol ** sym, ast ** init, ast ** end)
1432 {
1433
1434   /* the loop is considered countable if the following
1435      conditions are true :-
1436
1437      a) initExpr :- <sym> = <const>
1438      b) condExpr :- <sym> < <const1>
1439      c) loopExpr :- <sym> ++
1440    */
1441
1442   /* first check the initExpr */
1443   if (IS_AST_OP (initExpr) &&
1444       initExpr->opval.op == '=' &&      /* is assignment */
1445       IS_AST_SYM_VALUE (initExpr->left))
1446     {                           /* left is a symbol */
1447
1448       *sym = AST_SYMBOL (initExpr->left);
1449       *init = initExpr->right;
1450     }
1451   else
1452     return FALSE;
1453
1454   /* for now the symbol has to be of
1455      integral type */
1456   if (!IS_INTEGRAL ((*sym)->type))
1457     return FALSE;
1458
1459   /* now check condExpr */
1460   if (IS_AST_OP (condExpr))
1461     {
1462
1463       switch (condExpr->opval.op)
1464         {
1465         case '<':
1466           if (IS_AST_SYM_VALUE (condExpr->left) &&
1467               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) &&
1468               IS_AST_LIT_VALUE (condExpr->right))
1469             {
1470               *end = condExpr->right;
1471               break;
1472             }
1473           return FALSE;
1474
1475         case '!':
1476           if (IS_AST_OP (condExpr->left) &&
1477               condExpr->left->opval.op == '>' &&
1478               IS_AST_LIT_VALUE (condExpr->left->right) &&
1479               IS_AST_SYM_VALUE (condExpr->left->left) &&
1480               isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left)))
1481             {
1482
1483               *end = newNode ('+', condExpr->left->right,
1484                               newAst_VALUE (constVal ("1")));
1485               break;
1486             }
1487           return FALSE;
1488
1489         default:
1490           return FALSE;
1491         }
1492
1493     }
1494
1495   /* check loop expression is of the form <sym>++ */
1496   if (!IS_AST_OP (loopExpr))
1497     return FALSE;
1498
1499   /* check if <sym> ++ */
1500   if (loopExpr->opval.op == INC_OP)
1501     {
1502
1503       if (loopExpr->left)
1504         {
1505           /* pre */
1506           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1507               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)))
1508             return TRUE;
1509
1510         }
1511       else
1512         {
1513           /* post */
1514           if (IS_AST_SYM_VALUE (loopExpr->right) &&
1515               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right)))
1516             return TRUE;
1517         }
1518
1519     }
1520   else
1521     {
1522       /* check for += */
1523       if (loopExpr->opval.op == ADD_ASSIGN)
1524         {
1525
1526           if (IS_AST_SYM_VALUE (loopExpr->left) &&
1527               isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) &&
1528               IS_AST_LIT_VALUE (loopExpr->right) &&
1529               (int) AST_LIT_VALUE (loopExpr->right) != 1)
1530             return TRUE;
1531         }
1532     }
1533
1534   return FALSE;
1535 }
1536
1537 /*-----------------------------------------------------------------*/
1538 /* astHasVolatile - returns true if ast contains any volatile      */
1539 /*-----------------------------------------------------------------*/
1540 bool 
1541 astHasVolatile (ast * tree)
1542 {
1543   if (!tree)
1544     return FALSE;
1545
1546   if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree)))
1547     return TRUE;
1548
1549   if (IS_AST_OP (tree))
1550     return astHasVolatile (tree->left) ||
1551       astHasVolatile (tree->right);
1552   else
1553     return FALSE;
1554 }
1555
1556 /*-----------------------------------------------------------------*/
1557 /* astHasPointer - return true if the ast contains any ptr variable */
1558 /*-----------------------------------------------------------------*/
1559 bool 
1560 astHasPointer (ast * tree)
1561 {
1562   if (!tree)
1563     return FALSE;
1564
1565   if (IS_AST_LINK (tree))
1566     return TRUE;
1567
1568   /* if we hit an array expression then check
1569      only the left side */
1570   if (IS_AST_OP (tree) && tree->opval.op == '[')
1571     return astHasPointer (tree->left);
1572
1573   if (IS_AST_VALUE (tree))
1574     return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype);
1575
1576   return astHasPointer (tree->left) ||
1577     astHasPointer (tree->right);
1578
1579 }
1580
1581 /*-----------------------------------------------------------------*/
1582 /* astHasSymbol - return true if the ast has the given symbol      */
1583 /*-----------------------------------------------------------------*/
1584 bool 
1585 astHasSymbol (ast * tree, symbol * sym)
1586 {
1587   if (!tree || IS_AST_LINK (tree))
1588     return FALSE;
1589
1590   if (IS_AST_VALUE (tree))
1591     {
1592       if (IS_AST_SYM_VALUE (tree))
1593         return isSymbolEqual (AST_SYMBOL (tree), sym);
1594       else
1595         return FALSE;
1596     }
1597
1598   return astHasSymbol (tree->left, sym) ||
1599     astHasSymbol (tree->right, sym);
1600 }
1601
1602 /*-----------------------------------------------------------------*/
1603 /* astHasDeref - return true if the ast has an indirect access     */
1604 /*-----------------------------------------------------------------*/
1605 static bool 
1606 astHasDeref (ast * tree)
1607 {
1608   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE(tree))
1609     return FALSE;
1610
1611   if (tree->opval.op == '*' && tree->right == NULL) return TRUE;
1612   
1613   return astHasDeref (tree->left) || astHasDeref (tree->right);
1614 }
1615
1616 /*-----------------------------------------------------------------*/
1617 /* isConformingBody - the loop body has to conform to a set of rules */
1618 /* for the loop to be considered reversible read on for rules      */
1619 /*-----------------------------------------------------------------*/
1620 bool 
1621 isConformingBody (ast * pbody, symbol * sym, ast * body)
1622 {
1623
1624   /* we are going to do a pre-order traversal of the
1625      tree && check for the following conditions. (essentially
1626      a set of very shallow tests )
1627      a) the sym passed does not participate in
1628      any arithmetic operation
1629      b) There are no function calls
1630      c) all jumps are within the body
1631      d) address of loop control variable not taken
1632      e) if an assignment has a pointer on the
1633      left hand side make sure right does not have
1634      loop control variable */
1635
1636   /* if we reach the end or a leaf then true */
1637   if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody))
1638     return TRUE;
1639   
1640   /* if anything else is "volatile" */
1641   if (IS_VOLATILE (TETYPE (pbody)))
1642     return FALSE;
1643
1644   /* we will walk the body in a pre-order traversal for
1645      efficiency sake */
1646   switch (pbody->opval.op)
1647     {
1648 /*------------------------------------------------------------------*/
1649     case '[':
1650       // if the loopvar is used as an index
1651       if (astHasSymbol(pbody->right, sym)) {
1652         return FALSE;
1653       }
1654       return isConformingBody (pbody->right, sym, body);
1655
1656 /*------------------------------------------------------------------*/
1657     case PTR_OP:
1658     case '.':
1659       return TRUE;
1660
1661 /*------------------------------------------------------------------*/
1662     case INC_OP:
1663     case DEC_OP:
1664
1665       /* sure we are not sym is not modified */
1666       if (pbody->left &&
1667           IS_AST_SYM_VALUE (pbody->left) &&
1668           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1669         return FALSE;
1670
1671       if (pbody->right &&
1672           IS_AST_SYM_VALUE (pbody->right) &&
1673           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1674         return FALSE;
1675
1676       return TRUE;
1677
1678 /*------------------------------------------------------------------*/
1679
1680     case '*':                   /* can be unary  : if right is null then unary operation */
1681     case '+':
1682     case '-':
1683     case '&':
1684
1685       /* if right is NULL then unary operation  */
1686 /*------------------------------------------------------------------*/
1687 /*----------------------------*/
1688       /*  address of                */
1689 /*----------------------------*/
1690       if (!pbody->right)
1691         {
1692           if (IS_AST_SYM_VALUE (pbody->left) &&
1693               isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1694             return FALSE;
1695           else
1696             return isConformingBody (pbody->left, sym, body);
1697         }
1698       else
1699         {
1700           if (astHasSymbol (pbody->left, sym) ||
1701               astHasSymbol (pbody->right, sym))
1702             return FALSE;
1703         }
1704
1705
1706 /*------------------------------------------------------------------*/
1707     case '|':
1708     case '^':
1709     case '/':
1710     case '%':
1711     case LEFT_OP:
1712     case RIGHT_OP:
1713
1714       if (IS_AST_SYM_VALUE (pbody->left) &&
1715           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1716         return FALSE;
1717
1718       if (IS_AST_SYM_VALUE (pbody->right) &&
1719           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1720         return FALSE;
1721
1722       return isConformingBody (pbody->left, sym, body) &&
1723         isConformingBody (pbody->right, sym, body);
1724
1725     case '~':
1726     case '!':
1727     case RRC:
1728     case RLC:
1729     case GETHBIT:
1730     case SWAP:
1731       if (IS_AST_SYM_VALUE (pbody->left) &&
1732           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1733         return FALSE;
1734       return isConformingBody (pbody->left, sym, body);
1735
1736 /*------------------------------------------------------------------*/
1737
1738     case AND_OP:
1739     case OR_OP:
1740     case '>':
1741     case '<':
1742     case LE_OP:
1743     case GE_OP:
1744     case EQ_OP:
1745     case NE_OP:
1746     case '?':
1747     case ':':
1748     case SIZEOF:                /* evaluate wihout code generation */
1749
1750       if (IS_AST_SYM_VALUE (pbody->left) &&
1751           isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1752         return FALSE;
1753
1754       if (IS_AST_SYM_VALUE (pbody->right) &&
1755           isSymbolEqual (AST_SYMBOL (pbody->right), sym))
1756         return FALSE;
1757
1758       return isConformingBody (pbody->left, sym, body) &&
1759         isConformingBody (pbody->right, sym, body);
1760
1761 /*------------------------------------------------------------------*/
1762     case '=':
1763
1764       /* if left has a pointer & right has loop
1765          control variable then we cannot */
1766       if (astHasPointer (pbody->left) &&
1767           astHasSymbol (pbody->right, sym))
1768         return FALSE;
1769       if (astHasVolatile (pbody->left))
1770         return FALSE;
1771
1772       if (IS_AST_SYM_VALUE (pbody->left)) {
1773         // if the loopvar has an assignment
1774         if (isSymbolEqual (AST_SYMBOL (pbody->left), sym))
1775           return FALSE;
1776         // if the loopvar is used in another (maybe conditional) block
1777         if (astHasSymbol (pbody->right, sym) &&
1778             (pbody->level >= body->level)) {
1779           return FALSE;
1780         }
1781       }
1782
1783       if (astHasVolatile (pbody->left))
1784         return FALSE;
1785
1786       if (astHasDeref(pbody->right)) return FALSE;
1787
1788       return isConformingBody (pbody->left, sym, body) &&
1789         isConformingBody (pbody->right, sym, body);
1790
1791     case MUL_ASSIGN:
1792     case DIV_ASSIGN:
1793     case AND_ASSIGN:
1794     case OR_ASSIGN:
1795     case XOR_ASSIGN:
1796     case RIGHT_ASSIGN:
1797     case LEFT_ASSIGN:
1798     case SUB_ASSIGN:
1799     case ADD_ASSIGN:
1800       assert ("Parser should not have generated this\n");
1801
1802 /*------------------------------------------------------------------*/
1803 /*----------------------------*/
1804       /*      comma operator        */
1805 /*----------------------------*/
1806     case ',':
1807       return isConformingBody (pbody->left, sym, body) &&
1808         isConformingBody (pbody->right, sym, body);
1809
1810 /*------------------------------------------------------------------*/
1811 /*----------------------------*/
1812       /*       function call        */
1813 /*----------------------------*/
1814     case CALL:
1815         /* if local & not passed as paramater then ok */
1816         if (sym->level && !astHasSymbol(pbody->right,sym)) 
1817             return TRUE;
1818       return FALSE;
1819
1820 /*------------------------------------------------------------------*/
1821 /*----------------------------*/
1822       /*     return statement       */
1823 /*----------------------------*/
1824     case RETURN:
1825       return FALSE;
1826
1827     case GOTO:
1828       if (isLabelInAst (AST_SYMBOL (pbody->left), body))
1829         return TRUE;
1830       else
1831         return FALSE;
1832     case SWITCH:
1833       if (astHasSymbol (pbody->left, sym))
1834         return FALSE;
1835
1836     default:
1837       break;
1838     }
1839
1840   return isConformingBody (pbody->left, sym, body) &&
1841     isConformingBody (pbody->right, sym, body);
1842
1843
1844
1845 }
1846
1847 /*-----------------------------------------------------------------*/
1848 /* isLoopReversible - takes a for loop as input && returns true    */
1849 /* if the for loop is reversible. If yes will set the value of     */
1850 /* the loop control var & init value & termination value           */
1851 /*-----------------------------------------------------------------*/
1852 bool
1853 isLoopReversible (ast * loop, symbol ** loopCntrl,
1854                   ast ** init, ast ** end)
1855 {
1856   /* if option says don't do it then don't */
1857   if (optimize.noLoopReverse)
1858     return 0;
1859   /* there are several tests to determine this */
1860
1861   /* for loop has to be of the form
1862      for ( <sym> = <const1> ;
1863      [<sym> < <const2>]  ;
1864      [<sym>++] | [<sym> += 1] | [<sym> = <sym> + 1] )
1865      forBody */
1866   if (!isLoopCountable (AST_FOR (loop, initExpr),
1867                         AST_FOR (loop, condExpr),
1868                         AST_FOR (loop, loopExpr),
1869                         loopCntrl, init, end))
1870     return 0;
1871
1872   /* now do some serious checking on the body of the loop
1873    */
1874
1875   return isConformingBody (loop->left, *loopCntrl, loop->left);
1876
1877 }
1878
1879 /*-----------------------------------------------------------------*/
1880 /* replLoopSym - replace the loop sym by loop sym -1               */
1881 /*-----------------------------------------------------------------*/
1882 static void 
1883 replLoopSym (ast * body, symbol * sym)
1884 {
1885   /* reached end */
1886   if (!body || IS_AST_LINK (body))
1887     return;
1888
1889   if (IS_AST_SYM_VALUE (body))
1890     {
1891
1892       if (isSymbolEqual (AST_SYMBOL (body), sym))
1893         {
1894
1895           body->type = EX_OP;
1896           body->opval.op = '-';
1897           body->left = newAst_VALUE (symbolVal (sym));
1898           body->right = newAst_VALUE (constVal ("1"));
1899
1900         }
1901
1902       return;
1903
1904     }
1905
1906   replLoopSym (body->left, sym);
1907   replLoopSym (body->right, sym);
1908
1909 }
1910
1911 /*-----------------------------------------------------------------*/
1912 /* reverseLoop - do the actual loop reversal                       */
1913 /*-----------------------------------------------------------------*/
1914 ast *
1915 reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
1916 {
1917   ast *rloop;
1918
1919   /* create the following tree
1920      <sym> = loopCount ;
1921      for_continue:
1922      forbody
1923      <sym> -= 1;
1924      if (sym) goto for_continue ;
1925      <sym> = end */
1926
1927   /* put it together piece by piece */
1928   rloop = newNode (NULLOP,
1929                    createIf (newAst_VALUE (symbolVal (sym)),
1930                              newNode (GOTO,
1931                                       newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))),
1932                                       NULL), NULL),
1933                    newNode ('=',
1934                             newAst_VALUE (symbolVal (sym)),
1935                             end));
1936
1937   replLoopSym (loop->left, sym);
1938   setAstLineno (rloop, init->lineno);
1939
1940   rloop = newNode (NULLOP,
1941                    newNode ('=',
1942                             newAst_VALUE (symbolVal (sym)),
1943                             newNode ('-', end, init)),
1944                    createLabel (AST_FOR (loop, continueLabel),
1945                                 newNode (NULLOP,
1946                                          loop->left,
1947                                          newNode (NULLOP,
1948                                                   newNode (SUB_ASSIGN,
1949                                                            newAst_VALUE (symbolVal (sym)),
1950                                                            newAst_VALUE (constVal ("1"))),
1951                                                   rloop))));
1952
1953   rloop->lineno=init->lineno;
1954   return decorateType (rloop);
1955
1956 }
1957
1958 /*-----------------------------------------------------------------*/
1959 /* searchLitOp - search tree (*ops only) for an ast with literal */
1960 /*-----------------------------------------------------------------*/
1961 static ast *
1962 searchLitOp (ast *tree, ast **parent, const char *ops)
1963 {
1964   ast *ret;
1965
1966   if (tree && optimize.global_cse)
1967     {
1968       /* is there a literal operand? */
1969       if (tree->right &&
1970           IS_AST_OP(tree->right) &&
1971           tree->right->right &&
1972           (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
1973         {
1974           if (IS_LITERAL (RTYPE (tree->right)) ^
1975               IS_LITERAL (LTYPE (tree->right)))
1976             {
1977               tree->right->decorated = 0;
1978               tree->decorated = 0;
1979               *parent = tree;
1980               return tree->right;
1981             }
1982           ret = searchLitOp (tree->right, parent, ops);
1983           if (ret)
1984             return ret;
1985         }
1986       if (tree->left &&
1987           IS_AST_OP(tree->left) &&
1988           tree->left->right &&
1989           (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
1990         {
1991           if (IS_LITERAL (RTYPE (tree->left)) ^
1992               IS_LITERAL (LTYPE (tree->left)))
1993             {
1994               tree->left->decorated = 0;
1995               tree->decorated = 0;
1996               *parent = tree;
1997               return tree->left;
1998             }
1999           ret = searchLitOp (tree->left, parent, ops);
2000           if (ret)
2001             return ret;
2002         }
2003     }
2004   return NULL;
2005 }
2006
2007 /*-----------------------------------------------------------------*/
2008 /* decorateType - compute type for this tree also does type checking */
2009 /*          this is done bottom up, since type have to flow upwards */
2010 /*          it also does constant folding, and paramater checking  */
2011 /*-----------------------------------------------------------------*/
2012 ast *
2013 decorateType (ast * tree)
2014 {
2015   int parmNumber;
2016   sym_link *p;
2017
2018   if (!tree)
2019     return tree;
2020
2021   /* if already has type then do nothing */
2022   if (tree->decorated)
2023     return tree;
2024
2025   tree->decorated = 1;
2026
2027 #if 0
2028   /* print the line          */
2029   /* if not block & function */
2030   if (tree->type == EX_OP &&
2031       (tree->opval.op != FUNCTION &&
2032        tree->opval.op != BLOCK &&
2033        tree->opval.op != NULLOP))
2034     {
2035       filename = tree->filename;
2036       lineno = tree->lineno;
2037     }
2038 #endif
2039
2040   /* if any child is an error | this one is an error do nothing */
2041   if (tree->isError ||
2042       (tree->left && tree->left->isError) ||
2043       (tree->right && tree->right->isError))
2044     return tree;
2045
2046 /*------------------------------------------------------------------*/
2047 /*----------------------------*/
2048   /*   leaf has been reached    */
2049 /*----------------------------*/
2050   lineno=tree->lineno;
2051   /* if this is of type value */
2052   /* just get the type        */
2053   if (tree->type == EX_VALUE)
2054     {
2055
2056       if (IS_LITERAL (tree->opval.val->etype))
2057         {
2058
2059           /* if this is a character array then declare it */
2060           if (IS_ARRAY (tree->opval.val->type))
2061             tree->opval.val = stringToSymbol (tree->opval.val);
2062
2063           /* otherwise just copy the type information */
2064           COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2065           return tree;
2066         }
2067
2068       if (tree->opval.val->sym)
2069         {
2070           /* if the undefined flag is set then give error message */
2071           if (tree->opval.val->sym->undefined)
2072             {
2073               werror (E_ID_UNDEF, tree->opval.val->sym->name);
2074               /* assume int */
2075               TTYPE (tree) = TETYPE (tree) =
2076                 tree->opval.val->type = tree->opval.val->sym->type =
2077                 tree->opval.val->etype = tree->opval.val->sym->etype =
2078                 copyLinkChain (INTTYPE);
2079             }
2080           else
2081             {
2082
2083               /* if impilicit i.e. struct/union member then no type */
2084               if (tree->opval.val->sym->implicit)
2085                 TTYPE (tree) = TETYPE (tree) = NULL;
2086
2087               else
2088                 {
2089
2090                   /* else copy the type */
2091                   COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type);
2092
2093                   /* and mark it as referenced */
2094                   tree->opval.val->sym->isref = 1;
2095                 }
2096             }
2097         }
2098
2099       return tree;
2100     }
2101
2102   /* if type link for the case of cast */
2103   if (tree->type == EX_LINK)
2104     {
2105       COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk);
2106       return tree;
2107     }
2108
2109   {
2110     ast *dtl, *dtr;
2111
2112     #if 0
2113     if (tree->opval.op == NULLOP || tree->opval.op == BLOCK)
2114       {
2115         if (tree->left && tree->left->type == EX_OPERAND
2116             && (tree->left->opval.op == INC_OP
2117                 || tree->left->opval.op == DEC_OP)
2118             && tree->left->left)
2119           {
2120             tree->left->right = tree->left->left;
2121             tree->left->left = NULL;
2122           }
2123         if (tree->right && tree->right->type == EX_OPERAND
2124             && (tree->right->opval.op == INC_OP
2125                 || tree->right->opval.op == DEC_OP)
2126             && tree->right->left)
2127           {
2128             tree->right->right = tree->right->left;
2129             tree->right->left = NULL;
2130           }
2131       }
2132     #endif
2133     
2134     dtl = decorateType (tree->left);
2135     /* delay right side for '?' operator since conditional macro expansions might
2136        rely on this */
2137     dtr = (tree->opval.op == '?' ? tree->right : decorateType (tree->right));
2138
2139     /* this is to take care of situations
2140        when the tree gets rewritten */
2141     if (dtl != tree->left)
2142       tree->left = dtl;
2143     if (dtr != tree->right)
2144       tree->right = dtr;
2145     if ((dtl && dtl->isError) || (dtr && dtr->isError))
2146       return tree;
2147
2148     if (IS_AST_OP(tree) &&
2149         (tree->opval.op == CAST || tree->opval.op == '=') &&
2150         (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
2151         (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
2152       // this is a cast/assign to a bigger type
2153       if (IS_AST_OP(tree->right) &&
2154           IS_INTEGRAL(tree->right->ftype) &&
2155           (tree->right->opval.op == LEFT_OP ||
2156            tree->right->opval.op == '*' ||
2157            tree->right->opval.op == '+' ||
2158            tree->right->opval.op == '-') &&
2159           tree->right->right) {
2160         // we should cast an operand instead of the result
2161         tree->right->decorated = 0;
2162         tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
2163                                      tree->right->left);
2164         tree->right = decorateType(tree->right);
2165       }
2166     }
2167   }
2168
2169   /* depending on type of operator do */
2170
2171   switch (tree->opval.op)
2172     {
2173         /*------------------------------------------------------------------*/
2174         /*----------------------------*/
2175         /*        array node          */
2176         /*----------------------------*/
2177     case '[':
2178
2179       /* determine which is the array & which the index */
2180       if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree)))
2181         {
2182
2183           ast *tempTree = tree->left;
2184           tree->left = tree->right;
2185           tree->right = tempTree;
2186         }
2187
2188       /* first check if this is a array or a pointer */
2189       if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree))))
2190         {
2191           werror (E_NEED_ARRAY_PTR, "[]");
2192           goto errorTreeReturn;
2193         }
2194
2195       /* check if the type of the idx */
2196       if (!IS_INTEGRAL (RTYPE (tree)))
2197         {
2198           werror (E_IDX_NOT_INT);
2199           goto errorTreeReturn;
2200         }
2201
2202       /* if the left is an rvalue then error */
2203       if (LRVAL (tree))
2204         {
2205           werror (E_LVALUE_REQUIRED, "array access");
2206           goto errorTreeReturn;
2207         }
2208       RRVAL (tree) = 1;
2209       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
2210       return tree;
2211
2212       /*------------------------------------------------------------------*/
2213       /*----------------------------*/
2214       /*      struct/union          */
2215       /*----------------------------*/
2216     case '.':
2217       /* if this is not a structure */
2218       if (!IS_STRUCT (LTYPE (tree)))
2219         {
2220           werror (E_STRUCT_UNION, ".");
2221           goto errorTreeReturn;
2222         }
2223       TTYPE (tree) = structElemType (LTYPE (tree),
2224                                      (tree->right->type == EX_VALUE ?
2225                                tree->right->opval.val : NULL));
2226       TETYPE (tree) = getSpec (TTYPE (tree));
2227       return tree;
2228
2229       /*------------------------------------------------------------------*/
2230       /*----------------------------*/
2231       /*    struct/union pointer    */
2232       /*----------------------------*/
2233     case PTR_OP:
2234       /* if not pointer to a structure */
2235       if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
2236         {
2237           werror (E_PTR_REQD);
2238           goto errorTreeReturn;
2239         }
2240
2241       if (!IS_STRUCT (LTYPE (tree)->next))
2242         {
2243           werror (E_STRUCT_UNION, "->");
2244           goto errorTreeReturn;
2245         }
2246
2247       TTYPE (tree) = structElemType (LTYPE (tree)->next,
2248                                      (tree->right->type == EX_VALUE ?
2249                                tree->right->opval.val : NULL));
2250       TETYPE (tree) = getSpec (TTYPE (tree));
2251
2252       /* adjust the storage class */
2253       switch (DCL_TYPE(tree->left->ftype)) {
2254       case POINTER:
2255         SPEC_SCLS(TETYPE(tree)) = S_DATA; 
2256         break;
2257       case FPOINTER:
2258         SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2259         break;
2260       case CPOINTER:
2261         SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2262         break;
2263       case GPOINTER:
2264         SPEC_SCLS (TETYPE (tree)) = 0;
2265         break;
2266       case PPOINTER:
2267         SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2268         break;
2269       case IPOINTER:
2270         SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2271         break;
2272       case EEPPOINTER:
2273         SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2274         break;
2275       case UPOINTER:
2276         SPEC_SCLS (TETYPE (tree)) = 0;
2277         break;
2278       case ARRAY:
2279       case FUNCTION:
2280         break;
2281       }
2282       
2283       /* This breaks with extern declarations, bitfields, and perhaps other */
2284       /* cases (gcse). Let's leave this optimization disabled for now and   */
2285       /* ponder if there's a safe way to do this. -- EEP                    */
2286       #if 0
2287       if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
2288           && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
2289         {
2290             /* If defined    struct type at addr var
2291                then rewrite  (&struct var)->member
2292                as            temp
2293                and define    membertype at (addr+offsetof(struct var,member)) temp
2294             */
2295             symbol *sym;
2296             symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
2297                                                 AST_SYMBOL(tree->right));
2298
2299             sym = newSymbol(genSymName (0), 0);
2300             sym->type = TTYPE (tree);
2301             sym->etype = getSpec(sym->type);
2302             sym->lineDef = tree->lineno;
2303             sym->cdef = 1;
2304             sym->isref = 1;
2305             SPEC_STAT (sym->etype) = 1;
2306             SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
2307                                      + element->offset;
2308             SPEC_ABSA(sym->etype) = 1;
2309             addSym (SymbolTab, sym, sym->name, 0, 0, 0);
2310             allocGlobal (sym);
2311             
2312             AST_VALUE (tree) = symbolVal(sym);
2313             TLVAL (tree) = 1;
2314             TRVAL (tree) = 0;
2315             tree->type = EX_VALUE;
2316             tree->left = NULL;
2317             tree->right = NULL;
2318         }
2319       #endif
2320       
2321       return tree;
2322
2323       /*------------------------------------------------------------------*/
2324       /*----------------------------*/
2325       /*  ++/-- operation           */
2326       /*----------------------------*/
2327     case INC_OP:
2328     case DEC_OP:
2329       {
2330         sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
2331         COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
2332         if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
2333           werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
2334
2335         if (tree->right)
2336           RLVAL (tree) = 1;
2337         else
2338           LLVAL (tree) = 1;
2339         return tree;
2340       }
2341
2342       /*------------------------------------------------------------------*/
2343       /*----------------------------*/
2344       /*  bitwise and               */
2345       /*----------------------------*/
2346     case '&':                   /* can be unary   */
2347       /* if right is NULL then unary operation  */
2348       if (tree->right)          /* not an unary operation */
2349         {
2350
2351           if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2352             {
2353               werror (E_BITWISE_OP);
2354               werror (W_CONTINUE, "left & right types are ");
2355               printTypeChain (LTYPE (tree), stderr);
2356               fprintf (stderr, ",");
2357               printTypeChain (RTYPE (tree), stderr);
2358               fprintf (stderr, "\n");
2359               goto errorTreeReturn;
2360             }
2361
2362           /* if they are both literal */
2363           if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2364             {
2365               tree->type = EX_VALUE;
2366               tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2367                                           valFromType (RETYPE (tree)), '&');
2368
2369               tree->right = tree->left = NULL;
2370               TETYPE (tree) = tree->opval.val->etype;
2371               TTYPE (tree) = tree->opval.val->type;
2372               return tree;
2373             }
2374
2375           /* see if this is a GETHBIT operation if yes
2376              then return that */
2377           {
2378             ast *otree = optimizeGetHbit (tree);
2379
2380             if (otree != tree)
2381               return decorateType (otree);
2382           }
2383
2384           TTYPE (tree) =
2385             computeType (LTYPE (tree), RTYPE (tree), FALSE);
2386           TETYPE (tree) = getSpec (TTYPE (tree));
2387
2388           /* if left is a literal exchange left & right */
2389           if (IS_LITERAL (LTYPE (tree)))
2390             {
2391               ast *tTree = tree->left;
2392               tree->left = tree->right;
2393               tree->right = tTree;
2394             }
2395
2396           /* if right is a literal and */
2397           /* we can find a 2nd literal in a and-tree then */
2398           /* rearrange the tree */
2399           if (IS_LITERAL (RTYPE (tree)))
2400             {
2401               ast *parent;
2402               ast *litTree = searchLitOp (tree, &parent, "&");
2403               if (litTree)
2404                 {
2405                   ast *tTree = litTree->left;
2406                   litTree->left = tree->right;
2407                   tree->right = tTree;
2408                   /* both operands in tTree are literal now */
2409                   decorateType (parent);
2410                 }
2411             }
2412
2413           LRVAL (tree) = RRVAL (tree) = 1;
2414           return tree;
2415         }
2416
2417       /*------------------------------------------------------------------*/
2418       /*----------------------------*/
2419       /*  address of                */
2420       /*----------------------------*/
2421       p = newLink (DECLARATOR);
2422       /* if bit field then error */
2423       if (IS_BITVAR (tree->left->etype))
2424         {
2425           werror (E_ILLEGAL_ADDR, "address of bit variable");
2426           goto errorTreeReturn;
2427         }
2428
2429       if (LETYPE(tree) && SPEC_SCLS (tree->left->etype) == S_REGISTER)
2430         {
2431           werror (E_ILLEGAL_ADDR, "address of register variable");
2432           goto errorTreeReturn;
2433         }
2434
2435       if (IS_FUNC (LTYPE (tree)))
2436         {
2437           // this ought to be ignored
2438           return (tree->left);
2439         }
2440
2441       if (IS_LITERAL(LTYPE(tree)))
2442         {
2443           werror (E_ILLEGAL_ADDR, "address of literal");
2444           goto errorTreeReturn;
2445         }
2446
2447      if (LRVAL (tree))
2448         {
2449           werror (E_LVALUE_REQUIRED, "address of");
2450           goto errorTreeReturn;
2451         }
2452       if (!LETYPE (tree))
2453         DCL_TYPE (p) = POINTER;
2454       else if (SPEC_SCLS (tree->left->etype) == S_CODE)
2455         DCL_TYPE (p) = CPOINTER;
2456       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
2457         DCL_TYPE (p) = FPOINTER;
2458       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
2459         DCL_TYPE (p) = PPOINTER;
2460       else if (SPEC_SCLS (tree->left->etype) == S_IDATA)
2461         DCL_TYPE (p) = IPOINTER;
2462       else if (SPEC_SCLS (tree->left->etype) == S_EEPROM)
2463         DCL_TYPE (p) = EEPPOINTER;
2464       else if (SPEC_OCLS(tree->left->etype))
2465           DCL_TYPE (p) = PTR_TYPE(SPEC_OCLS(tree->left->etype));
2466       else
2467           DCL_TYPE (p) = POINTER;
2468
2469       if (IS_AST_SYM_VALUE (tree->left))
2470         {
2471           AST_SYMBOL (tree->left)->addrtaken = 1;
2472           AST_SYMBOL (tree->left)->allocreq = 1;
2473         }
2474
2475       p->next = LTYPE (tree);
2476       TTYPE (tree) = p;
2477       TETYPE (tree) = getSpec (TTYPE (tree));
2478       LLVAL (tree) = 1;
2479       TLVAL (tree) = 1;
2480
2481       #if 0
2482       if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
2483           && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
2484         {
2485           symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
2486                                       AST_SYMBOL(tree->left->right));
2487           AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
2488                                     valueFromLit(element->offset));
2489           tree->left = NULL;
2490           tree->right = NULL;
2491           tree->type = EX_VALUE;
2492           tree->values.literalFromCast = 1;
2493         }
2494       #endif
2495
2496       return tree;
2497
2498       /*------------------------------------------------------------------*/
2499       /*----------------------------*/
2500       /*  bitwise or                */
2501       /*----------------------------*/
2502     case '|':
2503       /* if the rewrite succeeds then don't go any furthur */
2504       {
2505         ast *wtree = optimizeRRCRLC (tree);
2506         if (wtree != tree)
2507           return decorateType (wtree);
2508         
2509         wtree = optimizeSWAP (tree);
2510         if (wtree != tree)
2511           return decorateType (wtree);
2512       }
2513
2514       /* if left is a literal exchange left & right */
2515       if (IS_LITERAL (LTYPE (tree)))
2516         {
2517           ast *tTree = tree->left;
2518           tree->left = tree->right;
2519           tree->right = tTree;
2520         }
2521
2522       /* if right is a literal and */
2523       /* we can find a 2nd literal in a or-tree then */
2524       /* rearrange the tree */
2525       if (IS_LITERAL (RTYPE (tree)))
2526         {
2527           ast *parent;
2528           ast *litTree = searchLitOp (tree, &parent, "|");
2529           if (litTree)
2530             {
2531               ast *tTree = litTree->left;
2532               litTree->left = tree->right;
2533               tree->right = tTree;
2534               /* both operands in tTree are literal now */
2535               decorateType (parent);
2536             }
2537         }
2538       /* fall through */
2539
2540       /*------------------------------------------------------------------*/
2541       /*----------------------------*/
2542       /*  bitwise xor               */
2543       /*----------------------------*/
2544     case '^':
2545       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2546         {
2547           werror (E_BITWISE_OP);
2548           werror (W_CONTINUE, "left & right types are ");
2549           printTypeChain (LTYPE (tree), stderr);
2550           fprintf (stderr, ",");
2551           printTypeChain (RTYPE (tree), stderr);
2552           fprintf (stderr, "\n");
2553           goto errorTreeReturn;
2554         }
2555
2556       /* if they are both literal then */
2557       /* rewrite the tree */
2558       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2559         {
2560           tree->type = EX_VALUE;
2561           tree->opval.val = valBitwise (valFromType (LETYPE (tree)),
2562                                         valFromType (RETYPE (tree)),
2563                                         tree->opval.op);
2564           tree->right = tree->left = NULL;
2565           TETYPE (tree) = tree->opval.val->etype;
2566           TTYPE (tree) = tree->opval.val->type;
2567           return tree;
2568         }
2569
2570       /* if left is a literal exchange left & right */
2571       if (IS_LITERAL (LTYPE (tree)))
2572         {
2573           ast *tTree = tree->left;
2574           tree->left = tree->right;
2575           tree->right = tTree;
2576         }
2577
2578       /* if right is a literal and */
2579       /* we can find a 2nd literal in a xor-tree then */
2580       /* rearrange the tree */
2581       if (IS_LITERAL (RTYPE (tree)) &&
2582           tree->opval.op == '^') /* the same source is used by 'bitwise or' */
2583         {
2584           ast *parent;
2585           ast *litTree = searchLitOp (tree, &parent, "^");
2586           if (litTree)
2587             {
2588               ast *tTree = litTree->left;
2589               litTree->left = tree->right;
2590               tree->right = tTree;
2591               /* both operands in litTree are literal now */
2592               decorateType (parent);
2593             }
2594         }
2595
2596       LRVAL (tree) = RRVAL (tree) = 1;
2597       TETYPE (tree) = getSpec (TTYPE (tree) =
2598                                computeType (LTYPE (tree),
2599                                             RTYPE (tree),
2600                                             FALSE));
2601
2602       return tree;
2603
2604       /*------------------------------------------------------------------*/
2605       /*----------------------------*/
2606       /*  division                  */
2607       /*----------------------------*/
2608     case '/':
2609       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2610         {
2611           werror (E_INVALID_OP, "divide");
2612           goto errorTreeReturn;
2613         }
2614       /* if they are both literal then */
2615       /* rewrite the tree */
2616       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2617         {
2618           tree->type = EX_VALUE;
2619           tree->opval.val = valDiv (valFromType (LETYPE (tree)),
2620                                     valFromType (RETYPE (tree)));
2621           tree->right = tree->left = NULL;
2622           TETYPE (tree) = getSpec (TTYPE (tree) =
2623                                    tree->opval.val->type);
2624           return tree;
2625         }
2626
2627       LRVAL (tree) = RRVAL (tree) = 1;
2628       TETYPE (tree) = getSpec (TTYPE (tree) =
2629                                computeType (LTYPE (tree),
2630                                             RTYPE (tree),
2631                                             TRUE));
2632
2633       /* if right is a literal and */
2634       /* left is also a division by a literal then */
2635       /* rearrange the tree */
2636       if (IS_LITERAL (RTYPE (tree))
2637           /* avoid infinite loop */
2638           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
2639         {
2640           ast *parent;
2641           ast *litTree = searchLitOp (tree, &parent, "/");
2642           if (litTree)
2643             {
2644               if (IS_LITERAL (RTYPE (litTree)))
2645                 {
2646                   /* foo_div */
2647                   litTree->right = newNode ('*', litTree->right, tree->right);
2648                   litTree->right->lineno = tree->lineno;
2649
2650                   tree->right->opval.val = constVal ("1");
2651                   decorateType (parent);
2652                 }
2653               else
2654                 {
2655                   /* litTree->left is literal: no gcse possible.
2656                      We can't call decorateType(parent), because
2657                      this would cause an infinit loop. */
2658                   parent->decorated = 1;
2659                   decorateType (litTree);
2660                 }
2661             }
2662         }
2663
2664       return tree;
2665
2666       /*------------------------------------------------------------------*/
2667       /*----------------------------*/
2668       /*            modulus         */
2669       /*----------------------------*/
2670     case '%':
2671       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
2672         {
2673           werror (E_BITWISE_OP);
2674           werror (W_CONTINUE, "left & right types are ");
2675           printTypeChain (LTYPE (tree), stderr);
2676           fprintf (stderr, ",");
2677           printTypeChain (RTYPE (tree), stderr);
2678           fprintf (stderr, "\n");
2679           goto errorTreeReturn;
2680         }
2681       /* if they are both literal then */
2682       /* rewrite the tree */
2683       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2684         {
2685           tree->type = EX_VALUE;
2686           tree->opval.val = valMod (valFromType (LETYPE (tree)),
2687                                     valFromType (RETYPE (tree)));
2688           tree->right = tree->left = NULL;
2689           TETYPE (tree) = getSpec (TTYPE (tree) =
2690                                    tree->opval.val->type);
2691           return tree;
2692         }
2693       LRVAL (tree) = RRVAL (tree) = 1;
2694       TETYPE (tree) = getSpec (TTYPE (tree) =
2695                                computeType (LTYPE (tree),
2696                                             RTYPE (tree),
2697                                             TRUE));
2698       return tree;
2699
2700       /*------------------------------------------------------------------*/
2701       /*----------------------------*/
2702       /*  address dereference       */
2703       /*----------------------------*/
2704     case '*':                   /* can be unary  : if right is null then unary operation */
2705       if (!tree->right)
2706         {
2707           if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2708             {
2709               werror (E_PTR_REQD);
2710               goto errorTreeReturn;
2711             }
2712
2713           if (LRVAL (tree))
2714             {
2715               werror (E_LVALUE_REQUIRED, "pointer deref");
2716               goto errorTreeReturn;
2717             }
2718           if (IS_ADDRESS_OF_OP(tree->left))
2719             {
2720               /* replace *&obj with obj */
2721               return tree->left->left;
2722             }
2723           TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
2724           TETYPE (tree) = getSpec (TTYPE (tree));
2725           /* adjust the storage class */
2726           switch (DCL_TYPE(tree->left->ftype)) {
2727             case POINTER:
2728               SPEC_SCLS(TETYPE(tree)) = S_DATA;
2729               break;
2730             case FPOINTER:
2731               SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
2732               break;
2733             case CPOINTER:
2734               SPEC_SCLS(TETYPE(tree)) = S_CODE; 
2735               break;
2736             case GPOINTER:
2737               SPEC_SCLS (TETYPE (tree)) = 0;
2738               break;
2739             case PPOINTER:
2740               SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
2741               break;
2742             case IPOINTER:
2743               SPEC_SCLS(TETYPE(tree)) = S_IDATA;
2744               break;
2745             case EEPPOINTER:
2746               SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
2747               break;
2748             case UPOINTER:
2749               SPEC_SCLS (TETYPE (tree)) = 0;
2750               break;
2751             case ARRAY:
2752             case FUNCTION:
2753               break;
2754           }
2755           return tree;
2756         }
2757
2758       /*------------------------------------------------------------------*/
2759       /*----------------------------*/
2760       /*      multiplication        */
2761       /*----------------------------*/
2762       if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
2763         {
2764           werror (E_INVALID_OP, "multiplication");
2765           goto errorTreeReturn;
2766         }
2767
2768       /* if they are both literal then */
2769       /* rewrite the tree */
2770       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2771         {
2772           tree->type = EX_VALUE;
2773           tree->opval.val = valMult (valFromType (LETYPE (tree)),
2774                                      valFromType (RETYPE (tree)));
2775           tree->right = tree->left = NULL;
2776           TETYPE (tree) = getSpec (TTYPE (tree) =
2777                                    tree->opval.val->type);
2778           return tree;
2779         }
2780
2781       /* if left is a literal exchange left & right */
2782       if (IS_LITERAL (LTYPE (tree)))
2783         {
2784           ast *tTree = tree->left;
2785           tree->left = tree->right;
2786           tree->right = tTree;
2787         }
2788
2789       /* if right is a literal and */
2790       /* we can find a 2nd literal in a mul-tree then */
2791       /* rearrange the tree */
2792       if (IS_LITERAL (RTYPE (tree)))
2793         {
2794           ast *parent;
2795           ast *litTree = searchLitOp (tree, &parent, "*");
2796           if (litTree)
2797             {
2798               ast *tTree = litTree->left;
2799               litTree->left = tree->right;
2800               tree->right = tTree;
2801               /* both operands in litTree are literal now */
2802               decorateType (parent);
2803             }
2804         }
2805
2806       LRVAL (tree) = RRVAL (tree) = 1;
2807       TETYPE (tree) = getSpec (TTYPE (tree) =
2808                                computeType (LTYPE (tree),
2809                                             RTYPE (tree),
2810                                             TRUE));
2811
2812       return tree;
2813
2814       /*------------------------------------------------------------------*/
2815       /*----------------------------*/
2816       /*    unary '+' operator      */
2817       /*----------------------------*/
2818     case '+':
2819       /* if unary plus */
2820       if (!tree->right)
2821         {
2822           if (!IS_ARITHMETIC (LTYPE (tree)))
2823             {
2824               werror (E_UNARY_OP, '+');
2825               goto errorTreeReturn;
2826             }
2827
2828           /* if left is a literal then do it */
2829           if (IS_LITERAL (LTYPE (tree)))
2830             {
2831               tree->type = EX_VALUE;
2832               tree->opval.val = valFromType (LETYPE (tree));
2833               tree->left = NULL;
2834               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2835               return tree;
2836             }
2837           LRVAL (tree) = 1;
2838           COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
2839           return tree;
2840         }
2841
2842       /*------------------------------------------------------------------*/
2843       /*----------------------------*/
2844       /*      addition              */
2845       /*----------------------------*/
2846
2847       /* this is not a unary operation */
2848       /* if both pointers then problem */
2849       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2850           (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree))))
2851         {
2852           werror (E_PTR_PLUS_PTR);
2853           goto errorTreeReturn;
2854         }
2855
2856       if (!IS_ARITHMETIC (LTYPE (tree)) &&
2857           !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree)))
2858         {
2859           werror (E_PLUS_INVALID, "+");
2860           goto errorTreeReturn;
2861         }
2862
2863       if (!IS_ARITHMETIC (RTYPE (tree)) &&
2864           !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree)))
2865         {
2866           werror (E_PLUS_INVALID, "+");
2867           goto errorTreeReturn;
2868         }
2869       /* if they are both literal then */
2870       /* rewrite the tree */
2871       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
2872         {
2873           tree->type = EX_VALUE;
2874           tree->opval.val = valPlus (valFromType (LETYPE (tree)),
2875                                      valFromType (RETYPE (tree)));
2876           tree->right = tree->left = NULL;
2877           TETYPE (tree) = getSpec (TTYPE (tree) =
2878                                    tree->opval.val->type);
2879           return tree;
2880         }
2881
2882       /* if the right is a pointer or left is a literal
2883          xchange left & right */
2884       if (IS_ARRAY (RTYPE (tree)) ||
2885           IS_PTR (RTYPE (tree)) ||
2886           IS_LITERAL (LTYPE (tree)))
2887         {
2888           ast *tTree = tree->left;
2889           tree->left = tree->right;
2890           tree->right = tTree;
2891         }
2892
2893       /* if right is a literal and */
2894       /* left is also an addition/subtraction with a literal then */
2895       /* rearrange the tree */
2896       if (IS_LITERAL (RTYPE (tree)))
2897         {
2898           ast *litTree, *parent;
2899           litTree = searchLitOp (tree, &parent, "+-");
2900           if (litTree)
2901             {
2902               if (litTree->opval.op == '+')
2903                 {
2904                   /* foo_aa */
2905                   ast *tTree = litTree->left;
2906                   litTree->left = tree->right;
2907                   tree->right = tree->left;
2908                   tree->left = tTree;
2909                 }
2910               else if (litTree->opval.op == '-')
2911                 {
2912                   if (IS_LITERAL (RTYPE (litTree)))
2913                     {
2914                       /* foo_asr */
2915                       ast *tTree = litTree->left;
2916                       litTree->left = tree->right;
2917                       tree->right = tTree;
2918                     }
2919                   else
2920                     {
2921                       /* foo_asl */
2922                       ast *tTree = litTree->right;
2923                       litTree->right = tree->right;
2924                       tree->right = tTree;
2925                       litTree->opval.op = '+';
2926                       tree->opval.op = '-';
2927                     }
2928                 }
2929               decorateType (parent);
2930             }
2931         }
2932
2933       LRVAL (tree) = RRVAL (tree) = 1;
2934       /* if the left is a pointer */
2935       if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
2936         TETYPE (tree) = getSpec (TTYPE (tree) =
2937                                  LTYPE (tree));
2938       else
2939         TETYPE (tree) = getSpec (TTYPE (tree) =
2940                                  computeType (LTYPE (tree),
2941                                               RTYPE (tree),
2942                                               FALSE));
2943       return tree;
2944
2945       /*------------------------------------------------------------------*/
2946       /*----------------------------*/
2947       /*      unary '-'             */
2948       /*----------------------------*/
2949     case '-':                   /* can be unary   */
2950       /* if right is null then unary */
2951       if (!tree->right)
2952         {
2953
2954           if (!IS_ARITHMETIC (LTYPE (tree)))
2955             {
2956               werror (E_UNARY_OP, tree->opval.op);
2957               goto errorTreeReturn;
2958             }
2959
2960           /* if left is a literal then do it */
2961           if (IS_LITERAL (LTYPE (tree)))
2962             {
2963               tree->type = EX_VALUE;
2964               tree->opval.val = valUnaryPM (valFromType (LETYPE (tree)));
2965               tree->left = NULL;
2966               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
2967               SPEC_USIGN(TETYPE(tree)) = 0;
2968               return tree;
2969             }
2970           LRVAL (tree) = 1;
2971           TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
2972           return tree;
2973         }
2974
2975       /*------------------------------------------------------------------*/
2976       /*----------------------------*/
2977       /*    subtraction             */
2978       /*----------------------------*/
2979
2980       if (!(IS_PTR (LTYPE (tree)) ||
2981             IS_ARRAY (LTYPE (tree)) ||
2982             IS_ARITHMETIC (LTYPE (tree))))
2983         {
2984           werror (E_PLUS_INVALID, "-");
2985           goto errorTreeReturn;
2986         }
2987
2988       if (!(IS_PTR (RTYPE (tree)) ||
2989             IS_ARRAY (RTYPE (tree)) ||
2990             IS_ARITHMETIC (RTYPE (tree))))
2991         {
2992           werror (E_PLUS_INVALID, "-");
2993           goto errorTreeReturn;
2994         }
2995
2996       if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) &&
2997           !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) ||
2998             IS_INTEGRAL (RTYPE (tree))))
2999         {
3000           werror (E_PLUS_INVALID, "-");
3001           goto errorTreeReturn;
3002         }
3003
3004       /* if they are both literal then */
3005       /* rewrite the tree */
3006       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3007         {
3008           tree->type = EX_VALUE;
3009           tree->opval.val = valMinus (valFromType (LETYPE (tree)),
3010                                       valFromType (RETYPE (tree)));
3011           tree->right = tree->left = NULL;
3012           TETYPE (tree) = getSpec (TTYPE (tree) =
3013                                    tree->opval.val->type);
3014           return tree;
3015         }
3016
3017       /* if the left & right are equal then zero */
3018       if (isAstEqual (tree->left, tree->right))
3019         {
3020           tree->type = EX_VALUE;
3021           tree->left = tree->right = NULL;
3022           tree->opval.val = constVal ("0");
3023           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3024           return tree;
3025         }
3026
3027       /* if both of them are pointers or arrays then */
3028       /* the result is going to be an integer        */
3029       if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) &&
3030           (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))))
3031         TETYPE (tree) = TTYPE (tree) = newIntLink ();
3032       else
3033         /* if only the left is a pointer */
3034         /* then result is a pointer      */
3035       if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree)))
3036         TETYPE (tree) = getSpec (TTYPE (tree) =
3037                                  LTYPE (tree));
3038       else
3039         TETYPE (tree) = getSpec (TTYPE (tree) =
3040                                  computeType (LTYPE (tree),
3041                                               RTYPE (tree),
3042                                               FALSE));
3043
3044       LRVAL (tree) = RRVAL (tree) = 1;
3045
3046       /* if right is a literal and */
3047       /* left is also an addition/subtraction with a literal then */
3048       /* rearrange the tree */
3049       if (IS_LITERAL (RTYPE (tree))
3050           /* avoid infinite loop */
3051           && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
3052         {
3053           ast *litTree, *litParent;
3054           litTree = searchLitOp (tree, &litParent, "+-");
3055           if (litTree)
3056             {
3057               if (litTree->opval.op == '+')
3058                 {
3059                   /* foo_sa */
3060                   litTree->right = newNode ('-', litTree->right, tree->right);
3061                   litTree->right->lineno = tree->lineno;
3062
3063                   tree->right->opval.val = constVal ("0");
3064                 }
3065               else if (litTree->opval.op == '-')
3066                 {
3067                   if (IS_LITERAL (RTYPE (litTree)))
3068                     {
3069                       /* foo_ssr */
3070                       litTree->right = newNode ('+', tree->right, litTree->right);
3071                       litTree->right->lineno = tree->lineno;
3072
3073                       tree->right->opval.val = constVal ("0");
3074                     }
3075                   else
3076                     {
3077                       /* foo_ssl */
3078                       ast *tTree = litTree->right;
3079                       litTree->right = tree->right;
3080                       tree->right = tTree;
3081                     }
3082                 }
3083               decorateType (litParent);
3084             }
3085         }
3086       return tree;
3087
3088       /*------------------------------------------------------------------*/
3089       /*----------------------------*/
3090       /*    complement              */
3091       /*----------------------------*/
3092     case '~':
3093       /* can be only integral type */
3094       if (!IS_INTEGRAL (LTYPE (tree)))
3095         {
3096           werror (E_UNARY_OP, tree->opval.op);
3097           goto errorTreeReturn;
3098         }
3099
3100       /* if left is a literal then do it */
3101       if (IS_LITERAL (LTYPE (tree)))
3102         {
3103           tree->type = EX_VALUE;
3104           tree->opval.val = valComplement (valFromType (LETYPE (tree)));
3105           tree->left = NULL;
3106           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3107           return tree;
3108         }
3109       LRVAL (tree) = 1;
3110       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
3111       return tree;
3112
3113       /*------------------------------------------------------------------*/
3114       /*----------------------------*/
3115       /*           not              */
3116       /*----------------------------*/
3117     case '!':
3118       /* can be pointer */
3119       if (!IS_ARITHMETIC (LTYPE (tree)) &&
3120           !IS_PTR (LTYPE (tree)) &&
3121           !IS_ARRAY (LTYPE (tree)))
3122         {
3123           werror (E_UNARY_OP, tree->opval.op);
3124           goto errorTreeReturn;
3125         }
3126
3127       /* if left is a literal then do it */
3128       if (IS_LITERAL (LTYPE (tree)))
3129         {
3130           tree->type = EX_VALUE;
3131           tree->opval.val = valNot (valFromType (LETYPE (tree)));
3132           tree->left = NULL;
3133           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3134           return tree;
3135         }
3136       LRVAL (tree) = 1;
3137       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3138       return tree;
3139
3140       /*------------------------------------------------------------------*/
3141       /*----------------------------*/
3142       /*           shift            */
3143       /*----------------------------*/
3144     case RRC:
3145     case RLC:
3146     case SWAP:
3147       TTYPE (tree) = LTYPE (tree);
3148       TETYPE (tree) = LETYPE (tree);
3149       return tree;
3150
3151     case GETHBIT:
3152       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3153       return tree;
3154
3155     case LEFT_OP:
3156     case RIGHT_OP:
3157       if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype))
3158         {
3159           werror (E_SHIFT_OP_INVALID);
3160           werror (W_CONTINUE, "left & right types are ");
3161           printTypeChain (LTYPE (tree), stderr);
3162           fprintf (stderr, ",");
3163           printTypeChain (RTYPE (tree), stderr);
3164           fprintf (stderr, "\n");
3165           goto errorTreeReturn;
3166         }
3167
3168       /* if they are both literal then */
3169       /* rewrite the tree */
3170       if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))
3171         {
3172           tree->type = EX_VALUE;
3173           tree->opval.val = valShift (valFromType (LETYPE (tree)),
3174                                       valFromType (RETYPE (tree)),
3175                                       (tree->opval.op == LEFT_OP ? 1 : 0));
3176           tree->right = tree->left = NULL;
3177           TETYPE (tree) = getSpec (TTYPE (tree) =
3178                                    tree->opval.val->type);
3179           return tree;
3180         }
3181
3182       LRVAL (tree) = RRVAL (tree) = 1;
3183       if (tree->opval.op == LEFT_OP)
3184         {
3185           /* promote char to int */
3186           TETYPE (tree) = getSpec (TTYPE (tree) =
3187                                    computeType (LTYPE (tree),
3188                                                 LTYPE (tree), /* no, not RTYPE! */
3189                                                 TRUE));
3190         }
3191       else /* RIGHT_OP */
3192         {
3193           /* no promotion necessary */
3194           TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
3195           if (IS_LITERAL (TTYPE (tree)))
3196             SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
3197         }
3198
3199       /* if only the right side is a literal & we are
3200          shifting more than size of the left operand then zero */
3201       if (IS_LITERAL (RTYPE (tree)) &&
3202           ((TYPE_UDWORD) floatFromVal (valFromType (RETYPE (tree)))) >=
3203           (getSize (TETYPE (tree)) * 8))
3204         {
3205           if (tree->opval.op==LEFT_OP ||
3206               (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree))))
3207             {
3208               lineno=tree->lineno;
3209               werror (W_SHIFT_CHANGED,
3210                       (tree->opval.op == LEFT_OP ? "left" : "right"));
3211               tree->type = EX_VALUE;
3212               tree->left = tree->right = NULL;
3213               tree->opval.val = constVal ("0");
3214               TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
3215               return tree;
3216             }
3217         }
3218
3219       return tree;
3220
3221       /*------------------------------------------------------------------*/
3222       /*----------------------------*/
3223       /*         casting            */
3224       /*----------------------------*/
3225     case CAST:                  /* change the type   */
3226       /* cannot cast to an aggregate type */
3227       if (IS_AGGREGATE (LTYPE (tree)))
3228         {
3229           werror (E_CAST_ILLEGAL);
3230           goto errorTreeReturn;
3231         }
3232
3233       /* make sure the type is complete and sane */
3234       checkTypeSanity(LETYPE(tree), "(cast)");
3235
3236 #if 0
3237       /* if the right is a literal replace the tree */
3238       if (IS_LITERAL (RETYPE (tree))) {
3239               if (!IS_PTR (LTYPE (tree))) {
3240                       tree->type = EX_VALUE;
3241                       tree->opval.val =
3242                               valCastLiteral (LTYPE (tree),
3243                                               floatFromVal (valFromType (RETYPE (tree))));
3244                       tree->left = NULL;
3245                       tree->right = NULL;
3246                       TTYPE (tree) = tree->opval.val->type;
3247                       tree->values.literalFromCast = 1;
3248               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3249                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
3250                       sym_link *rest = LTYPE(tree)->next;
3251                       werror(W_LITERAL_GENERIC);
3252                       TTYPE(tree) = newLink(DECLARATOR);
3253                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
3254                       TTYPE(tree)->next = rest;
3255                       tree->left->opval.lnk = TTYPE(tree);
3256                       LRVAL (tree) = 1;
3257               } else {
3258                       TTYPE (tree) = LTYPE (tree);
3259                       LRVAL (tree) = 1;
3260               }
3261       } else {
3262               TTYPE (tree) = LTYPE (tree);
3263               LRVAL (tree) = 1;
3264       }
3265 #else
3266 #if 0 // this is already checked, now this could be explicit
3267       /* if pointer to struct then check names */
3268       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3269           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3270           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3271         {
3272           werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3273                  SPEC_STRUCT(LETYPE(tree))->tag);
3274         }
3275 #endif
3276       if (IS_ADDRESS_OF_OP(tree->right)
3277           && IS_AST_SYM_VALUE (tree->right->left)
3278           && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3279
3280         tree->type = EX_VALUE;
3281         tree->opval.val =
3282           valCastLiteral (LTYPE (tree),
3283                           SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3284         TTYPE (tree) = tree->opval.val->type;
3285         TETYPE (tree) = getSpec (TTYPE (tree));
3286         tree->left = NULL;
3287         tree->right = NULL;
3288         tree->values.literalFromCast = 1;
3289         return tree;
3290       }
3291
3292       /* handle offsetof macro:            */
3293       /* #define offsetof(TYPE, MEMBER) \  */
3294       /* ((unsigned) &((TYPE *)0)->MEMBER) */
3295       if (IS_ADDRESS_OF_OP(tree->right)
3296           && IS_AST_OP (tree->right->left)
3297           && tree->right->left->opval.op == PTR_OP
3298           && IS_AST_OP (tree->right->left->left)
3299           && tree->right->left->left->opval.op == CAST
3300           && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3301
3302         symbol *element = getStructElement (
3303           SPEC_STRUCT (LETYPE(tree->right->left)),
3304           AST_SYMBOL(tree->right->left->right)
3305         );
3306
3307         if (element) {
3308           tree->type = EX_VALUE;
3309           tree->opval.val = valCastLiteral (
3310             LTYPE (tree),
3311             element->offset
3312             + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3313           );
3314
3315           TTYPE (tree) = tree->opval.val->type;
3316           TETYPE (tree) = getSpec (TTYPE (tree));
3317           tree->left = NULL;
3318           tree->right = NULL;
3319           return tree;
3320         }
3321       }
3322
3323       /* if the right is a literal replace the tree */
3324       if (IS_LITERAL (RETYPE (tree))) {
3325         #if 0
3326         if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3327           /* rewrite      (type *)litaddr
3328              as           &temp
3329              and define   type at litaddr temp
3330              (but only if type's storage class is not generic)
3331           */
3332           ast *newTree = newNode ('&', NULL, NULL);
3333           symbol *sym;
3334
3335           TTYPE (newTree) = LTYPE (tree);
3336           TETYPE (newTree) = getSpec(LTYPE (tree));
3337
3338           /* define a global symbol at the casted address*/
3339           sym = newSymbol(genSymName (0), 0);
3340           sym->type = LTYPE (tree)->next;
3341           if (!sym->type)
3342             sym->type = newLink (V_VOID);
3343           sym->etype = getSpec(sym->type);
3344           SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3345           sym->lineDef = tree->lineno;
3346           sym->cdef = 1;
3347           sym->isref = 1;
3348           SPEC_STAT (sym->etype) = 1;
3349           SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3350           SPEC_ABSA(sym->etype) = 1;
3351           addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3352           allocGlobal (sym);
3353
3354           newTree->left = newAst_VALUE(symbolVal(sym));
3355           newTree->left->lineno = tree->lineno;
3356           LTYPE (newTree) = sym->type;
3357           LETYPE (newTree) = sym->etype;
3358           LLVAL (newTree) = 1;
3359           LRVAL (newTree) = 0;
3360           TLVAL (newTree) = 1;
3361           return newTree;
3362         }
3363         #endif
3364         if (!IS_PTR (LTYPE (tree))) {
3365           tree->type = EX_VALUE;
3366           tree->opval.val =
3367           valCastLiteral (LTYPE (tree),
3368                           floatFromVal (valFromType (RTYPE (tree))));
3369           TTYPE (tree) = tree->opval.val->type;
3370           tree->left = NULL;
3371           tree->right = NULL;
3372           tree->values.literalFromCast = 1;
3373           TETYPE (tree) = getSpec (TTYPE (tree));
3374           return tree;
3375         }
3376       }
3377       TTYPE (tree) = LTYPE (tree);
3378       LRVAL (tree) = 1;
3379
3380 #endif
3381       TETYPE (tree) = getSpec (TTYPE (tree));
3382
3383       return tree;
3384
3385       /*------------------------------------------------------------------*/
3386       /*----------------------------*/
3387       /*       logical &&, ||       */
3388       /*----------------------------*/
3389     case AND_OP:
3390     case OR_OP:
3391       /* each must me arithmetic type or be a pointer */
3392       if (!IS_PTR (LTYPE (tree)) &&
3393           !IS_ARRAY (LTYPE (tree)) &&
3394           !IS_INTEGRAL (LTYPE (tree)))
3395         {
3396           werror (E_COMPARE_OP);
3397           goto errorTreeReturn;
3398         }
3399
3400       if (!IS_PTR (RTYPE (tree)) &&
3401           !IS_ARRAY (RTYPE (tree)) &&
3402           !IS_INTEGRAL (RTYPE (tree)))
3403         {
3404           werror (E_COMPARE_OP);
3405           goto errorTreeReturn;
3406         }
3407       /* if they are both literal then */
3408       /* rewrite the tree */
3409       if (IS_LITERAL (RTYPE (tree)) &&
3410           IS_LITERAL (LTYPE (tree)))
3411         {
3412           tree->type = EX_VALUE;
3413           tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3414                                            valFromType (RTYPE (tree)),
3415                                            tree->opval.op);
3416           tree->right = tree->left = NULL;
3417           TETYPE (tree) = getSpec (TTYPE (tree) =
3418                                    tree->opval.val->type);
3419           return tree;
3420         }
3421       LRVAL (tree) = RRVAL (tree) = 1;
3422       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3423       return tree;
3424
3425       /*------------------------------------------------------------------*/
3426       /*----------------------------*/
3427       /*     comparison operators   */
3428       /*----------------------------*/
3429     case '>':
3430     case '<':
3431     case LE_OP:
3432     case GE_OP:
3433     case EQ_OP:
3434     case NE_OP:
3435       {
3436         ast *lt = optimizeCompare (tree);
3437
3438         if (tree != lt)
3439           return lt;
3440       }
3441
3442       /* if they are pointers they must be castable */
3443       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3444         {
3445           if (tree->opval.op==EQ_OP &&
3446               !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3447             // we cannot cast a gptr to a !gptr: switch the leaves
3448             struct ast *s=tree->left;
3449             tree->left=tree->right;
3450             tree->right=s;
3451           }
3452           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3453             {
3454               werror (E_COMPARE_OP);
3455               fprintf (stderr, "comparing type ");
3456               printTypeChain (LTYPE (tree), stderr);
3457               fprintf (stderr, "to type ");
3458               printTypeChain (RTYPE (tree), stderr);
3459               fprintf (stderr, "\n");
3460               goto errorTreeReturn;
3461             }
3462         }
3463       /* else they should be promotable to one another */
3464       else
3465         {
3466           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3467                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3468
3469             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3470               {
3471                 werror (E_COMPARE_OP);
3472                 fprintf (stderr, "comparing type ");
3473                 printTypeChain (LTYPE (tree), stderr);
3474                 fprintf (stderr, "to type ");
3475                 printTypeChain (RTYPE (tree), stderr);
3476                 fprintf (stderr, "\n");
3477                 goto errorTreeReturn;
3478               }
3479         }
3480       /* if unsigned value < 0  then always false */
3481       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3482       if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  &&
3483           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3484         {
3485           if (tree->opval.op == '<')
3486             {
3487               return tree->right;
3488             }
3489           if (tree->opval.op == '>')
3490             {
3491               /* if the parent is an ifx, then we could do */
3492               /* return tree->left; */
3493               tree->opval.op = '?';
3494               tree->right = newNode (':',
3495                                      newAst_VALUE (constVal ("1")),
3496                                      tree->right); /* val 0 */
3497               tree->right->lineno = tree->lineno;
3498               tree->right->left->lineno = tree->lineno;
3499               decorateType (tree->right);
3500             }
3501         }
3502       /* if they are both literal then */
3503       /* rewrite the tree */
3504       if (IS_LITERAL (RTYPE (tree)) &&
3505           IS_LITERAL (LTYPE (tree)))
3506         {
3507           tree->type = EX_VALUE;
3508           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3509                                         valFromType (RETYPE (tree)),
3510                                         tree->opval.op);
3511           tree->right = tree->left = NULL;
3512           TETYPE (tree) = getSpec (TTYPE (tree) =
3513                                    tree->opval.val->type);
3514           return tree;
3515         }
3516       LRVAL (tree) = RRVAL (tree) = 1;
3517       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3518       return tree;
3519
3520       /*------------------------------------------------------------------*/
3521       /*----------------------------*/
3522       /*             sizeof         */
3523       /*----------------------------*/
3524     case SIZEOF:                /* evaluate wihout code generation */
3525       /* change the type to a integer */
3526       tree->type = EX_VALUE;
3527       SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3528       tree->opval.val = constVal (buffer);
3529       tree->right = tree->left = NULL;
3530       TETYPE (tree) = getSpec (TTYPE (tree) =
3531                                tree->opval.val->type);
3532       return tree;
3533
3534       /*------------------------------------------------------------------*/
3535       /*----------------------------*/
3536       /*             typeof         */
3537       /*----------------------------*/
3538     case TYPEOF:
3539         /* return typeof enum value */
3540         tree->type = EX_VALUE;
3541         {
3542             int typeofv = 0;
3543             if (IS_SPEC(tree->right->ftype)) {
3544                 switch (SPEC_NOUN(tree->right->ftype)) {
3545                 case V_INT:
3546                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3547                     else typeofv = TYPEOF_INT;
3548                     break;
3549                 case V_FLOAT:
3550                     typeofv = TYPEOF_FLOAT;
3551                     break;
3552                 case V_CHAR:
3553                     typeofv = TYPEOF_CHAR;
3554                     break;
3555                 case V_VOID:
3556                     typeofv = TYPEOF_VOID;
3557                     break;
3558                 case V_STRUCT:
3559                     typeofv = TYPEOF_STRUCT;
3560                     break;
3561                 case V_BITFIELD:
3562                     typeofv = TYPEOF_BITFIELD;
3563                     break;
3564                 case V_BIT:
3565                     typeofv = TYPEOF_BIT;
3566                     break;
3567                 case V_SBIT:
3568                     typeofv = TYPEOF_SBIT;
3569                     break;
3570                 default:
3571                     break;
3572                 }
3573             } else {
3574                 switch (DCL_TYPE(tree->right->ftype)) {
3575                 case POINTER:
3576                     typeofv = TYPEOF_POINTER;
3577                     break;
3578                 case FPOINTER:
3579                     typeofv = TYPEOF_FPOINTER;
3580                     break;
3581                 case CPOINTER:
3582                     typeofv = TYPEOF_CPOINTER;
3583                     break;
3584                 case GPOINTER:
3585                     typeofv = TYPEOF_GPOINTER;
3586                     break;
3587                 case PPOINTER:
3588                     typeofv = TYPEOF_PPOINTER;
3589                     break;
3590                 case IPOINTER:
3591                     typeofv = TYPEOF_IPOINTER;
3592                     break;
3593                 case ARRAY:
3594                     typeofv = TYPEOF_ARRAY;
3595                     break;
3596                 case FUNCTION:
3597                     typeofv = TYPEOF_FUNCTION;
3598                     break;
3599                 default:
3600                     break;
3601                 }
3602             }
3603             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3604             tree->opval.val = constVal (buffer);
3605             tree->right = tree->left = NULL;
3606             TETYPE (tree) = getSpec (TTYPE (tree) =
3607                                      tree->opval.val->type);
3608         }
3609         return tree;
3610       /*------------------------------------------------------------------*/
3611       /*----------------------------*/
3612       /* conditional operator  '?'  */
3613       /*----------------------------*/
3614     case '?':
3615       /* the type is value of the colon operator (on the right) */
3616       assert(IS_COLON_OP(tree->right));
3617       /* if already known then replace the tree : optimizer will do it
3618          but faster to do it here */
3619       if (IS_LITERAL (LTYPE(tree))) {     
3620           if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3621               return decorateType(tree->right->left) ;
3622           } else {
3623               return decorateType(tree->right->right) ;
3624           }
3625       } else {
3626           tree->right = decorateType(tree->right);
3627           TTYPE (tree) = RTYPE(tree);
3628           TETYPE (tree) = getSpec (TTYPE (tree));
3629       }
3630       return tree;
3631
3632     case ':':
3633       /* if they don't match we have a problem */
3634       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3635         {
3636           werror (E_TYPE_MISMATCH, "conditional operator", " ");
3637           goto errorTreeReturn;
3638         }
3639
3640       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3641       TETYPE (tree) = getSpec (TTYPE (tree));
3642       return tree;
3643
3644
3645 #if 0 // assignment operators are converted by the parser
3646       /*------------------------------------------------------------------*/
3647       /*----------------------------*/
3648       /*    assignment operators    */
3649       /*----------------------------*/
3650     case MUL_ASSIGN:
3651     case DIV_ASSIGN:
3652       /* for these it must be both must be integral */
3653       if (!IS_ARITHMETIC (LTYPE (tree)) ||
3654           !IS_ARITHMETIC (RTYPE (tree)))
3655         {
3656           werror (E_OPS_INTEGRAL);
3657           goto errorTreeReturn;
3658         }
3659       RRVAL (tree) = 1;
3660       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3661
3662       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3663         werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3664
3665       if (LRVAL (tree))
3666         {
3667           werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3668           goto errorTreeReturn;
3669         }
3670       LLVAL (tree) = 1;
3671
3672       return tree;
3673
3674     case AND_ASSIGN:
3675     case OR_ASSIGN:
3676     case XOR_ASSIGN:
3677     case RIGHT_ASSIGN:
3678     case LEFT_ASSIGN:
3679       /* for these it must be both must be integral */
3680       if (!IS_INTEGRAL (LTYPE (tree)) ||
3681           !IS_INTEGRAL (RTYPE (tree)))
3682         {
3683           werror (E_OPS_INTEGRAL);
3684           goto errorTreeReturn;
3685         }
3686       RRVAL (tree) = 1;
3687       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3688
3689       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3690         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3691
3692       if (LRVAL (tree))
3693         {
3694           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3695           goto errorTreeReturn;
3696         }
3697       LLVAL (tree) = 1;
3698
3699       return tree;
3700
3701       /*------------------------------------------------------------------*/
3702       /*----------------------------*/
3703       /*    -= operator             */
3704       /*----------------------------*/
3705     case SUB_ASSIGN:
3706       if (!(IS_PTR (LTYPE (tree)) ||
3707             IS_ARITHMETIC (LTYPE (tree))))
3708         {
3709           werror (E_PLUS_INVALID, "-=");
3710           goto errorTreeReturn;
3711         }
3712
3713       if (!(IS_PTR (RTYPE (tree)) ||
3714             IS_ARITHMETIC (RTYPE (tree))))
3715         {
3716           werror (E_PLUS_INVALID, "-=");
3717           goto errorTreeReturn;
3718         }
3719       RRVAL (tree) = 1;
3720       TETYPE (tree) = getSpec (TTYPE (tree) =
3721                                computeType (LTYPE (tree),
3722                                             RTYPE (tree),
3723                                             FALSE));
3724
3725       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3726         werror (E_CODE_WRITE, "-=");
3727
3728       if (LRVAL (tree))
3729         {
3730           werror (E_LVALUE_REQUIRED, "-=");
3731           goto errorTreeReturn;
3732         }
3733       LLVAL (tree) = 1;
3734
3735       return tree;
3736
3737       /*------------------------------------------------------------------*/
3738       /*----------------------------*/
3739       /*          += operator       */
3740       /*----------------------------*/
3741     case ADD_ASSIGN:
3742       /* this is not a unary operation */
3743       /* if both pointers then problem */
3744       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3745         {
3746           werror (E_PTR_PLUS_PTR);
3747           goto errorTreeReturn;
3748         }
3749
3750       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3751         {
3752           werror (E_PLUS_INVALID, "+=");
3753           goto errorTreeReturn;
3754         }
3755
3756       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3757         {
3758           werror (E_PLUS_INVALID, "+=");
3759           goto errorTreeReturn;
3760         }
3761       RRVAL (tree) = 1;
3762       TETYPE (tree) = getSpec (TTYPE (tree) =
3763                                computeType (LTYPE (tree),
3764                                             RTYPE (tree),
3765                                             FALSE));
3766
3767       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3768         werror (E_CODE_WRITE, "+=");
3769
3770       if (LRVAL (tree))
3771         {
3772           werror (E_LVALUE_REQUIRED, "+=");
3773           goto errorTreeReturn;
3774         }
3775
3776       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3777       tree->opval.op = '=';
3778
3779       return tree;
3780 #endif
3781
3782       /*------------------------------------------------------------------*/
3783       /*----------------------------*/
3784       /*      straight assignemnt   */
3785       /*----------------------------*/
3786     case '=':
3787       /* cannot be an aggregate */
3788       if (IS_AGGREGATE (LTYPE (tree)))
3789         {
3790           werror (E_AGGR_ASSIGN);
3791           goto errorTreeReturn;
3792         }
3793
3794       /* they should either match or be castable */
3795       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3796         {
3797           werror (E_TYPE_MISMATCH, "assignment", " ");
3798           printFromToType(RTYPE(tree),LTYPE(tree));
3799         }
3800
3801       /* if the left side of the tree is of type void
3802          then report error */
3803       if (IS_VOID (LTYPE (tree)))
3804         {
3805           werror (E_CAST_ZERO);
3806           printFromToType(RTYPE(tree), LTYPE(tree));
3807         }
3808
3809       TETYPE (tree) = getSpec (TTYPE (tree) =
3810                                LTYPE (tree));
3811       RRVAL (tree) = 1;
3812       LLVAL (tree) = 1;
3813       if (!tree->initMode ) {
3814         if (IS_CONSTANT(LTYPE(tree)))
3815           werror (E_CODE_WRITE, "=");
3816       }
3817       if (LRVAL (tree))
3818         {
3819           werror (E_LVALUE_REQUIRED, "=");
3820           goto errorTreeReturn;
3821         }
3822
3823       return tree;
3824
3825       /*------------------------------------------------------------------*/
3826       /*----------------------------*/
3827       /*      comma operator        */
3828       /*----------------------------*/
3829     case ',':
3830       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3831       return tree;
3832
3833       /*------------------------------------------------------------------*/
3834       /*----------------------------*/
3835       /*       function call        */
3836       /*----------------------------*/
3837     case CALL:
3838       parmNumber = 1;
3839
3840       if (processParms (tree->left,
3841                         FUNC_ARGS(tree->left->ftype),
3842                         tree->right, &parmNumber, TRUE)) {
3843         goto errorTreeReturn;
3844       }
3845
3846       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
3847           !IFFUNC_ISBUILTIN(LTYPE(tree)))
3848         {
3849           reverseParms (tree->right);
3850         }
3851
3852       if (IS_CODEPTR(LTYPE(tree))) {
3853         TTYPE(tree) = LTYPE(tree)->next->next;
3854       } else {
3855         TTYPE(tree) = LTYPE(tree)->next;
3856       }
3857       TETYPE (tree) = getSpec (TTYPE (tree));
3858       return tree;
3859
3860       /*------------------------------------------------------------------*/
3861       /*----------------------------*/
3862       /*     return statement       */
3863       /*----------------------------*/
3864     case RETURN:
3865       if (!tree->right)
3866         goto voidcheck;
3867
3868       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3869         {
3870           werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
3871           printFromToType (RTYPE(tree), currFunc->type->next);
3872           goto errorTreeReturn;
3873         }
3874
3875       if (IS_VOID (currFunc->type->next)
3876           && tree->right &&
3877           !IS_VOID (RTYPE (tree)))
3878         {
3879           werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
3880           goto errorTreeReturn;
3881         }
3882
3883       /* if there is going to be a casing required then add it */
3884       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3885         {
3886           tree->right =
3887             decorateType (newNode (CAST,
3888                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3889                                    tree->right));
3890         }
3891
3892       RRVAL (tree) = 1;
3893       return tree;
3894
3895     voidcheck:
3896
3897       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3898         {
3899           werror (W_VOID_FUNC, currFunc->name);
3900           goto errorTreeReturn;
3901         }
3902
3903       TTYPE (tree) = TETYPE (tree) = NULL;
3904       return tree;
3905
3906       /*------------------------------------------------------------------*/
3907       /*----------------------------*/
3908       /*     switch statement       */
3909       /*----------------------------*/
3910     case SWITCH:
3911       /* the switch value must be an integer */
3912       if (!IS_INTEGRAL (LTYPE (tree)))
3913         {
3914           werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
3915           goto errorTreeReturn;
3916         }
3917       LRVAL (tree) = 1;
3918       TTYPE (tree) = TETYPE (tree) = NULL;
3919       return tree;
3920
3921       /*------------------------------------------------------------------*/
3922       /*----------------------------*/
3923       /* ifx Statement              */
3924       /*----------------------------*/
3925     case IFX:
3926       tree->left = backPatchLabels (tree->left,
3927                                     tree->trueLabel,
3928                                     tree->falseLabel);
3929       TTYPE (tree) = TETYPE (tree) = NULL;
3930       return tree;
3931
3932       /*------------------------------------------------------------------*/
3933       /*----------------------------*/
3934       /* for Statement              */
3935       /*----------------------------*/
3936     case FOR:
3937
3938       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3939       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3940       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3941
3942       /* if the for loop is reversible then
3943          reverse it otherwise do what we normally
3944          do */
3945       {
3946         symbol *sym;
3947         ast *init, *end;
3948
3949         if (isLoopReversible (tree, &sym, &init, &end))
3950           return reverseLoop (tree, sym, init, end);
3951         else
3952           return decorateType (createFor (AST_FOR (tree, trueLabel),
3953                                           AST_FOR (tree, continueLabel),
3954                                           AST_FOR (tree, falseLabel),
3955                                           AST_FOR (tree, condLabel),
3956                                           AST_FOR (tree, initExpr),
3957                                           AST_FOR (tree, condExpr),
3958                                           AST_FOR (tree, loopExpr),
3959                                           tree->left));
3960       }
3961     default:
3962       TTYPE (tree) = TETYPE (tree) = NULL;
3963       return tree;
3964     }
3965
3966   /* some error found this tree will be killed */
3967 errorTreeReturn:
3968   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3969   tree->opval.op = NULLOP;
3970   tree->isError = 1;
3971
3972   return tree;
3973 }
3974
3975 /*-----------------------------------------------------------------*/
3976 /* sizeofOp - processes size of operation                          */
3977 /*-----------------------------------------------------------------*/
3978 value *
3979 sizeofOp (sym_link * type)
3980 {
3981   char buff[10];
3982
3983   /* make sure the type is complete and sane */
3984   checkTypeSanity(type, "(sizeof)");
3985
3986   /* get the size and convert it to character  */
3987   SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
3988
3989   /* now convert into value  */
3990   return constVal (buff);
3991 }
3992
3993
3994 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3995 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3996 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3997 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3998 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3999 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
4000 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
4001
4002 /*-----------------------------------------------------------------*/
4003 /* backPatchLabels - change and or not operators to flow control    */
4004 /*-----------------------------------------------------------------*/
4005 ast *
4006 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4007 {
4008
4009   if (!tree)
4010     return NULL;
4011
4012   if (!(IS_ANDORNOT (tree)))
4013     return tree;
4014
4015   /* if this an and */
4016   if (IS_AND (tree))
4017     {
4018       static int localLbl = 0;
4019       symbol *localLabel;
4020
4021       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4022       localLabel = newSymbol (buffer, NestLevel);
4023
4024       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4025
4026       /* if left is already a IFX then just change the if true label in that */
4027       if (!IS_IFX (tree->left))
4028         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4029
4030       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4031       /* right is a IFX then just join */
4032       if (IS_IFX (tree->right))
4033         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4034
4035       tree->right = createLabel (localLabel, tree->right);
4036       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4037
4038       return newNode (NULLOP, tree->left, tree->right);
4039     }
4040
4041   /* if this is an or operation */
4042   if (IS_OR (tree))
4043     {
4044       static int localLbl = 0;
4045       symbol *localLabel;
4046
4047       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4048       localLabel = newSymbol (buffer, NestLevel);
4049
4050       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4051
4052       /* if left is already a IFX then just change the if true label in that */
4053       if (!IS_IFX (tree->left))
4054         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4055
4056       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4057       /* right is a IFX then just join */
4058       if (IS_IFX (tree->right))
4059         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4060
4061       tree->right = createLabel (localLabel, tree->right);
4062       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4063
4064       return newNode (NULLOP, tree->left, tree->right);
4065     }
4066
4067   /* change not */
4068   if (IS_NOT (tree))
4069     {
4070       int wasnot = IS_NOT (tree->left);
4071       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4072
4073       /* if the left is already a IFX */
4074       if (!IS_IFX (tree->left))
4075         tree->left = newNode (IFX, tree->left, NULL);
4076
4077       if (wasnot)
4078         {
4079           tree->left->trueLabel = trueLabel;
4080           tree->left->falseLabel = falseLabel;
4081         }
4082       else
4083         {
4084           tree->left->trueLabel = falseLabel;
4085           tree->left->falseLabel = trueLabel;
4086         }
4087       return tree->left;
4088     }
4089
4090   if (IS_IFX (tree))
4091     {
4092       tree->trueLabel = trueLabel;
4093       tree->falseLabel = falseLabel;
4094     }
4095
4096   return tree;
4097 }
4098
4099
4100 /*-----------------------------------------------------------------*/
4101 /* createBlock - create expression tree for block                  */
4102 /*-----------------------------------------------------------------*/
4103 ast *
4104 createBlock (symbol * decl, ast * body)
4105 {
4106   ast *ex;
4107
4108   /* if the block has nothing */
4109   if (!body && !decl)
4110     return NULL;
4111
4112   ex = newNode (BLOCK, NULL, body);
4113   ex->values.sym = decl;
4114   
4115   ex->right = ex->right;
4116   ex->level++;
4117   ex->lineno = 0;
4118   return ex;
4119 }
4120
4121 /*-----------------------------------------------------------------*/
4122 /* createLabel - creates the expression tree for labels            */
4123 /*-----------------------------------------------------------------*/
4124 ast *
4125 createLabel (symbol * label, ast * stmnt)
4126 {
4127   symbol *csym;
4128   char name[SDCC_NAME_MAX + 1];
4129   ast *rValue;
4130
4131   /* must create fresh symbol if the symbol name  */
4132   /* exists in the symbol table, since there can  */
4133   /* be a variable with the same name as the labl */
4134   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4135       (csym->level == label->level))
4136     label = newSymbol (label->name, label->level);
4137
4138   /* change the name before putting it in add _ */
4139   SNPRINTF(name, sizeof(name), "%s", label->name);
4140
4141   /* put the label in the LabelSymbol table    */
4142   /* but first check if a label of the same    */
4143   /* name exists                               */
4144   if ((csym = findSym (LabelTab, NULL, name)))
4145     werror (E_DUPLICATE_LABEL, label->name);
4146   else
4147     addSym (LabelTab, label, name, label->level, 0, 0);
4148
4149   label->islbl = 1;
4150   label->key = labelKey++;
4151   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4152   rValue->lineno = 0;
4153
4154   return rValue;
4155 }
4156
4157 /*-----------------------------------------------------------------*/
4158 /* createCase - generates the parsetree for a case statement       */
4159 /*-----------------------------------------------------------------*/
4160 ast *
4161 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4162 {
4163   char caseLbl[SDCC_NAME_MAX + 1];
4164   ast *rexpr;
4165   value *val;
4166
4167   /* if the switch statement does not exist */
4168   /* then case is out of context            */
4169   if (!swStat)
4170     {
4171       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4172       return NULL;
4173     }
4174
4175   caseVal = decorateType (resolveSymbols (caseVal));
4176   /* if not a constant then error  */
4177   if (!IS_LITERAL (caseVal->ftype))
4178     {
4179       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4180       return NULL;
4181     }
4182
4183   /* if not a integer than error */
4184   if (!IS_INTEGRAL (caseVal->ftype))
4185     {
4186       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4187       return NULL;
4188     }
4189
4190   /* find the end of the switch values chain   */
4191   if (!(val = swStat->values.switchVals.swVals))
4192     swStat->values.switchVals.swVals = caseVal->opval.val;
4193   else
4194     {
4195       /* also order the cases according to value */
4196       value *pval = NULL;
4197       int cVal = (int) floatFromVal (caseVal->opval.val);
4198       while (val && (int) floatFromVal (val) < cVal)
4199         {
4200           pval = val;
4201           val = val->next;
4202         }
4203
4204       /* if we reached the end then */
4205       if (!val)
4206         {
4207           pval->next = caseVal->opval.val;
4208         }
4209       else if ((int) floatFromVal (val) == cVal)
4210         {
4211           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4212                     "case");
4213           return NULL;
4214         }
4215       else
4216         {
4217           /* we found a value greater than */
4218           /* the current value we must add this */
4219           /* before the value */
4220           caseVal->opval.val->next = val;
4221
4222           /* if this was the first in chain */
4223           if (swStat->values.switchVals.swVals == val)
4224             swStat->values.switchVals.swVals =
4225               caseVal->opval.val;
4226           else
4227             pval->next = caseVal->opval.val;
4228         }
4229
4230     }
4231
4232   /* create the case label   */
4233   SNPRINTF(caseLbl, sizeof(caseLbl), 
4234            "_case_%d_%d",
4235            swStat->values.switchVals.swNum,
4236            (int) floatFromVal (caseVal->opval.val));
4237
4238   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4239   rexpr->lineno = 0;
4240   return rexpr;
4241 }
4242
4243 /*-----------------------------------------------------------------*/
4244 /* createDefault - creates the parse tree for the default statement */
4245 /*-----------------------------------------------------------------*/
4246 ast *
4247 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4248 {
4249   char defLbl[SDCC_NAME_MAX + 1];
4250
4251   /* if the switch statement does not exist */
4252   /* then case is out of context            */
4253   if (!swStat)
4254     {
4255       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4256       return NULL;
4257     }
4258
4259   if (swStat->values.switchVals.swDefault)
4260     {
4261       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4262                 "default");
4263       return NULL;
4264     }
4265
4266   /* turn on the default flag   */
4267   swStat->values.switchVals.swDefault = 1;
4268
4269   /* create the label  */
4270   SNPRINTF (defLbl, sizeof(defLbl),
4271             "_default_%d", swStat->values.switchVals.swNum);
4272   return createLabel (newSymbol (defLbl, 0), stmnt);
4273 }
4274
4275 /*-----------------------------------------------------------------*/
4276 /* createIf - creates the parsetree for the if statement           */
4277 /*-----------------------------------------------------------------*/
4278 ast *
4279 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4280 {
4281   static int Lblnum = 0;
4282   ast *ifTree;
4283   symbol *ifTrue, *ifFalse, *ifEnd;
4284
4285   /* if neither exists */
4286   if (!elseBody && !ifBody) {
4287     // if there are no side effects (i++, j() etc)
4288     if (!hasSEFcalls(condAst)) {
4289       return condAst;
4290     }
4291   }
4292
4293   /* create the labels */
4294   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4295   ifFalse = newSymbol (buffer, NestLevel);
4296   /* if no else body then end == false */
4297   if (!elseBody)
4298     ifEnd = ifFalse;
4299   else
4300     {
4301       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4302       ifEnd = newSymbol (buffer, NestLevel);
4303     }
4304
4305   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4306   ifTrue = newSymbol (buffer, NestLevel);
4307
4308   Lblnum++;
4309
4310   /* attach the ifTrue label to the top of it body */
4311   ifBody = createLabel (ifTrue, ifBody);
4312   /* attach a goto end to the ifBody if else is present */
4313   if (elseBody)
4314     {
4315       ifBody = newNode (NULLOP, ifBody,
4316                         newNode (GOTO,
4317                                  newAst_VALUE (symbolVal (ifEnd)),
4318                                  NULL));
4319       /* put the elseLabel on the else body */
4320       elseBody = createLabel (ifFalse, elseBody);
4321       /* out the end at the end of the body */
4322       elseBody = newNode (NULLOP,
4323                           elseBody,
4324                           createLabel (ifEnd, NULL));
4325     }
4326   else
4327     {
4328       ifBody = newNode (NULLOP, ifBody,
4329                         createLabel (ifFalse, NULL));
4330     }
4331   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4332   if (IS_IFX (condAst))
4333     ifTree = condAst;
4334   else
4335     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4336
4337   return newNode (NULLOP, ifTree,
4338                   newNode (NULLOP, ifBody, elseBody));
4339
4340 }
4341
4342 /*-----------------------------------------------------------------*/
4343 /* createDo - creates parse tree for do                            */
4344 /*        _dobody_n:                                               */
4345 /*            statements                                           */
4346 /*        _docontinue_n:                                           */
4347 /*            condition_expression +-> trueLabel -> _dobody_n      */
4348 /*                                 |                               */
4349 /*                                 +-> falseLabel-> _dobreak_n     */
4350 /*        _dobreak_n:                                              */
4351 /*-----------------------------------------------------------------*/
4352 ast *
4353 createDo (symbol * trueLabel, symbol * continueLabel,
4354           symbol * falseLabel, ast * condAst, ast * doBody)
4355 {
4356   ast *doTree;
4357
4358
4359   /* if the body does not exist then it is simple */
4360   if (!doBody)
4361     {
4362       condAst = backPatchLabels (condAst, continueLabel, NULL);
4363       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4364                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4365       doTree->trueLabel = continueLabel;
4366       doTree->falseLabel = NULL;
4367       return doTree;
4368     }
4369
4370   /* otherwise we have a body */
4371   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4372
4373   /* attach the body label to the top */
4374   doBody = createLabel (trueLabel, doBody);
4375   /* attach the continue label to end of body */
4376   doBody = newNode (NULLOP, doBody,
4377                     createLabel (continueLabel, NULL));
4378
4379   /* now put the break label at the end */
4380   if (IS_IFX (condAst))
4381     doTree = condAst;
4382   else
4383     doTree = newIfxNode (condAst, trueLabel, falseLabel);
4384
4385   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4386
4387   /* putting it together */
4388   return newNode (NULLOP, doBody, doTree);
4389 }
4390
4391 /*-----------------------------------------------------------------*/
4392 /* createFor - creates parse tree for 'for' statement              */
4393 /*        initExpr                                                 */
4394 /*   _forcond_n:                                                   */
4395 /*        condExpr  +-> trueLabel -> _forbody_n                    */
4396 /*                  |                                              */
4397 /*                  +-> falseLabel-> _forbreak_n                   */
4398 /*   _forbody_n:                                                   */
4399 /*        statements                                               */
4400 /*   _forcontinue_n:                                               */
4401 /*        loopExpr                                                 */
4402 /*        goto _forcond_n ;                                        */
4403 /*   _forbreak_n:                                                  */
4404 /*-----------------------------------------------------------------*/
4405 ast *
4406 createFor (symbol * trueLabel, symbol * continueLabel,
4407            symbol * falseLabel, symbol * condLabel,
4408            ast * initExpr, ast * condExpr, ast * loopExpr,
4409            ast * forBody)
4410 {
4411   ast *forTree;
4412
4413   /* if loopexpression not present then we can generate it */
4414   /* the same way as a while */
4415   if (!loopExpr)
4416     return newNode (NULLOP, initExpr,
4417                     createWhile (trueLabel, continueLabel,
4418                                  falseLabel, condExpr, forBody));
4419   /* vanilla for statement */
4420   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4421
4422   if (condExpr && !IS_IFX (condExpr))
4423     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4424
4425
4426   /* attach condition label to condition */
4427   condExpr = createLabel (condLabel, condExpr);
4428
4429   /* attach body label to body */
4430   forBody = createLabel (trueLabel, forBody);
4431
4432   /* attach continue to forLoop expression & attach */
4433   /* goto the forcond @ and of loopExpression       */
4434   loopExpr = createLabel (continueLabel,
4435                           newNode (NULLOP,
4436                                    loopExpr,
4437                                    newNode (GOTO,
4438                                        newAst_VALUE (symbolVal (condLabel)),
4439                                             NULL)));
4440   /* now start putting them together */
4441   forTree = newNode (NULLOP, initExpr, condExpr);
4442   forTree = newNode (NULLOP, forTree, forBody);
4443   forTree = newNode (NULLOP, forTree, loopExpr);
4444   /* finally add the break label */
4445   forTree = newNode (NULLOP, forTree,
4446                      createLabel (falseLabel, NULL));
4447   return forTree;
4448 }
4449
4450 /*-----------------------------------------------------------------*/
4451 /* createWhile - creates parse tree for while statement            */
4452 /*               the while statement will be created as follows    */
4453 /*                                                                 */
4454 /*      _while_continue_n:                                         */
4455 /*            condition_expression +-> trueLabel -> _while_boby_n  */
4456 /*                                 |                               */
4457 /*                                 +-> falseLabel -> _while_break_n */
4458 /*      _while_body_n:                                             */
4459 /*            statements                                           */
4460 /*            goto _while_continue_n                               */
4461 /*      _while_break_n:                                            */
4462 /*-----------------------------------------------------------------*/
4463 ast *
4464 createWhile (symbol * trueLabel, symbol * continueLabel,
4465              symbol * falseLabel, ast * condExpr, ast * whileBody)
4466 {
4467   ast *whileTree;
4468
4469   /* put the continue label */
4470   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4471   condExpr = createLabel (continueLabel, condExpr);
4472   condExpr->lineno = 0;
4473
4474   /* put the body label in front of the body */
4475   whileBody = createLabel (trueLabel, whileBody);
4476   whileBody->lineno = 0;
4477   /* put a jump to continue at the end of the body */
4478   /* and put break label at the end of the body */
4479   whileBody = newNode (NULLOP,
4480                        whileBody,
4481                        newNode (GOTO,
4482                                 newAst_VALUE (symbolVal (continueLabel)),
4483                                 createLabel (falseLabel, NULL)));
4484
4485   /* put it all together */
4486   if (IS_IFX (condExpr))
4487     whileTree = condExpr;
4488   else
4489     {
4490       whileTree = newNode (IFX, condExpr, NULL);
4491       /* put the true & false labels in place */
4492       whileTree->trueLabel = trueLabel;
4493       whileTree->falseLabel = falseLabel;
4494     }
4495
4496   return newNode (NULLOP, whileTree, whileBody);
4497 }
4498
4499 /*-----------------------------------------------------------------*/
4500 /* optimizeGetHbit - get highest order bit of the expression       */
4501 /*-----------------------------------------------------------------*/
4502 ast *
4503 optimizeGetHbit (ast * tree)
4504 {
4505   int i, j;
4506   /* if this is not a bit and */
4507   if (!IS_BITAND (tree))
4508     return tree;
4509
4510   /* will look for tree of the form
4511      ( expr >> ((sizeof expr) -1) ) & 1 */
4512   if (!IS_AST_LIT_VALUE (tree->right))
4513     return tree;
4514
4515   if (AST_LIT_VALUE (tree->right) != 1)
4516     return tree;
4517
4518   if (!IS_RIGHT_OP (tree->left))
4519     return tree;
4520
4521   if (!IS_AST_LIT_VALUE (tree->left->right))
4522     return tree;
4523
4524   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4525       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4526     return tree;
4527       
4528   /* make sure the port supports GETHBIT */
4529   if (port->hasExtBitOp
4530       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4531     return tree;
4532
4533   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4534
4535 }
4536
4537 /*-----------------------------------------------------------------*/
4538 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
4539 /*-----------------------------------------------------------------*/
4540 ast *
4541 optimizeRRCRLC (ast * root)
4542 {
4543   /* will look for trees of the form
4544      (?expr << 1) | (?expr >> 7) or
4545      (?expr >> 7) | (?expr << 1) will make that
4546      into a RLC : operation ..
4547      Will also look for
4548      (?expr >> 1) | (?expr << 7) or
4549      (?expr << 7) | (?expr >> 1) will make that
4550      into a RRC operation
4551      note : by 7 I mean (number of bits required to hold the
4552      variable -1 ) */
4553   /* if the root operations is not a | operation the not */
4554   if (!IS_BITOR (root))
4555     return root;
4556
4557   /* I have to think of a better way to match patterns this sucks */
4558   /* that aside let start looking for the first case : I use a the
4559      negative check a lot to improve the efficiency */
4560   /* (?expr << 1) | (?expr >> 7) */
4561   if (IS_LEFT_OP (root->left) &&
4562       IS_RIGHT_OP (root->right))
4563     {
4564
4565       if (!SPEC_USIGN (TETYPE (root->left->left)))
4566         return root;
4567
4568       if (!IS_AST_LIT_VALUE (root->left->right) ||
4569           !IS_AST_LIT_VALUE (root->right->right))
4570         goto tryNext0;
4571
4572       /* make sure it is the same expression */
4573       if (!isAstEqual (root->left->left,
4574                        root->right->left))
4575         goto tryNext0;
4576
4577       if (AST_LIT_VALUE (root->left->right) != 1)
4578         goto tryNext0;
4579
4580       if (AST_LIT_VALUE (root->right->right) !=
4581           (getSize (TTYPE (root->left->left)) * 8 - 1))
4582         goto tryNext0;
4583
4584       /* make sure the port supports RLC */
4585       if (port->hasExtBitOp
4586           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4587         return root;
4588
4589       /* whew got the first case : create the AST */
4590       return newNode (RLC, root->left->left, NULL);
4591     }
4592
4593 tryNext0:
4594   /* check for second case */
4595   /* (?expr >> 7) | (?expr << 1) */
4596   if (IS_LEFT_OP (root->right) &&
4597       IS_RIGHT_OP (root->left))
4598     {
4599
4600       if (!SPEC_USIGN (TETYPE (root->left->left)))
4601         return root;
4602
4603       if (!IS_AST_LIT_VALUE (root->left->right) ||
4604           !IS_AST_LIT_VALUE (root->right->right))
4605         goto tryNext1;
4606
4607       /* make sure it is the same symbol */
4608       if (!isAstEqual (root->left->left,
4609                        root->right->left))
4610         goto tryNext1;
4611
4612       if (AST_LIT_VALUE (root->right->right) != 1)
4613         goto tryNext1;
4614
4615       if (AST_LIT_VALUE (root->left->right) !=
4616           (getSize (TTYPE (root->left->left)) * 8 - 1))
4617         goto tryNext1;
4618
4619       /* make sure the port supports RLC */
4620       if (port->hasExtBitOp
4621           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4622         return root;
4623
4624       /* whew got the first case : create the AST */
4625       return newNode (RLC, root->left->left, NULL);
4626
4627     }
4628
4629 tryNext1:
4630   /* third case for RRC */
4631   /*  (?symbol >> 1) | (?symbol << 7) */
4632   if (IS_LEFT_OP (root->right) &&
4633       IS_RIGHT_OP (root->left))
4634     {
4635
4636       if (!SPEC_USIGN (TETYPE (root->left->left)))
4637         return root;
4638
4639       if (!IS_AST_LIT_VALUE (root->left->right) ||
4640           !IS_AST_LIT_VALUE (root->right->right))
4641         goto tryNext2;
4642
4643       /* make sure it is the same symbol */
4644       if (!isAstEqual (root->left->left,
4645                        root->right->left))
4646         goto tryNext2;
4647
4648       if (AST_LIT_VALUE (root->left->right) != 1)
4649         goto tryNext2;
4650
4651       if (AST_LIT_VALUE (root->right->right) !=
4652           (getSize (TTYPE (root->left->left)) * 8 - 1))
4653         goto tryNext2;
4654
4655       /* make sure the port supports RRC */
4656       if (port->hasExtBitOp
4657           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4658         return root;
4659
4660       /* whew got the first case : create the AST */
4661       return newNode (RRC, root->left->left, NULL);
4662
4663     }
4664 tryNext2:
4665   /* fourth and last case for now */
4666   /* (?symbol << 7) | (?symbol >> 1) */
4667   if (IS_RIGHT_OP (root->right) &&
4668       IS_LEFT_OP (root->left))
4669     {
4670
4671       if (!SPEC_USIGN (TETYPE (root->left->left)))
4672         return root;
4673
4674       if (!IS_AST_LIT_VALUE (root->left->right) ||
4675           !IS_AST_LIT_VALUE (root->right->right))
4676         return root;
4677
4678       /* make sure it is the same symbol */
4679       if (!isAstEqual (root->left->left,
4680                        root->right->left))
4681         return root;
4682
4683       if (AST_LIT_VALUE (root->right->right) != 1)
4684         return root;
4685
4686       if (AST_LIT_VALUE (root->left->right) !=
4687           (getSize (TTYPE (root->left->left)) * 8 - 1))
4688         return root;
4689
4690       /* make sure the port supports RRC */
4691       if (port->hasExtBitOp
4692           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4693         return root;
4694
4695       /* whew got the first case : create the AST */
4696       return newNode (RRC, root->left->left, NULL);
4697
4698     }
4699
4700   /* not found return root */
4701   return root;
4702 }
4703
4704 /*-----------------------------------------------------------------*/
4705 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
4706 /*-----------------------------------------------------------------*/
4707 ast *
4708 optimizeSWAP (ast * root)
4709 {
4710   /* will look for trees of the form
4711      (?expr << 4) | (?expr >> 4) or
4712      (?expr >> 4) | (?expr << 4) will make that
4713      into a SWAP : operation ..
4714      note : by 4 I mean (number of bits required to hold the
4715      variable /2 ) */
4716   /* if the root operations is not a | operation the not */
4717   if (!IS_BITOR (root))
4718     return root;
4719
4720   /* (?expr << 4) | (?expr >> 4) */
4721   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4722       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4723     {
4724
4725       if (!SPEC_USIGN (TETYPE (root->left->left)))
4726         return root;
4727
4728       if (!IS_AST_LIT_VALUE (root->left->right) ||
4729           !IS_AST_LIT_VALUE (root->right->right))
4730         return root;
4731
4732       /* make sure it is the same expression */
4733       if (!isAstEqual (root->left->left,
4734                        root->right->left))
4735         return root;
4736
4737       if (AST_LIT_VALUE (root->left->right) !=
4738           (getSize (TTYPE (root->left->left)) * 4))
4739         return root;
4740
4741       if (AST_LIT_VALUE (root->right->right) !=
4742           (getSize (TTYPE (root->left->left)) * 4))
4743         return root;
4744
4745       /* make sure the port supports SWAP */
4746       if (port->hasExtBitOp
4747           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4748         return root;
4749
4750       /* found it : create the AST */
4751       return newNode (SWAP, root->left->left, NULL);
4752     }
4753
4754
4755   /* not found return root */
4756   return root;
4757 }
4758
4759 /*-----------------------------------------------------------------*/
4760 /* optimizeCompare - otimizes compares for bit variables     */
4761 /*-----------------------------------------------------------------*/
4762 static ast *
4763 optimizeCompare (ast * root)
4764 {
4765   ast *optExpr = NULL;
4766   value *vleft;
4767   value *vright;
4768   unsigned int litValue;
4769
4770   /* if nothing then return nothing */
4771   if (!root)
4772     return NULL;
4773
4774   /* if not a compare op then do leaves */
4775   if (!IS_COMPARE_OP (root))
4776     {
4777       root->left = optimizeCompare (root->left);
4778       root->right = optimizeCompare (root->right);
4779       return root;
4780     }
4781
4782   /* if left & right are the same then depending
4783      of the operation do */
4784   if (isAstEqual (root->left, root->right))
4785     {
4786       switch (root->opval.op)
4787         {
4788         case '>':
4789         case '<':
4790         case NE_OP:
4791           optExpr = newAst_VALUE (constVal ("0"));
4792           break;
4793         case GE_OP:
4794         case LE_OP:
4795         case EQ_OP:
4796           optExpr = newAst_VALUE (constVal ("1"));
4797           break;
4798         }
4799
4800       return decorateType (optExpr);
4801     }
4802
4803   vleft = (root->left->type == EX_VALUE ?
4804            root->left->opval.val : NULL);
4805
4806   vright = (root->right->type == EX_VALUE ?
4807             root->right->opval.val : NULL);
4808
4809   /* if left is a BITVAR in BITSPACE */
4810   /* and right is a LITERAL then opt- */
4811   /* imize else do nothing       */
4812   if (vleft && vright &&
4813       IS_BITVAR (vleft->etype) &&
4814       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4815       IS_LITERAL (vright->etype))
4816     {
4817
4818       /* if right side > 1 then comparison may never succeed */
4819       if ((litValue = (int) floatFromVal (vright)) > 1)
4820         {
4821           werror (W_BAD_COMPARE);
4822           goto noOptimize;
4823         }
4824
4825       if (litValue)
4826         {
4827           switch (root->opval.op)
4828             {
4829             case '>':           /* bit value greater than 1 cannot be */
4830               werror (W_BAD_COMPARE);
4831               goto noOptimize;
4832               break;
4833
4834             case '<':           /* bit value < 1 means 0 */
4835             case NE_OP:
4836               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4837               break;
4838
4839             case LE_OP: /* bit value <= 1 means no check */
4840               optExpr = newAst_VALUE (vright);
4841               break;
4842
4843             case GE_OP: /* bit value >= 1 means only check for = */
4844             case EQ_OP:
4845               optExpr = newAst_VALUE (vleft);
4846               break;
4847             }
4848         }
4849       else
4850         {                       /* literal is zero */
4851           switch (root->opval.op)
4852             {
4853             case '<':           /* bit value < 0 cannot be */
4854               werror (W_BAD_COMPARE);
4855               goto noOptimize;
4856               break;
4857
4858             case '>':           /* bit value > 0 means 1 */
4859             case NE_OP:
4860               optExpr = newAst_VALUE (vleft);
4861               break;
4862
4863             case LE_OP: /* bit value <= 0 means no check */
4864             case GE_OP: /* bit value >= 0 means no check */
4865               werror (W_BAD_COMPARE);
4866               goto noOptimize;
4867               break;
4868
4869             case EQ_OP: /* bit == 0 means ! of bit */
4870               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4871               break;
4872             }
4873         }
4874       return decorateType (resolveSymbols (optExpr));
4875     }                           /* end-of-if of BITVAR */
4876
4877 noOptimize:
4878   return root;
4879 }
4880 /*-----------------------------------------------------------------*/
4881 /* addSymToBlock : adds the symbol to the first block we find      */
4882 /*-----------------------------------------------------------------*/
4883 void 
4884 addSymToBlock (symbol * sym, ast * tree)
4885 {
4886   /* reached end of tree or a leaf */
4887   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4888     return;
4889
4890   /* found a block */
4891   if (IS_AST_OP (tree) &&
4892       tree->opval.op == BLOCK)
4893     {
4894
4895       symbol *lsym = copySymbol (sym);
4896
4897       lsym->next = AST_VALUES (tree, sym);
4898       AST_VALUES (tree, sym) = lsym;
4899       return;
4900     }
4901
4902   addSymToBlock (sym, tree->left);
4903   addSymToBlock (sym, tree->right);
4904 }
4905
4906 /*-----------------------------------------------------------------*/
4907 /* processRegParms - do processing for register parameters         */
4908 /*-----------------------------------------------------------------*/
4909 static void 
4910 processRegParms (value * args, ast * body)
4911 {
4912   while (args)
4913     {
4914       if (IS_REGPARM (args->etype))
4915         addSymToBlock (args->sym, body);
4916       args = args->next;
4917     }
4918 }
4919
4920 /*-----------------------------------------------------------------*/
4921 /* resetParmKey - resets the operandkeys for the symbols           */
4922 /*-----------------------------------------------------------------*/
4923 DEFSETFUNC (resetParmKey)
4924 {
4925   symbol *sym = item;
4926
4927   sym->key = 0;
4928   sym->defs = NULL;
4929   sym->uses = NULL;
4930   sym->remat = 0;
4931   return 1;
4932 }
4933
4934 /*-----------------------------------------------------------------*/
4935 /* createFunction - This is the key node that calls the iCode for  */
4936 /*                  generating the code for a function. Note code  */
4937 /*                  is generated function by function, later when  */
4938 /*                  add inter-procedural analysis this will change */
4939 /*-----------------------------------------------------------------*/
4940 ast *
4941 createFunction (symbol * name, ast * body)
4942 {
4943   ast *ex;
4944   symbol *csym;
4945   int stack = 0;
4946   sym_link *fetype;
4947   iCode *piCode = NULL;
4948
4949   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4950     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4951
4952   /* if check function return 0 then some problem */
4953   if (checkFunction (name, NULL) == 0)
4954     return NULL;
4955
4956   /* create a dummy block if none exists */
4957   if (!body)
4958     body = newNode (BLOCK, NULL, NULL);
4959
4960   noLineno++;
4961
4962   /* check if the function name already in the symbol table */
4963   if ((csym = findSym (SymbolTab, NULL, name->name)))
4964     {
4965       name = csym;
4966       /* special case for compiler defined functions
4967          we need to add the name to the publics list : this
4968          actually means we are now compiling the compiler
4969          support routine */
4970       if (name->cdef)
4971         {
4972           addSet (&publics, name);
4973         }
4974     }
4975   else
4976     {
4977       addSymChain (name);
4978       allocVariables (name);
4979     }
4980   name->lastLine = mylineno;
4981   currFunc = name;
4982
4983   /* set the stack pointer */
4984   /* PENDING: check this for the mcs51 */
4985   stackPtr = -port->stack.direction * port->stack.call_overhead;
4986   if (IFFUNC_ISISR (name->type))
4987     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4988   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
4989     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4990
4991   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4992
4993   fetype = getSpec (name->type);        /* get the specifier for the function */
4994   /* if this is a reentrant function then */
4995   if (IFFUNC_ISREENT (name->type))
4996     reentrant++;
4997
4998   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
4999
5000   /* do processing for parameters that are passed in registers */
5001   processRegParms (FUNC_ARGS(name->type), body);
5002
5003   /* set the stack pointer */
5004   stackPtr = 0;
5005   xstackPtr = -1;
5006
5007   /* allocate & autoinit the block variables */
5008   processBlockVars (body, &stack, ALLOCATE);
5009
5010   /* save the stack information */
5011   if (options.useXstack)
5012     name->xstack = SPEC_STAK (fetype) = stack;
5013   else
5014     name->stack = SPEC_STAK (fetype) = stack;
5015
5016   /* name needs to be mangled */
5017   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5018
5019   body = resolveSymbols (body); /* resolve the symbols */
5020   body = decorateType (body);   /* propagateType & do semantic checks */
5021
5022   ex = newAst_VALUE (symbolVal (name)); /* create name */
5023   ex = newNode (FUNCTION, ex, body);
5024   ex->values.args = FUNC_ARGS(name->type);
5025   ex->decorated=1;
5026   if (options.dump_tree) PA(ex);
5027   if (fatalError)
5028     {
5029       werror (E_FUNC_NO_CODE, name->name);
5030       goto skipall;
5031     }
5032
5033   /* create the node & generate intermediate code */
5034   GcurMemmap = code;
5035   codeOutFile = code->oFile;
5036   piCode = iCodeFromAst (ex);
5037
5038   if (fatalError)
5039     {
5040       werror (E_FUNC_NO_CODE, name->name);
5041       goto skipall;
5042     }
5043
5044   eBBlockFromiCode (piCode);
5045
5046   /* if there are any statics then do them */
5047   if (staticAutos)
5048     {
5049       GcurMemmap = statsg;
5050       codeOutFile = statsg->oFile;
5051       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
5052       staticAutos = NULL;
5053     }
5054
5055 skipall:
5056
5057   /* dealloc the block variables */
5058   processBlockVars (body, &stack, DEALLOCATE);
5059   outputDebugStackSymbols();
5060   /* deallocate paramaters */
5061   deallocParms (FUNC_ARGS(name->type));
5062
5063   if (IFFUNC_ISREENT (name->type))
5064     reentrant--;
5065
5066   /* we are done freeup memory & cleanup */
5067   noLineno--;
5068   if (port->reset_labelKey) labelKey = 1;
5069   name->key = 0;
5070   FUNC_HASBODY(name->type) = 1;
5071   addSet (&operKeyReset, name);
5072   applyToSet (operKeyReset, resetParmKey);
5073
5074   if (options.debug)
5075     cdbStructBlock(1);
5076
5077   cleanUpLevel (LabelTab, 0);
5078   cleanUpBlock (StructTab, 1);
5079   cleanUpBlock (TypedefTab, 1);
5080
5081   xstack->syms = NULL;
5082   istack->syms = NULL;
5083   return NULL;
5084 }
5085
5086
5087 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5088 /*-----------------------------------------------------------------*/
5089 /* ast_print : prints the ast (for debugging purposes)             */
5090 /*-----------------------------------------------------------------*/
5091
5092 void ast_print (ast * tree, FILE *outfile, int indent)
5093 {
5094
5095         if (!tree) return ;
5096
5097         /* can print only decorated trees */
5098         if (!tree->decorated) return;
5099
5100         /* if any child is an error | this one is an error do nothing */
5101         if (tree->isError ||
5102             (tree->left && tree->left->isError) ||
5103             (tree->right && tree->right->isError)) {
5104                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5105         }
5106
5107
5108         /* print the line          */
5109         /* if not block & function */
5110         if (tree->type == EX_OP &&
5111             (tree->opval.op != FUNCTION &&
5112              tree->opval.op != BLOCK &&
5113              tree->opval.op != NULLOP)) {
5114         }
5115
5116         if (tree->opval.op == FUNCTION) {
5117                 int arg=0;
5118                 value *args=FUNC_ARGS(tree->left->opval.val->type);
5119                 fprintf(outfile,"FUNCTION (%s=%p) type (",
5120                         tree->left->opval.val->name, tree);
5121                 printTypeChain (tree->left->opval.val->type->next,outfile);
5122                 fprintf(outfile,") args (");
5123                 do {
5124                   if (arg) {
5125                     fprintf (outfile, ", ");
5126                   }
5127                   printTypeChain (args ? args->type : NULL, outfile);
5128                   arg++;
5129                   args= args ? args->next : NULL;
5130                 } while (args);
5131                 fprintf(outfile,")\n");
5132                 ast_print(tree->left,outfile,indent);
5133                 ast_print(tree->right,outfile,indent);
5134                 return ;
5135         }
5136         if (tree->opval.op == BLOCK) {
5137                 symbol *decls = tree->values.sym;
5138                 INDENT(indent,outfile);
5139                 fprintf(outfile,"{\n");
5140                 while (decls) {
5141                         INDENT(indent+2,outfile);
5142                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5143                                 decls->name, decls);
5144                         printTypeChain(decls->type,outfile);
5145                         fprintf(outfile,")\n");
5146
5147                         decls = decls->next;
5148                 }
5149                 ast_print(tree->right,outfile,indent+2);
5150                 INDENT(indent,outfile);
5151                 fprintf(outfile,"}\n");
5152                 return;
5153         }
5154         if (tree->opval.op == NULLOP) {
5155                 ast_print(tree->left,outfile,indent);
5156                 ast_print(tree->right,outfile,indent);
5157                 return ;
5158         }
5159         INDENT(indent,outfile);
5160
5161         /*------------------------------------------------------------------*/
5162         /*----------------------------*/
5163         /*   leaf has been reached    */
5164         /*----------------------------*/
5165         /* if this is of type value */
5166         /* just get the type        */
5167         if (tree->type == EX_VALUE) {
5168
5169                 if (IS_LITERAL (tree->opval.val->etype)) {
5170                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
5171                         if (SPEC_USIGN (tree->opval.val->etype))
5172                                 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5173                         else
5174                                 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5175                         fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5176                                                       floatFromVal(tree->opval.val));
5177                 } else if (tree->opval.val->sym) {
5178                         /* if the undefined flag is set then give error message */
5179                         if (tree->opval.val->sym->undefined) {
5180                                 fprintf(outfile,"UNDEFINED SYMBOL ");
5181                         } else {
5182                                 fprintf(outfile,"SYMBOL ");
5183                         }
5184                         fprintf(outfile,"(%s=%p)",
5185                                 tree->opval.val->sym->name,tree);
5186                 }
5187                 if (tree->ftype) {
5188                         fprintf(outfile," type (");
5189                         printTypeChain(tree->ftype,outfile);
5190                         fprintf(outfile,")\n");
5191                 } else {
5192                         fprintf(outfile,"\n");
5193                 }
5194                 return ;
5195         }
5196
5197         /* if type link for the case of cast */
5198         if (tree->type == EX_LINK) {
5199                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5200                 printTypeChain(tree->opval.lnk,outfile);
5201                 fprintf(outfile,")\n");
5202                 return ;
5203         }
5204
5205
5206         /* depending on type of operator do */
5207
5208         switch (tree->opval.op) {
5209                 /*------------------------------------------------------------------*/
5210                 /*----------------------------*/
5211                 /*        array node          */
5212                 /*----------------------------*/
5213         case '[':
5214                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5215                 printTypeChain(tree->ftype,outfile);
5216                 fprintf(outfile,")\n");
5217                 ast_print(tree->left,outfile,indent+2);
5218                 ast_print(tree->right,outfile,indent+2);
5219                 return;
5220
5221                 /*------------------------------------------------------------------*/
5222                 /*----------------------------*/
5223                 /*      struct/union          */
5224                 /*----------------------------*/
5225         case '.':
5226                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5227                 printTypeChain(tree->ftype,outfile);
5228                 fprintf(outfile,")\n");
5229                 ast_print(tree->left,outfile,indent+2);
5230                 ast_print(tree->right,outfile,indent+2);
5231                 return ;
5232
5233                 /*------------------------------------------------------------------*/
5234                 /*----------------------------*/
5235                 /*    struct/union pointer    */
5236                 /*----------------------------*/
5237         case PTR_OP:
5238                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5239                 printTypeChain(tree->ftype,outfile);
5240                 fprintf(outfile,")\n");
5241                 ast_print(tree->left,outfile,indent+2);
5242                 ast_print(tree->right,outfile,indent+2);
5243                 return ;
5244
5245                 /*------------------------------------------------------------------*/
5246                 /*----------------------------*/
5247                 /*  ++/-- operation           */
5248                 /*----------------------------*/
5249         case INC_OP:
5250                 if (tree->left)
5251                   fprintf(outfile,"post-");
5252                 else
5253                   fprintf(outfile,"pre-");
5254                 fprintf(outfile,"INC_OP (%p) type (",tree);
5255                 printTypeChain(tree->ftype,outfile);
5256                 fprintf(outfile,")\n");
5257                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5258                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5259                 return ;
5260
5261         case DEC_OP:
5262                 if (tree->left)
5263                   fprintf(outfile,"post-");
5264                 else
5265                   fprintf(outfile,"pre-");
5266                 fprintf(outfile,"DEC_OP (%p) type (",tree);
5267                 printTypeChain(tree->ftype,outfile);
5268                 fprintf(outfile,")\n");
5269                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5270                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5271                 return ;
5272
5273                 /*------------------------------------------------------------------*/
5274                 /*----------------------------*/
5275                 /*  bitwise and               */
5276                 /*----------------------------*/
5277         case '&':
5278                 if (tree->right) {
5279                         fprintf(outfile,"& (%p) type (",tree);
5280                         printTypeChain(tree->ftype,outfile);
5281                         fprintf(outfile,")\n");
5282                         ast_print(tree->left,outfile,indent+2);
5283                         ast_print(tree->right,outfile,indent+2);
5284                 } else {
5285                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5286                         printTypeChain(tree->ftype,outfile);
5287                         fprintf(outfile,")\n");
5288                         ast_print(tree->left,outfile,indent+2);
5289                         ast_print(tree->right,outfile,indent+2);
5290                 }
5291                 return ;
5292                 /*----------------------------*/
5293                 /*  bitwise or                */
5294                 /*----------------------------*/
5295         case '|':
5296                 fprintf(outfile,"OR (%p) type (",tree);
5297                 printTypeChain(tree->ftype,outfile);
5298                 fprintf(outfile,")\n");
5299                 ast_print(tree->left,outfile,indent+2);
5300                 ast_print(tree->right,outfile,indent+2);
5301                 return ;
5302                 /*------------------------------------------------------------------*/
5303                 /*----------------------------*/
5304                 /*  bitwise xor               */
5305                 /*----------------------------*/
5306         case '^':
5307                 fprintf(outfile,"XOR (%p) type (",tree);
5308                 printTypeChain(tree->ftype,outfile);
5309                 fprintf(outfile,")\n");
5310                 ast_print(tree->left,outfile,indent+2);
5311                 ast_print(tree->right,outfile,indent+2);
5312                 return ;
5313
5314                 /*------------------------------------------------------------------*/
5315                 /*----------------------------*/
5316                 /*  division                  */
5317                 /*----------------------------*/
5318         case '/':
5319                 fprintf(outfile,"DIV (%p) type (",tree);
5320                 printTypeChain(tree->ftype,outfile);
5321                 fprintf(outfile,")\n");
5322                 ast_print(tree->left,outfile,indent+2);
5323                 ast_print(tree->right,outfile,indent+2);
5324                 return ;
5325                 /*------------------------------------------------------------------*/
5326                 /*----------------------------*/
5327                 /*            modulus         */
5328                 /*----------------------------*/
5329         case '%':
5330                 fprintf(outfile,"MOD (%p) type (",tree);
5331                 printTypeChain(tree->ftype,outfile);
5332                 fprintf(outfile,")\n");
5333                 ast_print(tree->left,outfile,indent+2);
5334                 ast_print(tree->right,outfile,indent+2);
5335                 return ;
5336
5337                 /*------------------------------------------------------------------*/
5338                 /*----------------------------*/
5339                 /*  address dereference       */
5340                 /*----------------------------*/
5341         case '*':                       /* can be unary  : if right is null then unary operation */
5342                 if (!tree->right) {
5343                         fprintf(outfile,"DEREF (%p) type (",tree);
5344                         printTypeChain(tree->ftype,outfile);
5345                         fprintf(outfile,")\n");
5346                         ast_print(tree->left,outfile,indent+2);
5347                         return ;
5348                 }                       
5349                 /*------------------------------------------------------------------*/
5350                 /*----------------------------*/
5351                 /*      multiplication        */
5352                 /*----------------------------*/                
5353                 fprintf(outfile,"MULT (%p) type (",tree);
5354                 printTypeChain(tree->ftype,outfile);
5355                 fprintf(outfile,")\n");
5356                 ast_print(tree->left,outfile,indent+2);
5357                 ast_print(tree->right,outfile,indent+2);
5358                 return ;
5359
5360
5361                 /*------------------------------------------------------------------*/
5362                 /*----------------------------*/
5363                 /*    unary '+' operator      */
5364                 /*----------------------------*/
5365         case '+':
5366                 /* if unary plus */
5367                 if (!tree->right) {
5368                         fprintf(outfile,"UPLUS (%p) type (",tree);
5369                         printTypeChain(tree->ftype,outfile);
5370                         fprintf(outfile,")\n");
5371                         ast_print(tree->left,outfile,indent+2);
5372                 } else {
5373                         /*------------------------------------------------------------------*/
5374                         /*----------------------------*/
5375                         /*      addition              */
5376                         /*----------------------------*/
5377                         fprintf(outfile,"ADD (%p) type (",tree);
5378                         printTypeChain(tree->ftype,outfile);
5379                         fprintf(outfile,")\n");
5380                         ast_print(tree->left,outfile,indent+2);
5381                         ast_print(tree->right,outfile,indent+2);
5382                 }
5383                 return;
5384                 /*------------------------------------------------------------------*/
5385                 /*----------------------------*/
5386                 /*      unary '-'             */
5387                 /*----------------------------*/
5388         case '-':                       /* can be unary   */
5389                 if (!tree->right) {
5390                         fprintf(outfile,"UMINUS (%p) type (",tree);
5391                         printTypeChain(tree->ftype,outfile);
5392                         fprintf(outfile,")\n");
5393                         ast_print(tree->left,outfile,indent+2);
5394                 } else {
5395                         /*------------------------------------------------------------------*/
5396                         /*----------------------------*/
5397                         /*      subtraction           */
5398                         /*----------------------------*/
5399                         fprintf(outfile,"SUB (%p) type (",tree);
5400                         printTypeChain(tree->ftype,outfile);
5401                         fprintf(outfile,")\n");
5402                         ast_print(tree->left,outfile,indent+2);
5403                         ast_print(tree->right,outfile,indent+2);
5404                 }
5405                 return;
5406                 /*------------------------------------------------------------------*/
5407                 /*----------------------------*/
5408                 /*    compliment              */
5409                 /*----------------------------*/
5410         case '~':
5411                 fprintf(outfile,"COMPL (%p) type (",tree);
5412                 printTypeChain(tree->ftype,outfile);
5413                 fprintf(outfile,")\n");
5414                 ast_print(tree->left,outfile,indent+2);
5415                 return ;
5416                 /*------------------------------------------------------------------*/
5417                 /*----------------------------*/
5418                 /*           not              */
5419                 /*----------------------------*/
5420         case '!':
5421                 fprintf(outfile,"NOT (%p) type (",tree);
5422                 printTypeChain(tree->ftype,outfile);
5423                 fprintf(outfile,")\n");
5424                 ast_print(tree->left,outfile,indent+2);
5425                 return ;
5426                 /*------------------------------------------------------------------*/
5427                 /*----------------------------*/
5428                 /*           shift            */
5429                 /*----------------------------*/
5430         case RRC:
5431                 fprintf(outfile,"RRC (%p) type (",tree);
5432                 printTypeChain(tree->ftype,outfile);
5433                 fprintf(outfile,")\n");
5434                 ast_print(tree->left,outfile,indent+2);
5435                 return ;
5436
5437         case RLC:
5438                 fprintf(outfile,"RLC (%p) type (",tree);
5439                 printTypeChain(tree->ftype,outfile);
5440                 fprintf(outfile,")\n");
5441                 ast_print(tree->left,outfile,indent+2);
5442                 return ;
5443         case SWAP:
5444                 fprintf(outfile,"SWAP (%p) type (",tree);
5445                 printTypeChain(tree->ftype,outfile);
5446                 fprintf(outfile,")\n");
5447                 ast_print(tree->left,outfile,indent+2);
5448                 return ;
5449         case GETHBIT:
5450                 fprintf(outfile,"GETHBIT (%p) type (",tree);
5451                 printTypeChain(tree->ftype,outfile);
5452                 fprintf(outfile,")\n");
5453                 ast_print(tree->left,outfile,indent+2);
5454                 return ;
5455         case LEFT_OP:
5456                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5457                 printTypeChain(tree->ftype,outfile);
5458                 fprintf(outfile,")\n");
5459                 ast_print(tree->left,outfile,indent+2);
5460                 ast_print(tree->right,outfile,indent+2);
5461                 return ;
5462         case RIGHT_OP:
5463                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5464                 printTypeChain(tree->ftype,outfile);
5465                 fprintf(outfile,")\n");
5466                 ast_print(tree->left,outfile,indent+2);
5467                 ast_print(tree->right,outfile,indent+2);
5468                 return ;
5469                 /*------------------------------------------------------------------*/
5470                 /*----------------------------*/
5471                 /*         casting            */
5472                 /*----------------------------*/
5473         case CAST:                      /* change the type   */
5474                 fprintf(outfile,"CAST (%p) from type (",tree);
5475                 printTypeChain(tree->right->ftype,outfile);
5476                 fprintf(outfile,") to type (");
5477                 printTypeChain(tree->ftype,outfile);
5478                 fprintf(outfile,")\n");
5479                 ast_print(tree->right,outfile,indent+2);
5480                 return ;
5481                 
5482         case AND_OP:
5483                 fprintf(outfile,"ANDAND (%p) type (",tree);
5484                 printTypeChain(tree->ftype,outfile);
5485                 fprintf(outfile,")\n");
5486                 ast_print(tree->left,outfile,indent+2);
5487                 ast_print(tree->right,outfile,indent+2);
5488                 return ;
5489         case OR_OP:
5490                 fprintf(outfile,"OROR (%p) type (",tree);
5491                 printTypeChain(tree->ftype,outfile);
5492                 fprintf(outfile,")\n");
5493                 ast_print(tree->left,outfile,indent+2);
5494                 ast_print(tree->right,outfile,indent+2);
5495                 return ;
5496                 
5497                 /*------------------------------------------------------------------*/
5498                 /*----------------------------*/
5499                 /*     comparison operators   */
5500                 /*----------------------------*/
5501         case '>':
5502                 fprintf(outfile,"GT(>) (%p) type (",tree);
5503                 printTypeChain(tree->ftype,outfile);
5504                 fprintf(outfile,")\n");
5505                 ast_print(tree->left,outfile,indent+2);
5506                 ast_print(tree->right,outfile,indent+2);
5507                 return ;
5508         case '<':
5509                 fprintf(outfile,"LT(<) (%p) type (",tree);
5510                 printTypeChain(tree->ftype,outfile);
5511                 fprintf(outfile,")\n");
5512                 ast_print(tree->left,outfile,indent+2);
5513                 ast_print(tree->right,outfile,indent+2);
5514                 return ;
5515         case LE_OP:
5516                 fprintf(outfile,"LE(<=) (%p) type (",tree);
5517                 printTypeChain(tree->ftype,outfile);
5518                 fprintf(outfile,")\n");
5519                 ast_print(tree->left,outfile,indent+2);
5520                 ast_print(tree->right,outfile,indent+2);
5521                 return ;
5522         case GE_OP:
5523                 fprintf(outfile,"GE(>=) (%p) type (",tree);
5524                 printTypeChain(tree->ftype,outfile);
5525                 fprintf(outfile,")\n");
5526                 ast_print(tree->left,outfile,indent+2);
5527                 ast_print(tree->right,outfile,indent+2);
5528                 return ;
5529         case EQ_OP:
5530                 fprintf(outfile,"EQ(==) (%p) type (",tree);
5531                 printTypeChain(tree->ftype,outfile);
5532                 fprintf(outfile,")\n");
5533                 ast_print(tree->left,outfile,indent+2);
5534                 ast_print(tree->right,outfile,indent+2);
5535                 return ;
5536         case NE_OP:
5537                 fprintf(outfile,"NE(!=) (%p) type (",tree);
5538                 printTypeChain(tree->ftype,outfile);
5539                 fprintf(outfile,")\n");
5540                 ast_print(tree->left,outfile,indent+2);
5541                 ast_print(tree->right,outfile,indent+2);
5542                 /*------------------------------------------------------------------*/
5543                 /*----------------------------*/
5544                 /*             sizeof         */
5545                 /*----------------------------*/
5546         case SIZEOF:            /* evaluate wihout code generation */
5547                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5548                 return ;
5549
5550                 /*------------------------------------------------------------------*/
5551                 /*----------------------------*/
5552                 /* conditional operator  '?'  */
5553                 /*----------------------------*/
5554         case '?':
5555                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5556                 printTypeChain(tree->ftype,outfile);
5557                 fprintf(outfile,")\n");
5558                 ast_print(tree->left,outfile,indent+2);
5559                 ast_print(tree->right,outfile,indent+2);
5560                 return;
5561
5562         case ':':
5563                 fprintf(outfile,"COLON(:) (%p) type (",tree);
5564                 printTypeChain(tree->ftype,outfile);
5565                 fprintf(outfile,")\n");
5566                 ast_print(tree->left,outfile,indent+2);
5567                 ast_print(tree->right,outfile,indent+2);
5568                 return ;
5569
5570                 /*------------------------------------------------------------------*/
5571                 /*----------------------------*/
5572                 /*    assignment operators    */
5573                 /*----------------------------*/
5574         case MUL_ASSIGN:
5575                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5576                 printTypeChain(tree->ftype,outfile);
5577                 fprintf(outfile,")\n");
5578                 ast_print(tree->left,outfile,indent+2);
5579                 ast_print(tree->right,outfile,indent+2);
5580                 return;
5581         case DIV_ASSIGN:
5582                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5583                 printTypeChain(tree->ftype,outfile);
5584                 fprintf(outfile,")\n");
5585                 ast_print(tree->left,outfile,indent+2);
5586                 ast_print(tree->right,outfile,indent+2);
5587                 return;
5588         case AND_ASSIGN:
5589                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5590                 printTypeChain(tree->ftype,outfile);
5591                 fprintf(outfile,")\n");
5592                 ast_print(tree->left,outfile,indent+2);
5593                 ast_print(tree->right,outfile,indent+2);
5594                 return;
5595         case OR_ASSIGN:
5596                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5597                 printTypeChain(tree->ftype,outfile);
5598                 fprintf(outfile,")\n");
5599                 ast_print(tree->left,outfile,indent+2);
5600                 ast_print(tree->right,outfile,indent+2);
5601                 return;
5602         case XOR_ASSIGN:
5603                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5604                 printTypeChain(tree->ftype,outfile);
5605                 fprintf(outfile,")\n");
5606                 ast_print(tree->left,outfile,indent+2);
5607                 ast_print(tree->right,outfile,indent+2);
5608                 return;
5609         case RIGHT_ASSIGN:
5610                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5611                 printTypeChain(tree->ftype,outfile);
5612                 fprintf(outfile,")\n");
5613                 ast_print(tree->left,outfile,indent+2);
5614                 ast_print(tree->right,outfile,indent+2);
5615                 return;
5616         case LEFT_ASSIGN:
5617                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5618                 printTypeChain(tree->ftype,outfile);
5619                 fprintf(outfile,")\n");
5620                 ast_print(tree->left,outfile,indent+2);
5621                 ast_print(tree->right,outfile,indent+2);
5622                 return;
5623                 /*------------------------------------------------------------------*/
5624                 /*----------------------------*/
5625                 /*    -= operator             */
5626                 /*----------------------------*/
5627         case SUB_ASSIGN:
5628                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5629                 printTypeChain(tree->ftype,outfile);
5630                 fprintf(outfile,")\n");
5631                 ast_print(tree->left,outfile,indent+2);
5632                 ast_print(tree->right,outfile,indent+2);
5633                 return;
5634                 /*------------------------------------------------------------------*/
5635                 /*----------------------------*/
5636                 /*          += operator       */
5637                 /*----------------------------*/
5638         case ADD_ASSIGN:
5639                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5640                 printTypeChain(tree->ftype,outfile);
5641                 fprintf(outfile,")\n");
5642                 ast_print(tree->left,outfile,indent+2);
5643                 ast_print(tree->right,outfile,indent+2);
5644                 return;
5645                 /*------------------------------------------------------------------*/
5646                 /*----------------------------*/
5647                 /*      straight assignemnt   */
5648                 /*----------------------------*/
5649         case '=':
5650                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5651                 printTypeChain(tree->ftype,outfile);
5652                 fprintf(outfile,")\n");
5653                 ast_print(tree->left,outfile,indent+2);
5654                 ast_print(tree->right,outfile,indent+2);
5655                 return;     
5656                 /*------------------------------------------------------------------*/
5657                 /*----------------------------*/
5658                 /*      comma operator        */
5659                 /*----------------------------*/
5660         case ',':
5661                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5662                 printTypeChain(tree->ftype,outfile);
5663                 fprintf(outfile,")\n");
5664                 ast_print(tree->left,outfile,indent+2);
5665                 ast_print(tree->right,outfile,indent+2);
5666                 return;
5667                 /*------------------------------------------------------------------*/
5668                 /*----------------------------*/
5669                 /*       function call        */
5670                 /*----------------------------*/
5671         case CALL:
5672         case PCALL:
5673                 fprintf(outfile,"CALL (%p) type (",tree);
5674                 printTypeChain(tree->ftype,outfile);
5675                 fprintf(outfile,")\n");
5676                 ast_print(tree->left,outfile,indent+2);
5677                 ast_print(tree->right,outfile,indent+2);
5678                 return;
5679         case PARAM:
5680                 fprintf(outfile,"PARMS\n");
5681                 ast_print(tree->left,outfile,indent+2);
5682                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5683                         ast_print(tree->right,outfile,indent+2);
5684                 }
5685                 return ;
5686                 /*------------------------------------------------------------------*/
5687                 /*----------------------------*/
5688                 /*     return statement       */
5689                 /*----------------------------*/
5690         case RETURN:
5691                 fprintf(outfile,"RETURN (%p) type (",tree);
5692                 if (tree->right) {
5693                     printTypeChain(tree->right->ftype,outfile);
5694                 }
5695                 fprintf(outfile,")\n");
5696                 ast_print(tree->right,outfile,indent+2);
5697                 return ;
5698                 /*------------------------------------------------------------------*/
5699                 /*----------------------------*/
5700                 /*     label statement        */
5701                 /*----------------------------*/
5702         case LABEL :
5703                 fprintf(outfile,"LABEL (%p)\n",tree);
5704                 ast_print(tree->left,outfile,indent+2);
5705                 ast_print(tree->right,outfile,indent);
5706                 return;
5707                 /*------------------------------------------------------------------*/
5708                 /*----------------------------*/
5709                 /*     switch statement       */
5710                 /*----------------------------*/
5711         case SWITCH:
5712                 {
5713                         value *val;
5714                         fprintf(outfile,"SWITCH (%p) ",tree);
5715                         ast_print(tree->left,outfile,0);
5716                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5717                                 INDENT(indent+2,outfile);
5718                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5719                                         (int) floatFromVal(val),
5720                                         tree->values.switchVals.swNum,
5721                                         (int) floatFromVal(val));
5722                         }
5723                         ast_print(tree->right,outfile,indent);
5724                 }
5725                 return ;
5726                 /*------------------------------------------------------------------*/
5727                 /*----------------------------*/
5728                 /* ifx Statement              */
5729                 /*----------------------------*/
5730         case IFX:
5731                 fprintf(outfile,"IF (%p) \n",tree);
5732                 ast_print(tree->left,outfile,indent+2);
5733                 if (tree->trueLabel) {
5734                         INDENT(indent+2,outfile);
5735                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5736                 }
5737                 if (tree->falseLabel) {
5738                         INDENT(indent+2,outfile);
5739                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5740                 }
5741                 ast_print(tree->right,outfile,indent+2);
5742                 return ;
5743                 /*----------------------------*/
5744                 /* goto Statement              */
5745                 /*----------------------------*/
5746         case GOTO:
5747                 fprintf(outfile,"GOTO (%p) \n",tree);
5748                 ast_print(tree->left,outfile,indent+2);
5749                 fprintf(outfile,"\n");
5750                 return ;
5751                 /*------------------------------------------------------------------*/
5752                 /*----------------------------*/
5753                 /* for Statement              */
5754                 /*----------------------------*/
5755         case FOR:
5756                 fprintf(outfile,"FOR (%p) \n",tree);
5757                 if (AST_FOR( tree, initExpr)) {
5758                         INDENT(indent+2,outfile);
5759                         fprintf(outfile,"INIT EXPR ");
5760                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5761                 }
5762                 if (AST_FOR( tree, condExpr)) {
5763                         INDENT(indent+2,outfile);
5764                         fprintf(outfile,"COND EXPR ");
5765                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5766                 }
5767                 if (AST_FOR( tree, loopExpr)) {
5768                         INDENT(indent+2,outfile);
5769                         fprintf(outfile,"LOOP EXPR ");
5770                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5771                 }
5772                 fprintf(outfile,"FOR LOOP BODY \n");
5773                 ast_print(tree->left,outfile,indent+2);
5774                 return ;
5775         case CRITICAL:
5776                 fprintf(outfile,"CRITICAL (%p) \n",tree);
5777                 ast_print(tree->left,outfile,indent+2);
5778         default:
5779             return ;
5780         }
5781 }
5782
5783 void PA(ast *t)
5784 {
5785         ast_print(t,stdout,0);
5786 }
5787
5788
5789
5790 /*-----------------------------------------------------------------*/
5791 /* astErrors : returns non-zero if errors present in tree          */
5792 /*-----------------------------------------------------------------*/
5793 int astErrors(ast *t)
5794 {
5795   int errors=0;
5796   
5797   if (t)
5798     {
5799       if (t->isError)
5800         errors++;
5801   
5802       if (t->type == EX_VALUE
5803           && t->opval.val->sym
5804           && t->opval.val->sym->undefined)
5805         errors++;
5806
5807       errors += astErrors(t->left);
5808       errors += astErrors(t->right);
5809     }
5810     
5811   return errors;
5812 }