* src/hc08/ralloc.c (rematStr): fixed bug #879282
[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 code memory is read only, then pointers to code memory */
3237       /* implicitly point to constants -- make this explicit       */
3238       {
3239         sym_link *t = LTYPE(tree);
3240         while (t && t->next)
3241           {
3242             if (IS_CODEPTR(t) && port->mem.code_ro)
3243               {
3244                 if (IS_SPEC(t->next))
3245                   SPEC_CONST (t->next) = 1;
3246                 else
3247                   DCL_PTR_CONST (t->next) = 1;
3248               }
3249             t = t->next;
3250           }
3251       }
3252
3253 #if 0
3254       /* if the right is a literal replace the tree */
3255       if (IS_LITERAL (RETYPE (tree))) {
3256               if (!IS_PTR (LTYPE (tree))) {
3257                       tree->type = EX_VALUE;
3258                       tree->opval.val =
3259                               valCastLiteral (LTYPE (tree),
3260                                               floatFromVal (valFromType (RETYPE (tree))));
3261                       tree->left = NULL;
3262                       tree->right = NULL;
3263                       TTYPE (tree) = tree->opval.val->type;
3264                       tree->values.literalFromCast = 1;
3265               } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
3266                          ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
3267                       sym_link *rest = LTYPE(tree)->next;
3268                       werror(W_LITERAL_GENERIC);
3269                       TTYPE(tree) = newLink(DECLARATOR);
3270                       DCL_TYPE(TTYPE(tree)) = FPOINTER;
3271                       TTYPE(tree)->next = rest;
3272                       tree->left->opval.lnk = TTYPE(tree);
3273                       LRVAL (tree) = 1;
3274               } else {
3275                       TTYPE (tree) = LTYPE (tree);
3276                       LRVAL (tree) = 1;
3277               }
3278       } else {
3279               TTYPE (tree) = LTYPE (tree);
3280               LRVAL (tree) = 1;
3281       }
3282 #else
3283 #if 0 // this is already checked, now this could be explicit
3284       /* if pointer to struct then check names */
3285       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
3286           IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
3287           strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
3288         {
3289           werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
3290                  SPEC_STRUCT(LETYPE(tree))->tag);
3291         }
3292 #endif
3293       if (IS_ADDRESS_OF_OP(tree->right)
3294           && IS_AST_SYM_VALUE (tree->right->left)
3295           && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
3296
3297         tree->type = EX_VALUE;
3298         tree->opval.val =
3299           valCastLiteral (LTYPE (tree),
3300                           SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
3301         TTYPE (tree) = tree->opval.val->type;
3302         TETYPE (tree) = getSpec (TTYPE (tree));
3303         tree->left = NULL;
3304         tree->right = NULL;
3305         tree->values.literalFromCast = 1;
3306         return tree;
3307       }
3308
3309       /* handle offsetof macro:            */
3310       /* #define offsetof(TYPE, MEMBER) \  */
3311       /* ((unsigned) &((TYPE *)0)->MEMBER) */
3312       if (IS_ADDRESS_OF_OP(tree->right)
3313           && IS_AST_OP (tree->right->left)
3314           && tree->right->left->opval.op == PTR_OP
3315           && IS_AST_OP (tree->right->left->left)
3316           && tree->right->left->left->opval.op == CAST
3317           && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3318
3319         symbol *element = getStructElement (
3320           SPEC_STRUCT (LETYPE(tree->right->left)),
3321           AST_SYMBOL(tree->right->left->right)
3322         );
3323
3324         if (element) {
3325           tree->type = EX_VALUE;
3326           tree->opval.val = valCastLiteral (
3327             LTYPE (tree),
3328             element->offset
3329             + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3330           );
3331
3332           TTYPE (tree) = tree->opval.val->type;
3333           TETYPE (tree) = getSpec (TTYPE (tree));
3334           tree->left = NULL;
3335           tree->right = NULL;
3336           return tree;
3337         }
3338       }
3339
3340       /* if the right is a literal replace the tree */
3341       if (IS_LITERAL (RETYPE (tree))) {
3342         #if 0
3343         if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3344           /* rewrite      (type *)litaddr
3345              as           &temp
3346              and define   type at litaddr temp
3347              (but only if type's storage class is not generic)
3348           */
3349           ast *newTree = newNode ('&', NULL, NULL);
3350           symbol *sym;
3351
3352           TTYPE (newTree) = LTYPE (tree);
3353           TETYPE (newTree) = getSpec(LTYPE (tree));
3354
3355           /* define a global symbol at the casted address*/
3356           sym = newSymbol(genSymName (0), 0);
3357           sym->type = LTYPE (tree)->next;
3358           if (!sym->type)
3359             sym->type = newLink (V_VOID);
3360           sym->etype = getSpec(sym->type);
3361           SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3362           sym->lineDef = tree->lineno;
3363           sym->cdef = 1;
3364           sym->isref = 1;
3365           SPEC_STAT (sym->etype) = 1;
3366           SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3367           SPEC_ABSA(sym->etype) = 1;
3368           addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3369           allocGlobal (sym);
3370
3371           newTree->left = newAst_VALUE(symbolVal(sym));
3372           newTree->left->lineno = tree->lineno;
3373           LTYPE (newTree) = sym->type;
3374           LETYPE (newTree) = sym->etype;
3375           LLVAL (newTree) = 1;
3376           LRVAL (newTree) = 0;
3377           TLVAL (newTree) = 1;
3378           return newTree;
3379         }
3380         #endif
3381         if (!IS_PTR (LTYPE (tree))) {
3382           tree->type = EX_VALUE;
3383           tree->opval.val =
3384           valCastLiteral (LTYPE (tree),
3385                           floatFromVal (valFromType (RTYPE (tree))));
3386           TTYPE (tree) = tree->opval.val->type;
3387           tree->left = NULL;
3388           tree->right = NULL;
3389           tree->values.literalFromCast = 1;
3390           TETYPE (tree) = getSpec (TTYPE (tree));
3391           return tree;
3392         }
3393       }
3394       TTYPE (tree) = LTYPE (tree);
3395       LRVAL (tree) = 1;
3396
3397 #endif
3398       TETYPE (tree) = getSpec (TTYPE (tree));
3399
3400       return tree;
3401
3402       /*------------------------------------------------------------------*/
3403       /*----------------------------*/
3404       /*       logical &&, ||       */
3405       /*----------------------------*/
3406     case AND_OP:
3407     case OR_OP:
3408       /* each must me arithmetic type or be a pointer */
3409       if (!IS_PTR (LTYPE (tree)) &&
3410           !IS_ARRAY (LTYPE (tree)) &&
3411           !IS_INTEGRAL (LTYPE (tree)))
3412         {
3413           werror (E_COMPARE_OP);
3414           goto errorTreeReturn;
3415         }
3416
3417       if (!IS_PTR (RTYPE (tree)) &&
3418           !IS_ARRAY (RTYPE (tree)) &&
3419           !IS_INTEGRAL (RTYPE (tree)))
3420         {
3421           werror (E_COMPARE_OP);
3422           goto errorTreeReturn;
3423         }
3424       /* if they are both literal then */
3425       /* rewrite the tree */
3426       if (IS_LITERAL (RTYPE (tree)) &&
3427           IS_LITERAL (LTYPE (tree)))
3428         {
3429           tree->type = EX_VALUE;
3430           tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
3431                                            valFromType (RTYPE (tree)),
3432                                            tree->opval.op);
3433           tree->right = tree->left = NULL;
3434           TETYPE (tree) = getSpec (TTYPE (tree) =
3435                                    tree->opval.val->type);
3436           return tree;
3437         }
3438       LRVAL (tree) = RRVAL (tree) = 1;
3439       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3440       return tree;
3441
3442       /*------------------------------------------------------------------*/
3443       /*----------------------------*/
3444       /*     comparison operators   */
3445       /*----------------------------*/
3446     case '>':
3447     case '<':
3448     case LE_OP:
3449     case GE_OP:
3450     case EQ_OP:
3451     case NE_OP:
3452       {
3453         ast *lt = optimizeCompare (tree);
3454
3455         if (tree != lt)
3456           return lt;
3457       }
3458
3459       /* if they are pointers they must be castable */
3460       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3461         {
3462           if (tree->opval.op==EQ_OP &&
3463               !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
3464             // we cannot cast a gptr to a !gptr: switch the leaves
3465             struct ast *s=tree->left;
3466             tree->left=tree->right;
3467             tree->right=s;
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       /* else they should be promotable to one another */
3481       else
3482         {
3483           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
3484                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
3485
3486             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3487               {
3488                 werror (E_COMPARE_OP);
3489                 fprintf (stderr, "comparing type ");
3490                 printTypeChain (LTYPE (tree), stderr);
3491                 fprintf (stderr, "to type ");
3492                 printTypeChain (RTYPE (tree), stderr);
3493                 fprintf (stderr, "\n");
3494                 goto errorTreeReturn;
3495               }
3496         }
3497       /* if unsigned value < 0  then always false */
3498       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
3499       if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  &&
3500           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
3501         {
3502           if (tree->opval.op == '<')
3503             {
3504               return tree->right;
3505             }
3506           if (tree->opval.op == '>')
3507             {
3508               /* if the parent is an ifx, then we could do */
3509               /* return tree->left; */
3510               tree->opval.op = '?';
3511               tree->right = newNode (':',
3512                                      newAst_VALUE (constVal ("1")),
3513                                      tree->right); /* val 0 */
3514               tree->right->lineno = tree->lineno;
3515               tree->right->left->lineno = tree->lineno;
3516               decorateType (tree->right);
3517             }
3518         }
3519       /* if they are both literal then */
3520       /* rewrite the tree */
3521       if (IS_LITERAL (RTYPE (tree)) &&
3522           IS_LITERAL (LTYPE (tree)))
3523         {
3524           tree->type = EX_VALUE;
3525           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
3526                                         valFromType (RETYPE (tree)),
3527                                         tree->opval.op);
3528           tree->right = tree->left = NULL;
3529           TETYPE (tree) = getSpec (TTYPE (tree) =
3530                                    tree->opval.val->type);
3531           return tree;
3532         }
3533       LRVAL (tree) = RRVAL (tree) = 1;
3534       TTYPE (tree) = TETYPE (tree) = newCharLink ();
3535       return tree;
3536
3537       /*------------------------------------------------------------------*/
3538       /*----------------------------*/
3539       /*             sizeof         */
3540       /*----------------------------*/
3541     case SIZEOF:                /* evaluate wihout code generation */
3542       /* change the type to a integer */
3543       tree->type = EX_VALUE;
3544       SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
3545       tree->opval.val = constVal (buffer);
3546       tree->right = tree->left = NULL;
3547       TETYPE (tree) = getSpec (TTYPE (tree) =
3548                                tree->opval.val->type);
3549       return tree;
3550
3551       /*------------------------------------------------------------------*/
3552       /*----------------------------*/
3553       /*             typeof         */
3554       /*----------------------------*/
3555     case TYPEOF:
3556         /* return typeof enum value */
3557         tree->type = EX_VALUE;
3558         {
3559             int typeofv = 0;
3560             if (IS_SPEC(tree->right->ftype)) {
3561                 switch (SPEC_NOUN(tree->right->ftype)) {
3562                 case V_INT:
3563                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
3564                     else typeofv = TYPEOF_INT;
3565                     break;
3566                 case V_FLOAT:
3567                     typeofv = TYPEOF_FLOAT;
3568                     break;
3569                 case V_CHAR:
3570                     typeofv = TYPEOF_CHAR;
3571                     break;
3572                 case V_VOID:
3573                     typeofv = TYPEOF_VOID;
3574                     break;
3575                 case V_STRUCT:
3576                     typeofv = TYPEOF_STRUCT;
3577                     break;
3578                 case V_BITFIELD:
3579                     typeofv = TYPEOF_BITFIELD;
3580                     break;
3581                 case V_BIT:
3582                     typeofv = TYPEOF_BIT;
3583                     break;
3584                 case V_SBIT:
3585                     typeofv = TYPEOF_SBIT;
3586                     break;
3587                 default:
3588                     break;
3589                 }
3590             } else {
3591                 switch (DCL_TYPE(tree->right->ftype)) {
3592                 case POINTER:
3593                     typeofv = TYPEOF_POINTER;
3594                     break;
3595                 case FPOINTER:
3596                     typeofv = TYPEOF_FPOINTER;
3597                     break;
3598                 case CPOINTER:
3599                     typeofv = TYPEOF_CPOINTER;
3600                     break;
3601                 case GPOINTER:
3602                     typeofv = TYPEOF_GPOINTER;
3603                     break;
3604                 case PPOINTER:
3605                     typeofv = TYPEOF_PPOINTER;
3606                     break;
3607                 case IPOINTER:
3608                     typeofv = TYPEOF_IPOINTER;
3609                     break;
3610                 case ARRAY:
3611                     typeofv = TYPEOF_ARRAY;
3612                     break;
3613                 case FUNCTION:
3614                     typeofv = TYPEOF_FUNCTION;
3615                     break;
3616                 default:
3617                     break;
3618                 }
3619             }
3620             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
3621             tree->opval.val = constVal (buffer);
3622             tree->right = tree->left = NULL;
3623             TETYPE (tree) = getSpec (TTYPE (tree) =
3624                                      tree->opval.val->type);
3625         }
3626         return tree;
3627       /*------------------------------------------------------------------*/
3628       /*----------------------------*/
3629       /* conditional operator  '?'  */
3630       /*----------------------------*/
3631     case '?':
3632       /* the type is value of the colon operator (on the right) */
3633       assert(IS_COLON_OP(tree->right));
3634       /* if already known then replace the tree : optimizer will do it
3635          but faster to do it here */
3636       if (IS_LITERAL (LTYPE(tree))) {     
3637           if ( ((int) floatFromVal (valFromType (LETYPE (tree)))) != 0) {
3638               return decorateType(tree->right->left) ;
3639           } else {
3640               return decorateType(tree->right->right) ;
3641           }
3642       } else {
3643           tree->right = decorateType(tree->right);
3644           TTYPE (tree) = RTYPE(tree);
3645           TETYPE (tree) = getSpec (TTYPE (tree));
3646       }
3647       return tree;
3648
3649     case ':':
3650       /* if they don't match we have a problem */
3651       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3652         {
3653           werror (E_TYPE_MISMATCH, "conditional operator", " ");
3654           goto errorTreeReturn;
3655         }
3656
3657       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
3658       TETYPE (tree) = getSpec (TTYPE (tree));
3659       return tree;
3660
3661
3662 #if 0 // assignment operators are converted by the parser
3663       /*------------------------------------------------------------------*/
3664       /*----------------------------*/
3665       /*    assignment operators    */
3666       /*----------------------------*/
3667     case MUL_ASSIGN:
3668     case DIV_ASSIGN:
3669       /* for these it must be both must be integral */
3670       if (!IS_ARITHMETIC (LTYPE (tree)) ||
3671           !IS_ARITHMETIC (RTYPE (tree)))
3672         {
3673           werror (E_OPS_INTEGRAL);
3674           goto errorTreeReturn;
3675         }
3676       RRVAL (tree) = 1;
3677       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3678
3679       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
3680         werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3681
3682       if (LRVAL (tree))
3683         {
3684           werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
3685           goto errorTreeReturn;
3686         }
3687       LLVAL (tree) = 1;
3688
3689       return tree;
3690
3691     case AND_ASSIGN:
3692     case OR_ASSIGN:
3693     case XOR_ASSIGN:
3694     case RIGHT_ASSIGN:
3695     case LEFT_ASSIGN:
3696       /* for these it must be both must be integral */
3697       if (!IS_INTEGRAL (LTYPE (tree)) ||
3698           !IS_INTEGRAL (RTYPE (tree)))
3699         {
3700           werror (E_OPS_INTEGRAL);
3701           goto errorTreeReturn;
3702         }
3703       RRVAL (tree) = 1;
3704       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
3705
3706       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3707         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
3708
3709       if (LRVAL (tree))
3710         {
3711           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
3712           goto errorTreeReturn;
3713         }
3714       LLVAL (tree) = 1;
3715
3716       return tree;
3717
3718       /*------------------------------------------------------------------*/
3719       /*----------------------------*/
3720       /*    -= operator             */
3721       /*----------------------------*/
3722     case SUB_ASSIGN:
3723       if (!(IS_PTR (LTYPE (tree)) ||
3724             IS_ARITHMETIC (LTYPE (tree))))
3725         {
3726           werror (E_PLUS_INVALID, "-=");
3727           goto errorTreeReturn;
3728         }
3729
3730       if (!(IS_PTR (RTYPE (tree)) ||
3731             IS_ARITHMETIC (RTYPE (tree))))
3732         {
3733           werror (E_PLUS_INVALID, "-=");
3734           goto errorTreeReturn;
3735         }
3736       RRVAL (tree) = 1;
3737       TETYPE (tree) = getSpec (TTYPE (tree) =
3738                                computeType (LTYPE (tree),
3739                                             RTYPE (tree),
3740                                             FALSE));
3741
3742       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3743         werror (E_CODE_WRITE, "-=");
3744
3745       if (LRVAL (tree))
3746         {
3747           werror (E_LVALUE_REQUIRED, "-=");
3748           goto errorTreeReturn;
3749         }
3750       LLVAL (tree) = 1;
3751
3752       return tree;
3753
3754       /*------------------------------------------------------------------*/
3755       /*----------------------------*/
3756       /*          += operator       */
3757       /*----------------------------*/
3758     case ADD_ASSIGN:
3759       /* this is not a unary operation */
3760       /* if both pointers then problem */
3761       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
3762         {
3763           werror (E_PTR_PLUS_PTR);
3764           goto errorTreeReturn;
3765         }
3766
3767       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
3768         {
3769           werror (E_PLUS_INVALID, "+=");
3770           goto errorTreeReturn;
3771         }
3772
3773       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
3774         {
3775           werror (E_PLUS_INVALID, "+=");
3776           goto errorTreeReturn;
3777         }
3778       RRVAL (tree) = 1;
3779       TETYPE (tree) = getSpec (TTYPE (tree) =
3780                                computeType (LTYPE (tree),
3781                                             RTYPE (tree),
3782                                             FALSE));
3783
3784       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
3785         werror (E_CODE_WRITE, "+=");
3786
3787       if (LRVAL (tree))
3788         {
3789           werror (E_LVALUE_REQUIRED, "+=");
3790           goto errorTreeReturn;
3791         }
3792
3793       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right));
3794       tree->opval.op = '=';
3795
3796       return tree;
3797 #endif
3798
3799       /*------------------------------------------------------------------*/
3800       /*----------------------------*/
3801       /*      straight assignemnt   */
3802       /*----------------------------*/
3803     case '=':
3804       /* cannot be an aggregate */
3805       if (IS_AGGREGATE (LTYPE (tree)))
3806         {
3807           werror (E_AGGR_ASSIGN);
3808           goto errorTreeReturn;
3809         }
3810
3811       /* they should either match or be castable */
3812       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
3813         {
3814           werror (E_TYPE_MISMATCH, "assignment", " ");
3815           printFromToType(RTYPE(tree),LTYPE(tree));
3816         }
3817
3818       /* if the left side of the tree is of type void
3819          then report error */
3820       if (IS_VOID (LTYPE (tree)))
3821         {
3822           werror (E_CAST_ZERO);
3823           printFromToType(RTYPE(tree), LTYPE(tree));
3824         }
3825
3826       TETYPE (tree) = getSpec (TTYPE (tree) =
3827                                LTYPE (tree));
3828       RRVAL (tree) = 1;
3829       LLVAL (tree) = 1;
3830       if (!tree->initMode ) {
3831         if (IS_CONSTANT(LTYPE(tree)))
3832           werror (E_CODE_WRITE, "=");
3833       }
3834       if (LRVAL (tree))
3835         {
3836           werror (E_LVALUE_REQUIRED, "=");
3837           goto errorTreeReturn;
3838         }
3839
3840       return tree;
3841
3842       /*------------------------------------------------------------------*/
3843       /*----------------------------*/
3844       /*      comma operator        */
3845       /*----------------------------*/
3846     case ',':
3847       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
3848       return tree;
3849
3850       /*------------------------------------------------------------------*/
3851       /*----------------------------*/
3852       /*       function call        */
3853       /*----------------------------*/
3854     case CALL:
3855       parmNumber = 1;
3856
3857       if (processParms (tree->left,
3858                         FUNC_ARGS(tree->left->ftype),
3859                         tree->right, &parmNumber, TRUE)) {
3860         goto errorTreeReturn;
3861       }
3862
3863       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
3864           !IFFUNC_ISBUILTIN(LTYPE(tree)))
3865         {
3866           reverseParms (tree->right);
3867         }
3868
3869       if (IS_CODEPTR(LTYPE(tree))) {
3870         TTYPE(tree) = LTYPE(tree)->next->next;
3871       } else {
3872         TTYPE(tree) = LTYPE(tree)->next;
3873       }
3874       TETYPE (tree) = getSpec (TTYPE (tree));
3875       return tree;
3876
3877       /*------------------------------------------------------------------*/
3878       /*----------------------------*/
3879       /*     return statement       */
3880       /*----------------------------*/
3881     case RETURN:
3882       if (!tree->right)
3883         goto voidcheck;
3884
3885       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
3886         {
3887           werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
3888           printFromToType (RTYPE(tree), currFunc->type->next);
3889           goto errorTreeReturn;
3890         }
3891
3892       if (IS_VOID (currFunc->type->next)
3893           && tree->right &&
3894           !IS_VOID (RTYPE (tree)))
3895         {
3896           werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
3897           goto errorTreeReturn;
3898         }
3899
3900       /* if there is going to be a casing required then add it */
3901       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3902         {
3903           tree->right =
3904             decorateType (newNode (CAST,
3905                            newAst_LINK (copyLinkChain (currFunc->type->next)),
3906                                    tree->right));
3907         }
3908
3909       RRVAL (tree) = 1;
3910       return tree;
3911
3912     voidcheck:
3913
3914       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3915         {
3916           werror (W_VOID_FUNC, currFunc->name);
3917           goto errorTreeReturn;
3918         }
3919
3920       TTYPE (tree) = TETYPE (tree) = NULL;
3921       return tree;
3922
3923       /*------------------------------------------------------------------*/
3924       /*----------------------------*/
3925       /*     switch statement       */
3926       /*----------------------------*/
3927     case SWITCH:
3928       /* the switch value must be an integer */
3929       if (!IS_INTEGRAL (LTYPE (tree)))
3930         {
3931           werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
3932           goto errorTreeReturn;
3933         }
3934       LRVAL (tree) = 1;
3935       TTYPE (tree) = TETYPE (tree) = NULL;
3936       return tree;
3937
3938       /*------------------------------------------------------------------*/
3939       /*----------------------------*/
3940       /* ifx Statement              */
3941       /*----------------------------*/
3942     case IFX:
3943       tree->left = backPatchLabels (tree->left,
3944                                     tree->trueLabel,
3945                                     tree->falseLabel);
3946       TTYPE (tree) = TETYPE (tree) = NULL;
3947       return tree;
3948
3949       /*------------------------------------------------------------------*/
3950       /*----------------------------*/
3951       /* for Statement              */
3952       /*----------------------------*/
3953     case FOR:
3954
3955       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3956       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3957       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3958
3959       /* if the for loop is reversible then
3960          reverse it otherwise do what we normally
3961          do */
3962       {
3963         symbol *sym;
3964         ast *init, *end;
3965
3966         if (isLoopReversible (tree, &sym, &init, &end))
3967           return reverseLoop (tree, sym, init, end);
3968         else
3969           return decorateType (createFor (AST_FOR (tree, trueLabel),
3970                                           AST_FOR (tree, continueLabel),
3971                                           AST_FOR (tree, falseLabel),
3972                                           AST_FOR (tree, condLabel),
3973                                           AST_FOR (tree, initExpr),
3974                                           AST_FOR (tree, condExpr),
3975                                           AST_FOR (tree, loopExpr),
3976                                           tree->left));
3977       }
3978     default:
3979       TTYPE (tree) = TETYPE (tree) = NULL;
3980       return tree;
3981     }
3982
3983   /* some error found this tree will be killed */
3984 errorTreeReturn:
3985   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3986   tree->opval.op = NULLOP;
3987   tree->isError = 1;
3988
3989   return tree;
3990 }
3991
3992 /*-----------------------------------------------------------------*/
3993 /* sizeofOp - processes size of operation                          */
3994 /*-----------------------------------------------------------------*/
3995 value *
3996 sizeofOp (sym_link * type)
3997 {
3998   char buff[10];
3999
4000   /* make sure the type is complete and sane */
4001   checkTypeSanity(type, "(sizeof)");
4002
4003   /* get the size and convert it to character  */
4004   SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
4005
4006   /* now convert into value  */
4007   return constVal (buff);
4008 }
4009
4010
4011 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4012 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
4013 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4014 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4015 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4016 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
4017 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
4018
4019 /*-----------------------------------------------------------------*/
4020 /* backPatchLabels - change and or not operators to flow control    */
4021 /*-----------------------------------------------------------------*/
4022 ast *
4023 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4024 {
4025
4026   if (!tree)
4027     return NULL;
4028
4029   if (!(IS_ANDORNOT (tree)))
4030     return tree;
4031
4032   /* if this an and */
4033   if (IS_AND (tree))
4034     {
4035       static int localLbl = 0;
4036       symbol *localLabel;
4037
4038       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4039       localLabel = newSymbol (buffer, NestLevel);
4040
4041       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4042
4043       /* if left is already a IFX then just change the if true label in that */
4044       if (!IS_IFX (tree->left))
4045         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4046
4047       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4048       /* right is a IFX then just join */
4049       if (IS_IFX (tree->right))
4050         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4051
4052       tree->right = createLabel (localLabel, tree->right);
4053       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4054
4055       return newNode (NULLOP, tree->left, tree->right);
4056     }
4057
4058   /* if this is an or operation */
4059   if (IS_OR (tree))
4060     {
4061       static int localLbl = 0;
4062       symbol *localLabel;
4063
4064       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4065       localLabel = newSymbol (buffer, NestLevel);
4066
4067       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4068
4069       /* if left is already a IFX then just change the if true label in that */
4070       if (!IS_IFX (tree->left))
4071         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4072
4073       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4074       /* right is a IFX then just join */
4075       if (IS_IFX (tree->right))
4076         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4077
4078       tree->right = createLabel (localLabel, tree->right);
4079       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4080
4081       return newNode (NULLOP, tree->left, tree->right);
4082     }
4083
4084   /* change not */
4085   if (IS_NOT (tree))
4086     {
4087       int wasnot = IS_NOT (tree->left);
4088       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4089
4090       /* if the left is already a IFX */
4091       if (!IS_IFX (tree->left))
4092         tree->left = newNode (IFX, tree->left, NULL);
4093
4094       if (wasnot)
4095         {
4096           tree->left->trueLabel = trueLabel;
4097           tree->left->falseLabel = falseLabel;
4098         }
4099       else
4100         {
4101           tree->left->trueLabel = falseLabel;
4102           tree->left->falseLabel = trueLabel;
4103         }
4104       return tree->left;
4105     }
4106
4107   if (IS_IFX (tree))
4108     {
4109       tree->trueLabel = trueLabel;
4110       tree->falseLabel = falseLabel;
4111     }
4112
4113   return tree;
4114 }
4115
4116
4117 /*-----------------------------------------------------------------*/
4118 /* createBlock - create expression tree for block                  */
4119 /*-----------------------------------------------------------------*/
4120 ast *
4121 createBlock (symbol * decl, ast * body)
4122 {
4123   ast *ex;
4124
4125   /* if the block has nothing */
4126   if (!body && !decl)
4127     return NULL;
4128
4129   ex = newNode (BLOCK, NULL, body);
4130   ex->values.sym = decl;
4131   
4132   ex->right = ex->right;
4133   ex->level++;
4134   ex->lineno = 0;
4135   return ex;
4136 }
4137
4138 /*-----------------------------------------------------------------*/
4139 /* createLabel - creates the expression tree for labels            */
4140 /*-----------------------------------------------------------------*/
4141 ast *
4142 createLabel (symbol * label, ast * stmnt)
4143 {
4144   symbol *csym;
4145   char name[SDCC_NAME_MAX + 1];
4146   ast *rValue;
4147
4148   /* must create fresh symbol if the symbol name  */
4149   /* exists in the symbol table, since there can  */
4150   /* be a variable with the same name as the labl */
4151   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4152       (csym->level == label->level))
4153     label = newSymbol (label->name, label->level);
4154
4155   /* change the name before putting it in add _ */
4156   SNPRINTF(name, sizeof(name), "%s", label->name);
4157
4158   /* put the label in the LabelSymbol table    */
4159   /* but first check if a label of the same    */
4160   /* name exists                               */
4161   if ((csym = findSym (LabelTab, NULL, name)))
4162     werror (E_DUPLICATE_LABEL, label->name);
4163   else
4164     addSym (LabelTab, label, name, label->level, 0, 0);
4165
4166   label->islbl = 1;
4167   label->key = labelKey++;
4168   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4169   rValue->lineno = 0;
4170
4171   return rValue;
4172 }
4173
4174 /*-----------------------------------------------------------------*/
4175 /* createCase - generates the parsetree for a case statement       */
4176 /*-----------------------------------------------------------------*/
4177 ast *
4178 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4179 {
4180   char caseLbl[SDCC_NAME_MAX + 1];
4181   ast *rexpr;
4182   value *val;
4183
4184   /* if the switch statement does not exist */
4185   /* then case is out of context            */
4186   if (!swStat)
4187     {
4188       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4189       return NULL;
4190     }
4191
4192   caseVal = decorateType (resolveSymbols (caseVal));
4193   /* if not a constant then error  */
4194   if (!IS_LITERAL (caseVal->ftype))
4195     {
4196       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4197       return NULL;
4198     }
4199
4200   /* if not a integer than error */
4201   if (!IS_INTEGRAL (caseVal->ftype))
4202     {
4203       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4204       return NULL;
4205     }
4206
4207   /* find the end of the switch values chain   */
4208   if (!(val = swStat->values.switchVals.swVals))
4209     swStat->values.switchVals.swVals = caseVal->opval.val;
4210   else
4211     {
4212       /* also order the cases according to value */
4213       value *pval = NULL;
4214       int cVal = (int) floatFromVal (caseVal->opval.val);
4215       while (val && (int) floatFromVal (val) < cVal)
4216         {
4217           pval = val;
4218           val = val->next;
4219         }
4220
4221       /* if we reached the end then */
4222       if (!val)
4223         {
4224           pval->next = caseVal->opval.val;
4225         }
4226       else if ((int) floatFromVal (val) == cVal)
4227         {
4228           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4229                     "case");
4230           return NULL;
4231         }
4232       else
4233         {
4234           /* we found a value greater than */
4235           /* the current value we must add this */
4236           /* before the value */
4237           caseVal->opval.val->next = val;
4238
4239           /* if this was the first in chain */
4240           if (swStat->values.switchVals.swVals == val)
4241             swStat->values.switchVals.swVals =
4242               caseVal->opval.val;
4243           else
4244             pval->next = caseVal->opval.val;
4245         }
4246
4247     }
4248
4249   /* create the case label   */
4250   SNPRINTF(caseLbl, sizeof(caseLbl), 
4251            "_case_%d_%d",
4252            swStat->values.switchVals.swNum,
4253            (int) floatFromVal (caseVal->opval.val));
4254
4255   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
4256   rexpr->lineno = 0;
4257   return rexpr;
4258 }
4259
4260 /*-----------------------------------------------------------------*/
4261 /* createDefault - creates the parse tree for the default statement */
4262 /*-----------------------------------------------------------------*/
4263 ast *
4264 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
4265 {
4266   char defLbl[SDCC_NAME_MAX + 1];
4267
4268   /* if the switch statement does not exist */
4269   /* then case is out of context            */
4270   if (!swStat)
4271     {
4272       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
4273       return NULL;
4274     }
4275
4276   if (swStat->values.switchVals.swDefault)
4277     {
4278       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
4279                 "default");
4280       return NULL;
4281     }
4282
4283   /* turn on the default flag   */
4284   swStat->values.switchVals.swDefault = 1;
4285
4286   /* create the label  */
4287   SNPRINTF (defLbl, sizeof(defLbl),
4288             "_default_%d", swStat->values.switchVals.swNum);
4289   return createLabel (newSymbol (defLbl, 0), stmnt);
4290 }
4291
4292 /*-----------------------------------------------------------------*/
4293 /* createIf - creates the parsetree for the if statement           */
4294 /*-----------------------------------------------------------------*/
4295 ast *
4296 createIf (ast * condAst, ast * ifBody, ast * elseBody)
4297 {
4298   static int Lblnum = 0;
4299   ast *ifTree;
4300   symbol *ifTrue, *ifFalse, *ifEnd;
4301
4302   /* if neither exists */
4303   if (!elseBody && !ifBody) {
4304     // if there are no side effects (i++, j() etc)
4305     if (!hasSEFcalls(condAst)) {
4306       return condAst;
4307     }
4308   }
4309
4310   /* create the labels */
4311   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
4312   ifFalse = newSymbol (buffer, NestLevel);
4313   /* if no else body then end == false */
4314   if (!elseBody)
4315     ifEnd = ifFalse;
4316   else
4317     {
4318       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
4319       ifEnd = newSymbol (buffer, NestLevel);
4320     }
4321
4322   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
4323   ifTrue = newSymbol (buffer, NestLevel);
4324
4325   Lblnum++;
4326
4327   /* attach the ifTrue label to the top of it body */
4328   ifBody = createLabel (ifTrue, ifBody);
4329   /* attach a goto end to the ifBody if else is present */
4330   if (elseBody)
4331     {
4332       ifBody = newNode (NULLOP, ifBody,
4333                         newNode (GOTO,
4334                                  newAst_VALUE (symbolVal (ifEnd)),
4335                                  NULL));
4336       /* put the elseLabel on the else body */
4337       elseBody = createLabel (ifFalse, elseBody);
4338       /* out the end at the end of the body */
4339       elseBody = newNode (NULLOP,
4340                           elseBody,
4341                           createLabel (ifEnd, NULL));
4342     }
4343   else
4344     {
4345       ifBody = newNode (NULLOP, ifBody,
4346                         createLabel (ifFalse, NULL));
4347     }
4348   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
4349   if (IS_IFX (condAst))
4350     ifTree = condAst;
4351   else
4352     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
4353
4354   return newNode (NULLOP, ifTree,
4355                   newNode (NULLOP, ifBody, elseBody));
4356
4357 }
4358
4359 /*-----------------------------------------------------------------*/
4360 /* createDo - creates parse tree for do                            */
4361 /*        _dobody_n:                                               */
4362 /*            statements                                           */
4363 /*        _docontinue_n:                                           */
4364 /*            condition_expression +-> trueLabel -> _dobody_n      */
4365 /*                                 |                               */
4366 /*                                 +-> falseLabel-> _dobreak_n     */
4367 /*        _dobreak_n:                                              */
4368 /*-----------------------------------------------------------------*/
4369 ast *
4370 createDo (symbol * trueLabel, symbol * continueLabel,
4371           symbol * falseLabel, ast * condAst, ast * doBody)
4372 {
4373   ast *doTree;
4374
4375
4376   /* if the body does not exist then it is simple */
4377   if (!doBody)
4378     {
4379       condAst = backPatchLabels (condAst, continueLabel, NULL);
4380       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
4381                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
4382       doTree->trueLabel = continueLabel;
4383       doTree->falseLabel = NULL;
4384       return doTree;
4385     }
4386
4387   /* otherwise we have a body */
4388   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
4389
4390   /* attach the body label to the top */
4391   doBody = createLabel (trueLabel, doBody);
4392   /* attach the continue label to end of body */
4393   doBody = newNode (NULLOP, doBody,
4394                     createLabel (continueLabel, NULL));
4395
4396   /* now put the break label at the end */
4397   if (IS_IFX (condAst))
4398     doTree = condAst;
4399   else
4400     doTree = newIfxNode (condAst, trueLabel, falseLabel);
4401
4402   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
4403
4404   /* putting it together */
4405   return newNode (NULLOP, doBody, doTree);
4406 }
4407
4408 /*-----------------------------------------------------------------*/
4409 /* createFor - creates parse tree for 'for' statement              */
4410 /*        initExpr                                                 */
4411 /*   _forcond_n:                                                   */
4412 /*        condExpr  +-> trueLabel -> _forbody_n                    */
4413 /*                  |                                              */
4414 /*                  +-> falseLabel-> _forbreak_n                   */
4415 /*   _forbody_n:                                                   */
4416 /*        statements                                               */
4417 /*   _forcontinue_n:                                               */
4418 /*        loopExpr                                                 */
4419 /*        goto _forcond_n ;                                        */
4420 /*   _forbreak_n:                                                  */
4421 /*-----------------------------------------------------------------*/
4422 ast *
4423 createFor (symbol * trueLabel, symbol * continueLabel,
4424            symbol * falseLabel, symbol * condLabel,
4425            ast * initExpr, ast * condExpr, ast * loopExpr,
4426            ast * forBody)
4427 {
4428   ast *forTree;
4429
4430   /* if loopexpression not present then we can generate it */
4431   /* the same way as a while */
4432   if (!loopExpr)
4433     return newNode (NULLOP, initExpr,
4434                     createWhile (trueLabel, continueLabel,
4435                                  falseLabel, condExpr, forBody));
4436   /* vanilla for statement */
4437   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4438
4439   if (condExpr && !IS_IFX (condExpr))
4440     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
4441
4442
4443   /* attach condition label to condition */
4444   condExpr = createLabel (condLabel, condExpr);
4445
4446   /* attach body label to body */
4447   forBody = createLabel (trueLabel, forBody);
4448
4449   /* attach continue to forLoop expression & attach */
4450   /* goto the forcond @ and of loopExpression       */
4451   loopExpr = createLabel (continueLabel,
4452                           newNode (NULLOP,
4453                                    loopExpr,
4454                                    newNode (GOTO,
4455                                        newAst_VALUE (symbolVal (condLabel)),
4456                                             NULL)));
4457   /* now start putting them together */
4458   forTree = newNode (NULLOP, initExpr, condExpr);
4459   forTree = newNode (NULLOP, forTree, forBody);
4460   forTree = newNode (NULLOP, forTree, loopExpr);
4461   /* finally add the break label */
4462   forTree = newNode (NULLOP, forTree,
4463                      createLabel (falseLabel, NULL));
4464   return forTree;
4465 }
4466
4467 /*-----------------------------------------------------------------*/
4468 /* createWhile - creates parse tree for while statement            */
4469 /*               the while statement will be created as follows    */
4470 /*                                                                 */
4471 /*      _while_continue_n:                                         */
4472 /*            condition_expression +-> trueLabel -> _while_boby_n  */
4473 /*                                 |                               */
4474 /*                                 +-> falseLabel -> _while_break_n */
4475 /*      _while_body_n:                                             */
4476 /*            statements                                           */
4477 /*            goto _while_continue_n                               */
4478 /*      _while_break_n:                                            */
4479 /*-----------------------------------------------------------------*/
4480 ast *
4481 createWhile (symbol * trueLabel, symbol * continueLabel,
4482              symbol * falseLabel, ast * condExpr, ast * whileBody)
4483 {
4484   ast *whileTree;
4485
4486   /* put the continue label */
4487   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
4488   condExpr = createLabel (continueLabel, condExpr);
4489   condExpr->lineno = 0;
4490
4491   /* put the body label in front of the body */
4492   whileBody = createLabel (trueLabel, whileBody);
4493   whileBody->lineno = 0;
4494   /* put a jump to continue at the end of the body */
4495   /* and put break label at the end of the body */
4496   whileBody = newNode (NULLOP,
4497                        whileBody,
4498                        newNode (GOTO,
4499                                 newAst_VALUE (symbolVal (continueLabel)),
4500                                 createLabel (falseLabel, NULL)));
4501
4502   /* put it all together */
4503   if (IS_IFX (condExpr))
4504     whileTree = condExpr;
4505   else
4506     {
4507       whileTree = newNode (IFX, condExpr, NULL);
4508       /* put the true & false labels in place */
4509       whileTree->trueLabel = trueLabel;
4510       whileTree->falseLabel = falseLabel;
4511     }
4512
4513   return newNode (NULLOP, whileTree, whileBody);
4514 }
4515
4516 /*-----------------------------------------------------------------*/
4517 /* optimizeGetHbit - get highest order bit of the expression       */
4518 /*-----------------------------------------------------------------*/
4519 ast *
4520 optimizeGetHbit (ast * tree)
4521 {
4522   int i, j;
4523   /* if this is not a bit and */
4524   if (!IS_BITAND (tree))
4525     return tree;
4526
4527   /* will look for tree of the form
4528      ( expr >> ((sizeof expr) -1) ) & 1 */
4529   if (!IS_AST_LIT_VALUE (tree->right))
4530     return tree;
4531
4532   if (AST_LIT_VALUE (tree->right) != 1)
4533     return tree;
4534
4535   if (!IS_RIGHT_OP (tree->left))
4536     return tree;
4537
4538   if (!IS_AST_LIT_VALUE (tree->left->right))
4539     return tree;
4540
4541   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
4542       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
4543     return tree;
4544       
4545   /* make sure the port supports GETHBIT */
4546   if (port->hasExtBitOp
4547       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
4548     return tree;
4549
4550   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
4551
4552 }
4553
4554 /*-----------------------------------------------------------------*/
4555 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
4556 /*-----------------------------------------------------------------*/
4557 ast *
4558 optimizeRRCRLC (ast * root)
4559 {
4560   /* will look for trees of the form
4561      (?expr << 1) | (?expr >> 7) or
4562      (?expr >> 7) | (?expr << 1) will make that
4563      into a RLC : operation ..
4564      Will also look for
4565      (?expr >> 1) | (?expr << 7) or
4566      (?expr << 7) | (?expr >> 1) will make that
4567      into a RRC operation
4568      note : by 7 I mean (number of bits required to hold the
4569      variable -1 ) */
4570   /* if the root operations is not a | operation the not */
4571   if (!IS_BITOR (root))
4572     return root;
4573
4574   /* I have to think of a better way to match patterns this sucks */
4575   /* that aside let start looking for the first case : I use a the
4576      negative check a lot to improve the efficiency */
4577   /* (?expr << 1) | (?expr >> 7) */
4578   if (IS_LEFT_OP (root->left) &&
4579       IS_RIGHT_OP (root->right))
4580     {
4581
4582       if (!SPEC_USIGN (TETYPE (root->left->left)))
4583         return root;
4584
4585       if (!IS_AST_LIT_VALUE (root->left->right) ||
4586           !IS_AST_LIT_VALUE (root->right->right))
4587         goto tryNext0;
4588
4589       /* make sure it is the same expression */
4590       if (!isAstEqual (root->left->left,
4591                        root->right->left))
4592         goto tryNext0;
4593
4594       if (AST_LIT_VALUE (root->left->right) != 1)
4595         goto tryNext0;
4596
4597       if (AST_LIT_VALUE (root->right->right) !=
4598           (getSize (TTYPE (root->left->left)) * 8 - 1))
4599         goto tryNext0;
4600
4601       /* make sure the port supports RLC */
4602       if (port->hasExtBitOp
4603           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4604         return root;
4605
4606       /* whew got the first case : create the AST */
4607       return newNode (RLC, root->left->left, NULL);
4608     }
4609
4610 tryNext0:
4611   /* check for second case */
4612   /* (?expr >> 7) | (?expr << 1) */
4613   if (IS_LEFT_OP (root->right) &&
4614       IS_RIGHT_OP (root->left))
4615     {
4616
4617       if (!SPEC_USIGN (TETYPE (root->left->left)))
4618         return root;
4619
4620       if (!IS_AST_LIT_VALUE (root->left->right) ||
4621           !IS_AST_LIT_VALUE (root->right->right))
4622         goto tryNext1;
4623
4624       /* make sure it is the same symbol */
4625       if (!isAstEqual (root->left->left,
4626                        root->right->left))
4627         goto tryNext1;
4628
4629       if (AST_LIT_VALUE (root->right->right) != 1)
4630         goto tryNext1;
4631
4632       if (AST_LIT_VALUE (root->left->right) !=
4633           (getSize (TTYPE (root->left->left)) * 8 - 1))
4634         goto tryNext1;
4635
4636       /* make sure the port supports RLC */
4637       if (port->hasExtBitOp
4638           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
4639         return root;
4640
4641       /* whew got the first case : create the AST */
4642       return newNode (RLC, root->left->left, NULL);
4643
4644     }
4645
4646 tryNext1:
4647   /* third case for RRC */
4648   /*  (?symbol >> 1) | (?symbol << 7) */
4649   if (IS_LEFT_OP (root->right) &&
4650       IS_RIGHT_OP (root->left))
4651     {
4652
4653       if (!SPEC_USIGN (TETYPE (root->left->left)))
4654         return root;
4655
4656       if (!IS_AST_LIT_VALUE (root->left->right) ||
4657           !IS_AST_LIT_VALUE (root->right->right))
4658         goto tryNext2;
4659
4660       /* make sure it is the same symbol */
4661       if (!isAstEqual (root->left->left,
4662                        root->right->left))
4663         goto tryNext2;
4664
4665       if (AST_LIT_VALUE (root->left->right) != 1)
4666         goto tryNext2;
4667
4668       if (AST_LIT_VALUE (root->right->right) !=
4669           (getSize (TTYPE (root->left->left)) * 8 - 1))
4670         goto tryNext2;
4671
4672       /* make sure the port supports RRC */
4673       if (port->hasExtBitOp
4674           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4675         return root;
4676
4677       /* whew got the first case : create the AST */
4678       return newNode (RRC, root->left->left, NULL);
4679
4680     }
4681 tryNext2:
4682   /* fourth and last case for now */
4683   /* (?symbol << 7) | (?symbol >> 1) */
4684   if (IS_RIGHT_OP (root->right) &&
4685       IS_LEFT_OP (root->left))
4686     {
4687
4688       if (!SPEC_USIGN (TETYPE (root->left->left)))
4689         return root;
4690
4691       if (!IS_AST_LIT_VALUE (root->left->right) ||
4692           !IS_AST_LIT_VALUE (root->right->right))
4693         return root;
4694
4695       /* make sure it is the same symbol */
4696       if (!isAstEqual (root->left->left,
4697                        root->right->left))
4698         return root;
4699
4700       if (AST_LIT_VALUE (root->right->right) != 1)
4701         return root;
4702
4703       if (AST_LIT_VALUE (root->left->right) !=
4704           (getSize (TTYPE (root->left->left)) * 8 - 1))
4705         return root;
4706
4707       /* make sure the port supports RRC */
4708       if (port->hasExtBitOp
4709           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
4710         return root;
4711
4712       /* whew got the first case : create the AST */
4713       return newNode (RRC, root->left->left, NULL);
4714
4715     }
4716
4717   /* not found return root */
4718   return root;
4719 }
4720
4721 /*-----------------------------------------------------------------*/
4722 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
4723 /*-----------------------------------------------------------------*/
4724 ast *
4725 optimizeSWAP (ast * root)
4726 {
4727   /* will look for trees of the form
4728      (?expr << 4) | (?expr >> 4) or
4729      (?expr >> 4) | (?expr << 4) will make that
4730      into a SWAP : operation ..
4731      note : by 4 I mean (number of bits required to hold the
4732      variable /2 ) */
4733   /* if the root operations is not a | operation the not */
4734   if (!IS_BITOR (root))
4735     return root;
4736
4737   /* (?expr << 4) | (?expr >> 4) */
4738   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
4739       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
4740     {
4741
4742       if (!SPEC_USIGN (TETYPE (root->left->left)))
4743         return root;
4744
4745       if (!IS_AST_LIT_VALUE (root->left->right) ||
4746           !IS_AST_LIT_VALUE (root->right->right))
4747         return root;
4748
4749       /* make sure it is the same expression */
4750       if (!isAstEqual (root->left->left,
4751                        root->right->left))
4752         return root;
4753
4754       if (AST_LIT_VALUE (root->left->right) !=
4755           (getSize (TTYPE (root->left->left)) * 4))
4756         return root;
4757
4758       if (AST_LIT_VALUE (root->right->right) !=
4759           (getSize (TTYPE (root->left->left)) * 4))
4760         return root;
4761
4762       /* make sure the port supports SWAP */
4763       if (port->hasExtBitOp
4764           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
4765         return root;
4766
4767       /* found it : create the AST */
4768       return newNode (SWAP, root->left->left, NULL);
4769     }
4770
4771
4772   /* not found return root */
4773   return root;
4774 }
4775
4776 /*-----------------------------------------------------------------*/
4777 /* optimizeCompare - otimizes compares for bit variables     */
4778 /*-----------------------------------------------------------------*/
4779 static ast *
4780 optimizeCompare (ast * root)
4781 {
4782   ast *optExpr = NULL;
4783   value *vleft;
4784   value *vright;
4785   unsigned int litValue;
4786
4787   /* if nothing then return nothing */
4788   if (!root)
4789     return NULL;
4790
4791   /* if not a compare op then do leaves */
4792   if (!IS_COMPARE_OP (root))
4793     {
4794       root->left = optimizeCompare (root->left);
4795       root->right = optimizeCompare (root->right);
4796       return root;
4797     }
4798
4799   /* if left & right are the same then depending
4800      of the operation do */
4801   if (isAstEqual (root->left, root->right))
4802     {
4803       switch (root->opval.op)
4804         {
4805         case '>':
4806         case '<':
4807         case NE_OP:
4808           optExpr = newAst_VALUE (constVal ("0"));
4809           break;
4810         case GE_OP:
4811         case LE_OP:
4812         case EQ_OP:
4813           optExpr = newAst_VALUE (constVal ("1"));
4814           break;
4815         }
4816
4817       return decorateType (optExpr);
4818     }
4819
4820   vleft = (root->left->type == EX_VALUE ?
4821            root->left->opval.val : NULL);
4822
4823   vright = (root->right->type == EX_VALUE ?
4824             root->right->opval.val : NULL);
4825
4826   /* if left is a BITVAR in BITSPACE */
4827   /* and right is a LITERAL then opt- */
4828   /* imize else do nothing       */
4829   if (vleft && vright &&
4830       IS_BITVAR (vleft->etype) &&
4831       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4832       IS_LITERAL (vright->etype))
4833     {
4834
4835       /* if right side > 1 then comparison may never succeed */
4836       if ((litValue = (int) floatFromVal (vright)) > 1)
4837         {
4838           werror (W_BAD_COMPARE);
4839           goto noOptimize;
4840         }
4841
4842       if (litValue)
4843         {
4844           switch (root->opval.op)
4845             {
4846             case '>':           /* bit value greater than 1 cannot be */
4847               werror (W_BAD_COMPARE);
4848               goto noOptimize;
4849               break;
4850
4851             case '<':           /* bit value < 1 means 0 */
4852             case NE_OP:
4853               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4854               break;
4855
4856             case LE_OP: /* bit value <= 1 means no check */
4857               optExpr = newAst_VALUE (vright);
4858               break;
4859
4860             case GE_OP: /* bit value >= 1 means only check for = */
4861             case EQ_OP:
4862               optExpr = newAst_VALUE (vleft);
4863               break;
4864             }
4865         }
4866       else
4867         {                       /* literal is zero */
4868           switch (root->opval.op)
4869             {
4870             case '<':           /* bit value < 0 cannot be */
4871               werror (W_BAD_COMPARE);
4872               goto noOptimize;
4873               break;
4874
4875             case '>':           /* bit value > 0 means 1 */
4876             case NE_OP:
4877               optExpr = newAst_VALUE (vleft);
4878               break;
4879
4880             case LE_OP: /* bit value <= 0 means no check */
4881             case GE_OP: /* bit value >= 0 means no check */
4882               werror (W_BAD_COMPARE);
4883               goto noOptimize;
4884               break;
4885
4886             case EQ_OP: /* bit == 0 means ! of bit */
4887               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4888               break;
4889             }
4890         }
4891       return decorateType (resolveSymbols (optExpr));
4892     }                           /* end-of-if of BITVAR */
4893
4894 noOptimize:
4895   return root;
4896 }
4897 /*-----------------------------------------------------------------*/
4898 /* addSymToBlock : adds the symbol to the first block we find      */
4899 /*-----------------------------------------------------------------*/
4900 void 
4901 addSymToBlock (symbol * sym, ast * tree)
4902 {
4903   /* reached end of tree or a leaf */
4904   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4905     return;
4906
4907   /* found a block */
4908   if (IS_AST_OP (tree) &&
4909       tree->opval.op == BLOCK)
4910     {
4911
4912       symbol *lsym = copySymbol (sym);
4913
4914       lsym->next = AST_VALUES (tree, sym);
4915       AST_VALUES (tree, sym) = lsym;
4916       return;
4917     }
4918
4919   addSymToBlock (sym, tree->left);
4920   addSymToBlock (sym, tree->right);
4921 }
4922
4923 /*-----------------------------------------------------------------*/
4924 /* processRegParms - do processing for register parameters         */
4925 /*-----------------------------------------------------------------*/
4926 static void 
4927 processRegParms (value * args, ast * body)
4928 {
4929   while (args)
4930     {
4931       if (IS_REGPARM (args->etype))
4932         addSymToBlock (args->sym, body);
4933       args = args->next;
4934     }
4935 }
4936
4937 /*-----------------------------------------------------------------*/
4938 /* resetParmKey - resets the operandkeys for the symbols           */
4939 /*-----------------------------------------------------------------*/
4940 DEFSETFUNC (resetParmKey)
4941 {
4942   symbol *sym = item;
4943
4944   sym->key = 0;
4945   sym->defs = NULL;
4946   sym->uses = NULL;
4947   sym->remat = 0;
4948   return 1;
4949 }
4950
4951 /*-----------------------------------------------------------------*/
4952 /* createFunction - This is the key node that calls the iCode for  */
4953 /*                  generating the code for a function. Note code  */
4954 /*                  is generated function by function, later when  */
4955 /*                  add inter-procedural analysis this will change */
4956 /*-----------------------------------------------------------------*/
4957 ast *
4958 createFunction (symbol * name, ast * body)
4959 {
4960   ast *ex;
4961   symbol *csym;
4962   int stack = 0;
4963   sym_link *fetype;
4964   iCode *piCode = NULL;
4965
4966   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
4967     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
4968
4969   /* if check function return 0 then some problem */
4970   if (checkFunction (name, NULL) == 0)
4971     return NULL;
4972
4973   /* create a dummy block if none exists */
4974   if (!body)
4975     body = newNode (BLOCK, NULL, NULL);
4976
4977   noLineno++;
4978
4979   /* check if the function name already in the symbol table */
4980   if ((csym = findSym (SymbolTab, NULL, name->name)))
4981     {
4982       name = csym;
4983       /* special case for compiler defined functions
4984          we need to add the name to the publics list : this
4985          actually means we are now compiling the compiler
4986          support routine */
4987       if (name->cdef)
4988         {
4989           addSet (&publics, name);
4990         }
4991     }
4992   else
4993     {
4994       addSymChain (name);
4995       allocVariables (name);
4996     }
4997   name->lastLine = mylineno;
4998   currFunc = name;
4999
5000   /* set the stack pointer */
5001   /* PENDING: check this for the mcs51 */
5002   stackPtr = -port->stack.direction * port->stack.call_overhead;
5003   if (IFFUNC_ISISR (name->type))
5004     stackPtr -= port->stack.direction * port->stack.isr_overhead;
5005   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5006     stackPtr -= port->stack.direction * port->stack.reent_overhead;
5007
5008   xstackPtr = -port->stack.direction * port->stack.call_overhead;
5009
5010   fetype = getSpec (name->type);        /* get the specifier for the function */
5011   /* if this is a reentrant function then */
5012   if (IFFUNC_ISREENT (name->type))
5013     reentrant++;
5014
5015   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
5016
5017   /* do processing for parameters that are passed in registers */
5018   processRegParms (FUNC_ARGS(name->type), body);
5019
5020   /* set the stack pointer */
5021   stackPtr = 0;
5022   xstackPtr = -1;
5023
5024   /* allocate & autoinit the block variables */
5025   processBlockVars (body, &stack, ALLOCATE);
5026
5027   /* save the stack information */
5028   if (options.useXstack)
5029     name->xstack = SPEC_STAK (fetype) = stack;
5030   else
5031     name->stack = SPEC_STAK (fetype) = stack;
5032
5033   /* name needs to be mangled */
5034   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5035
5036   body = resolveSymbols (body); /* resolve the symbols */
5037   body = decorateType (body);   /* propagateType & do semantic checks */
5038
5039   ex = newAst_VALUE (symbolVal (name)); /* create name */
5040   ex = newNode (FUNCTION, ex, body);
5041   ex->values.args = FUNC_ARGS(name->type);
5042   ex->decorated=1;
5043   if (options.dump_tree) PA(ex);
5044   if (fatalError)
5045     {
5046       werror (E_FUNC_NO_CODE, name->name);
5047       goto skipall;
5048     }
5049
5050   /* create the node & generate intermediate code */
5051   GcurMemmap = code;
5052   codeOutFile = code->oFile;
5053   piCode = iCodeFromAst (ex);
5054
5055   if (fatalError)
5056     {
5057       werror (E_FUNC_NO_CODE, name->name);
5058       goto skipall;
5059     }
5060
5061   eBBlockFromiCode (piCode);
5062
5063   /* if there are any statics then do them */
5064   if (staticAutos)
5065     {
5066       GcurMemmap = statsg;
5067       codeOutFile = statsg->oFile;
5068       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
5069       staticAutos = NULL;
5070     }
5071
5072 skipall:
5073
5074   /* dealloc the block variables */
5075   processBlockVars (body, &stack, DEALLOCATE);
5076   outputDebugStackSymbols();
5077   /* deallocate paramaters */
5078   deallocParms (FUNC_ARGS(name->type));
5079
5080   if (IFFUNC_ISREENT (name->type))
5081     reentrant--;
5082
5083   /* we are done freeup memory & cleanup */
5084   noLineno--;
5085   if (port->reset_labelKey) labelKey = 1;
5086   name->key = 0;
5087   FUNC_HASBODY(name->type) = 1;
5088   addSet (&operKeyReset, name);
5089   applyToSet (operKeyReset, resetParmKey);
5090
5091   if (options.debug)
5092     cdbStructBlock(1);
5093
5094   cleanUpLevel (LabelTab, 0);
5095   cleanUpBlock (StructTab, 1);
5096   cleanUpBlock (TypedefTab, 1);
5097
5098   xstack->syms = NULL;
5099   istack->syms = NULL;
5100   return NULL;
5101 }
5102
5103
5104 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
5105 /*-----------------------------------------------------------------*/
5106 /* ast_print : prints the ast (for debugging purposes)             */
5107 /*-----------------------------------------------------------------*/
5108
5109 void ast_print (ast * tree, FILE *outfile, int indent)
5110 {
5111
5112         if (!tree) return ;
5113
5114         /* can print only decorated trees */
5115         if (!tree->decorated) return;
5116
5117         /* if any child is an error | this one is an error do nothing */
5118         if (tree->isError ||
5119             (tree->left && tree->left->isError) ||
5120             (tree->right && tree->right->isError)) {
5121                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
5122         }
5123
5124
5125         /* print the line          */
5126         /* if not block & function */
5127         if (tree->type == EX_OP &&
5128             (tree->opval.op != FUNCTION &&
5129              tree->opval.op != BLOCK &&
5130              tree->opval.op != NULLOP)) {
5131         }
5132
5133         if (tree->opval.op == FUNCTION) {
5134                 int arg=0;
5135                 value *args=FUNC_ARGS(tree->left->opval.val->type);
5136                 fprintf(outfile,"FUNCTION (%s=%p) type (",
5137                         tree->left->opval.val->name, tree);
5138                 printTypeChain (tree->left->opval.val->type->next,outfile);
5139                 fprintf(outfile,") args (");
5140                 do {
5141                   if (arg) {
5142                     fprintf (outfile, ", ");
5143                   }
5144                   printTypeChain (args ? args->type : NULL, outfile);
5145                   arg++;
5146                   args= args ? args->next : NULL;
5147                 } while (args);
5148                 fprintf(outfile,")\n");
5149                 ast_print(tree->left,outfile,indent);
5150                 ast_print(tree->right,outfile,indent);
5151                 return ;
5152         }
5153         if (tree->opval.op == BLOCK) {
5154                 symbol *decls = tree->values.sym;
5155                 INDENT(indent,outfile);
5156                 fprintf(outfile,"{\n");
5157                 while (decls) {
5158                         INDENT(indent+2,outfile);
5159                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
5160                                 decls->name, decls);
5161                         printTypeChain(decls->type,outfile);
5162                         fprintf(outfile,")\n");
5163
5164                         decls = decls->next;
5165                 }
5166                 ast_print(tree->right,outfile,indent+2);
5167                 INDENT(indent,outfile);
5168                 fprintf(outfile,"}\n");
5169                 return;
5170         }
5171         if (tree->opval.op == NULLOP) {
5172                 ast_print(tree->left,outfile,indent);
5173                 ast_print(tree->right,outfile,indent);
5174                 return ;
5175         }
5176         INDENT(indent,outfile);
5177
5178         /*------------------------------------------------------------------*/
5179         /*----------------------------*/
5180         /*   leaf has been reached    */
5181         /*----------------------------*/
5182         /* if this is of type value */
5183         /* just get the type        */
5184         if (tree->type == EX_VALUE) {
5185
5186                 if (IS_LITERAL (tree->opval.val->etype)) {
5187                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
5188                         if (SPEC_USIGN (tree->opval.val->etype))
5189                                 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
5190                         else
5191                                 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
5192                         fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
5193                                                       floatFromVal(tree->opval.val));
5194                 } else if (tree->opval.val->sym) {
5195                         /* if the undefined flag is set then give error message */
5196                         if (tree->opval.val->sym->undefined) {
5197                                 fprintf(outfile,"UNDEFINED SYMBOL ");
5198                         } else {
5199                                 fprintf(outfile,"SYMBOL ");
5200                         }
5201                         fprintf(outfile,"(%s=%p)",
5202                                 tree->opval.val->sym->name,tree);
5203                 }
5204                 if (tree->ftype) {
5205                         fprintf(outfile," type (");
5206                         printTypeChain(tree->ftype,outfile);
5207                         fprintf(outfile,")\n");
5208                 } else {
5209                         fprintf(outfile,"\n");
5210                 }
5211                 return ;
5212         }
5213
5214         /* if type link for the case of cast */
5215         if (tree->type == EX_LINK) {
5216                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
5217                 printTypeChain(tree->opval.lnk,outfile);
5218                 fprintf(outfile,")\n");
5219                 return ;
5220         }
5221
5222
5223         /* depending on type of operator do */
5224
5225         switch (tree->opval.op) {
5226                 /*------------------------------------------------------------------*/
5227                 /*----------------------------*/
5228                 /*        array node          */
5229                 /*----------------------------*/
5230         case '[':
5231                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
5232                 printTypeChain(tree->ftype,outfile);
5233                 fprintf(outfile,")\n");
5234                 ast_print(tree->left,outfile,indent+2);
5235                 ast_print(tree->right,outfile,indent+2);
5236                 return;
5237
5238                 /*------------------------------------------------------------------*/
5239                 /*----------------------------*/
5240                 /*      struct/union          */
5241                 /*----------------------------*/
5242         case '.':
5243                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
5244                 printTypeChain(tree->ftype,outfile);
5245                 fprintf(outfile,")\n");
5246                 ast_print(tree->left,outfile,indent+2);
5247                 ast_print(tree->right,outfile,indent+2);
5248                 return ;
5249
5250                 /*------------------------------------------------------------------*/
5251                 /*----------------------------*/
5252                 /*    struct/union pointer    */
5253                 /*----------------------------*/
5254         case PTR_OP:
5255                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
5256                 printTypeChain(tree->ftype,outfile);
5257                 fprintf(outfile,")\n");
5258                 ast_print(tree->left,outfile,indent+2);
5259                 ast_print(tree->right,outfile,indent+2);
5260                 return ;
5261
5262                 /*------------------------------------------------------------------*/
5263                 /*----------------------------*/
5264                 /*  ++/-- operation           */
5265                 /*----------------------------*/
5266         case INC_OP:
5267                 if (tree->left)
5268                   fprintf(outfile,"post-");
5269                 else
5270                   fprintf(outfile,"pre-");
5271                 fprintf(outfile,"INC_OP (%p) type (",tree);
5272                 printTypeChain(tree->ftype,outfile);
5273                 fprintf(outfile,")\n");
5274                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
5275                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
5276                 return ;
5277
5278         case DEC_OP:
5279                 if (tree->left)
5280                   fprintf(outfile,"post-");
5281                 else
5282                   fprintf(outfile,"pre-");
5283                 fprintf(outfile,"DEC_OP (%p) type (",tree);
5284                 printTypeChain(tree->ftype,outfile);
5285                 fprintf(outfile,")\n");
5286                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
5287                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
5288                 return ;
5289
5290                 /*------------------------------------------------------------------*/
5291                 /*----------------------------*/
5292                 /*  bitwise and               */
5293                 /*----------------------------*/
5294         case '&':
5295                 if (tree->right) {
5296                         fprintf(outfile,"& (%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                 } else {
5302                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
5303                         printTypeChain(tree->ftype,outfile);
5304                         fprintf(outfile,")\n");
5305                         ast_print(tree->left,outfile,indent+2);
5306                         ast_print(tree->right,outfile,indent+2);
5307                 }
5308                 return ;
5309                 /*----------------------------*/
5310                 /*  bitwise or                */
5311                 /*----------------------------*/
5312         case '|':
5313                 fprintf(outfile,"OR (%p) type (",tree);
5314                 printTypeChain(tree->ftype,outfile);
5315                 fprintf(outfile,")\n");
5316                 ast_print(tree->left,outfile,indent+2);
5317                 ast_print(tree->right,outfile,indent+2);
5318                 return ;
5319                 /*------------------------------------------------------------------*/
5320                 /*----------------------------*/
5321                 /*  bitwise xor               */
5322                 /*----------------------------*/
5323         case '^':
5324                 fprintf(outfile,"XOR (%p) type (",tree);
5325                 printTypeChain(tree->ftype,outfile);
5326                 fprintf(outfile,")\n");
5327                 ast_print(tree->left,outfile,indent+2);
5328                 ast_print(tree->right,outfile,indent+2);
5329                 return ;
5330
5331                 /*------------------------------------------------------------------*/
5332                 /*----------------------------*/
5333                 /*  division                  */
5334                 /*----------------------------*/
5335         case '/':
5336                 fprintf(outfile,"DIV (%p) type (",tree);
5337                 printTypeChain(tree->ftype,outfile);
5338                 fprintf(outfile,")\n");
5339                 ast_print(tree->left,outfile,indent+2);
5340                 ast_print(tree->right,outfile,indent+2);
5341                 return ;
5342                 /*------------------------------------------------------------------*/
5343                 /*----------------------------*/
5344                 /*            modulus         */
5345                 /*----------------------------*/
5346         case '%':
5347                 fprintf(outfile,"MOD (%p) type (",tree);
5348                 printTypeChain(tree->ftype,outfile);
5349                 fprintf(outfile,")\n");
5350                 ast_print(tree->left,outfile,indent+2);
5351                 ast_print(tree->right,outfile,indent+2);
5352                 return ;
5353
5354                 /*------------------------------------------------------------------*/
5355                 /*----------------------------*/
5356                 /*  address dereference       */
5357                 /*----------------------------*/
5358         case '*':                       /* can be unary  : if right is null then unary operation */
5359                 if (!tree->right) {
5360                         fprintf(outfile,"DEREF (%p) type (",tree);
5361                         printTypeChain(tree->ftype,outfile);
5362                         fprintf(outfile,")\n");
5363                         ast_print(tree->left,outfile,indent+2);
5364                         return ;
5365                 }                       
5366                 /*------------------------------------------------------------------*/
5367                 /*----------------------------*/
5368                 /*      multiplication        */
5369                 /*----------------------------*/                
5370                 fprintf(outfile,"MULT (%p) type (",tree);
5371                 printTypeChain(tree->ftype,outfile);
5372                 fprintf(outfile,")\n");
5373                 ast_print(tree->left,outfile,indent+2);
5374                 ast_print(tree->right,outfile,indent+2);
5375                 return ;
5376
5377
5378                 /*------------------------------------------------------------------*/
5379                 /*----------------------------*/
5380                 /*    unary '+' operator      */
5381                 /*----------------------------*/
5382         case '+':
5383                 /* if unary plus */
5384                 if (!tree->right) {
5385                         fprintf(outfile,"UPLUS (%p) type (",tree);
5386                         printTypeChain(tree->ftype,outfile);
5387                         fprintf(outfile,")\n");
5388                         ast_print(tree->left,outfile,indent+2);
5389                 } else {
5390                         /*------------------------------------------------------------------*/
5391                         /*----------------------------*/
5392                         /*      addition              */
5393                         /*----------------------------*/
5394                         fprintf(outfile,"ADD (%p) type (",tree);
5395                         printTypeChain(tree->ftype,outfile);
5396                         fprintf(outfile,")\n");
5397                         ast_print(tree->left,outfile,indent+2);
5398                         ast_print(tree->right,outfile,indent+2);
5399                 }
5400                 return;
5401                 /*------------------------------------------------------------------*/
5402                 /*----------------------------*/
5403                 /*      unary '-'             */
5404                 /*----------------------------*/
5405         case '-':                       /* can be unary   */
5406                 if (!tree->right) {
5407                         fprintf(outfile,"UMINUS (%p) type (",tree);
5408                         printTypeChain(tree->ftype,outfile);
5409                         fprintf(outfile,")\n");
5410                         ast_print(tree->left,outfile,indent+2);
5411                 } else {
5412                         /*------------------------------------------------------------------*/
5413                         /*----------------------------*/
5414                         /*      subtraction           */
5415                         /*----------------------------*/
5416                         fprintf(outfile,"SUB (%p) type (",tree);
5417                         printTypeChain(tree->ftype,outfile);
5418                         fprintf(outfile,")\n");
5419                         ast_print(tree->left,outfile,indent+2);
5420                         ast_print(tree->right,outfile,indent+2);
5421                 }
5422                 return;
5423                 /*------------------------------------------------------------------*/
5424                 /*----------------------------*/
5425                 /*    compliment              */
5426                 /*----------------------------*/
5427         case '~':
5428                 fprintf(outfile,"COMPL (%p) type (",tree);
5429                 printTypeChain(tree->ftype,outfile);
5430                 fprintf(outfile,")\n");
5431                 ast_print(tree->left,outfile,indent+2);
5432                 return ;
5433                 /*------------------------------------------------------------------*/
5434                 /*----------------------------*/
5435                 /*           not              */
5436                 /*----------------------------*/
5437         case '!':
5438                 fprintf(outfile,"NOT (%p) type (",tree);
5439                 printTypeChain(tree->ftype,outfile);
5440                 fprintf(outfile,")\n");
5441                 ast_print(tree->left,outfile,indent+2);
5442                 return ;
5443                 /*------------------------------------------------------------------*/
5444                 /*----------------------------*/
5445                 /*           shift            */
5446                 /*----------------------------*/
5447         case RRC:
5448                 fprintf(outfile,"RRC (%p) type (",tree);
5449                 printTypeChain(tree->ftype,outfile);
5450                 fprintf(outfile,")\n");
5451                 ast_print(tree->left,outfile,indent+2);
5452                 return ;
5453
5454         case RLC:
5455                 fprintf(outfile,"RLC (%p) type (",tree);
5456                 printTypeChain(tree->ftype,outfile);
5457                 fprintf(outfile,")\n");
5458                 ast_print(tree->left,outfile,indent+2);
5459                 return ;
5460         case SWAP:
5461                 fprintf(outfile,"SWAP (%p) type (",tree);
5462                 printTypeChain(tree->ftype,outfile);
5463                 fprintf(outfile,")\n");
5464                 ast_print(tree->left,outfile,indent+2);
5465                 return ;
5466         case GETHBIT:
5467                 fprintf(outfile,"GETHBIT (%p) type (",tree);
5468                 printTypeChain(tree->ftype,outfile);
5469                 fprintf(outfile,")\n");
5470                 ast_print(tree->left,outfile,indent+2);
5471                 return ;
5472         case LEFT_OP:
5473                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
5474                 printTypeChain(tree->ftype,outfile);
5475                 fprintf(outfile,")\n");
5476                 ast_print(tree->left,outfile,indent+2);
5477                 ast_print(tree->right,outfile,indent+2);
5478                 return ;
5479         case RIGHT_OP:
5480                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
5481                 printTypeChain(tree->ftype,outfile);
5482                 fprintf(outfile,")\n");
5483                 ast_print(tree->left,outfile,indent+2);
5484                 ast_print(tree->right,outfile,indent+2);
5485                 return ;
5486                 /*------------------------------------------------------------------*/
5487                 /*----------------------------*/
5488                 /*         casting            */
5489                 /*----------------------------*/
5490         case CAST:                      /* change the type   */
5491                 fprintf(outfile,"CAST (%p) from type (",tree);
5492                 printTypeChain(tree->right->ftype,outfile);
5493                 fprintf(outfile,") to type (");
5494                 printTypeChain(tree->ftype,outfile);
5495                 fprintf(outfile,")\n");
5496                 ast_print(tree->right,outfile,indent+2);
5497                 return ;
5498                 
5499         case AND_OP:
5500                 fprintf(outfile,"ANDAND (%p) type (",tree);
5501                 printTypeChain(tree->ftype,outfile);
5502                 fprintf(outfile,")\n");
5503                 ast_print(tree->left,outfile,indent+2);
5504                 ast_print(tree->right,outfile,indent+2);
5505                 return ;
5506         case OR_OP:
5507                 fprintf(outfile,"OROR (%p) type (",tree);
5508                 printTypeChain(tree->ftype,outfile);
5509                 fprintf(outfile,")\n");
5510                 ast_print(tree->left,outfile,indent+2);
5511                 ast_print(tree->right,outfile,indent+2);
5512                 return ;
5513                 
5514                 /*------------------------------------------------------------------*/
5515                 /*----------------------------*/
5516                 /*     comparison operators   */
5517                 /*----------------------------*/
5518         case '>':
5519                 fprintf(outfile,"GT(>) (%p) type (",tree);
5520                 printTypeChain(tree->ftype,outfile);
5521                 fprintf(outfile,")\n");
5522                 ast_print(tree->left,outfile,indent+2);
5523                 ast_print(tree->right,outfile,indent+2);
5524                 return ;
5525         case '<':
5526                 fprintf(outfile,"LT(<) (%p) type (",tree);
5527                 printTypeChain(tree->ftype,outfile);
5528                 fprintf(outfile,")\n");
5529                 ast_print(tree->left,outfile,indent+2);
5530                 ast_print(tree->right,outfile,indent+2);
5531                 return ;
5532         case LE_OP:
5533                 fprintf(outfile,"LE(<=) (%p) type (",tree);
5534                 printTypeChain(tree->ftype,outfile);
5535                 fprintf(outfile,")\n");
5536                 ast_print(tree->left,outfile,indent+2);
5537                 ast_print(tree->right,outfile,indent+2);
5538                 return ;
5539         case GE_OP:
5540                 fprintf(outfile,"GE(>=) (%p) type (",tree);
5541                 printTypeChain(tree->ftype,outfile);
5542                 fprintf(outfile,")\n");
5543                 ast_print(tree->left,outfile,indent+2);
5544                 ast_print(tree->right,outfile,indent+2);
5545                 return ;
5546         case EQ_OP:
5547                 fprintf(outfile,"EQ(==) (%p) type (",tree);
5548                 printTypeChain(tree->ftype,outfile);
5549                 fprintf(outfile,")\n");
5550                 ast_print(tree->left,outfile,indent+2);
5551                 ast_print(tree->right,outfile,indent+2);
5552                 return ;
5553         case NE_OP:
5554                 fprintf(outfile,"NE(!=) (%p) type (",tree);
5555                 printTypeChain(tree->ftype,outfile);
5556                 fprintf(outfile,")\n");
5557                 ast_print(tree->left,outfile,indent+2);
5558                 ast_print(tree->right,outfile,indent+2);
5559                 /*------------------------------------------------------------------*/
5560                 /*----------------------------*/
5561                 /*             sizeof         */
5562                 /*----------------------------*/
5563         case SIZEOF:            /* evaluate wihout code generation */
5564                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
5565                 return ;
5566
5567                 /*------------------------------------------------------------------*/
5568                 /*----------------------------*/
5569                 /* conditional operator  '?'  */
5570                 /*----------------------------*/
5571         case '?':
5572                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
5573                 printTypeChain(tree->ftype,outfile);
5574                 fprintf(outfile,")\n");
5575                 ast_print(tree->left,outfile,indent+2);
5576                 ast_print(tree->right,outfile,indent+2);
5577                 return;
5578
5579         case ':':
5580                 fprintf(outfile,"COLON(:) (%p) type (",tree);
5581                 printTypeChain(tree->ftype,outfile);
5582                 fprintf(outfile,")\n");
5583                 ast_print(tree->left,outfile,indent+2);
5584                 ast_print(tree->right,outfile,indent+2);
5585                 return ;
5586
5587                 /*------------------------------------------------------------------*/
5588                 /*----------------------------*/
5589                 /*    assignment operators    */
5590                 /*----------------------------*/
5591         case MUL_ASSIGN:
5592                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
5593                 printTypeChain(tree->ftype,outfile);
5594                 fprintf(outfile,")\n");
5595                 ast_print(tree->left,outfile,indent+2);
5596                 ast_print(tree->right,outfile,indent+2);
5597                 return;
5598         case DIV_ASSIGN:
5599                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
5600                 printTypeChain(tree->ftype,outfile);
5601                 fprintf(outfile,")\n");
5602                 ast_print(tree->left,outfile,indent+2);
5603                 ast_print(tree->right,outfile,indent+2);
5604                 return;
5605         case AND_ASSIGN:
5606                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
5607                 printTypeChain(tree->ftype,outfile);
5608                 fprintf(outfile,")\n");
5609                 ast_print(tree->left,outfile,indent+2);
5610                 ast_print(tree->right,outfile,indent+2);
5611                 return;
5612         case OR_ASSIGN:
5613                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
5614                 printTypeChain(tree->ftype,outfile);
5615                 fprintf(outfile,")\n");
5616                 ast_print(tree->left,outfile,indent+2);
5617                 ast_print(tree->right,outfile,indent+2);
5618                 return;
5619         case XOR_ASSIGN:
5620                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
5621                 printTypeChain(tree->ftype,outfile);
5622                 fprintf(outfile,")\n");
5623                 ast_print(tree->left,outfile,indent+2);
5624                 ast_print(tree->right,outfile,indent+2);
5625                 return;
5626         case RIGHT_ASSIGN:
5627                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
5628                 printTypeChain(tree->ftype,outfile);
5629                 fprintf(outfile,")\n");
5630                 ast_print(tree->left,outfile,indent+2);
5631                 ast_print(tree->right,outfile,indent+2);
5632                 return;
5633         case LEFT_ASSIGN:
5634                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
5635                 printTypeChain(tree->ftype,outfile);
5636                 fprintf(outfile,")\n");
5637                 ast_print(tree->left,outfile,indent+2);
5638                 ast_print(tree->right,outfile,indent+2);
5639                 return;
5640                 /*------------------------------------------------------------------*/
5641                 /*----------------------------*/
5642                 /*    -= operator             */
5643                 /*----------------------------*/
5644         case SUB_ASSIGN:
5645                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
5646                 printTypeChain(tree->ftype,outfile);
5647                 fprintf(outfile,")\n");
5648                 ast_print(tree->left,outfile,indent+2);
5649                 ast_print(tree->right,outfile,indent+2);
5650                 return;
5651                 /*------------------------------------------------------------------*/
5652                 /*----------------------------*/
5653                 /*          += operator       */
5654                 /*----------------------------*/
5655         case ADD_ASSIGN:
5656                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
5657                 printTypeChain(tree->ftype,outfile);
5658                 fprintf(outfile,")\n");
5659                 ast_print(tree->left,outfile,indent+2);
5660                 ast_print(tree->right,outfile,indent+2);
5661                 return;
5662                 /*------------------------------------------------------------------*/
5663                 /*----------------------------*/
5664                 /*      straight assignemnt   */
5665                 /*----------------------------*/
5666         case '=':
5667                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
5668                 printTypeChain(tree->ftype,outfile);
5669                 fprintf(outfile,")\n");
5670                 ast_print(tree->left,outfile,indent+2);
5671                 ast_print(tree->right,outfile,indent+2);
5672                 return;     
5673                 /*------------------------------------------------------------------*/
5674                 /*----------------------------*/
5675                 /*      comma operator        */
5676                 /*----------------------------*/
5677         case ',':
5678                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
5679                 printTypeChain(tree->ftype,outfile);
5680                 fprintf(outfile,")\n");
5681                 ast_print(tree->left,outfile,indent+2);
5682                 ast_print(tree->right,outfile,indent+2);
5683                 return;
5684                 /*------------------------------------------------------------------*/
5685                 /*----------------------------*/
5686                 /*       function call        */
5687                 /*----------------------------*/
5688         case CALL:
5689         case PCALL:
5690                 fprintf(outfile,"CALL (%p) type (",tree);
5691                 printTypeChain(tree->ftype,outfile);
5692                 fprintf(outfile,")\n");
5693                 ast_print(tree->left,outfile,indent+2);
5694                 ast_print(tree->right,outfile,indent+2);
5695                 return;
5696         case PARAM:
5697                 fprintf(outfile,"PARMS\n");
5698                 ast_print(tree->left,outfile,indent+2);
5699                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
5700                         ast_print(tree->right,outfile,indent+2);
5701                 }
5702                 return ;
5703                 /*------------------------------------------------------------------*/
5704                 /*----------------------------*/
5705                 /*     return statement       */
5706                 /*----------------------------*/
5707         case RETURN:
5708                 fprintf(outfile,"RETURN (%p) type (",tree);
5709                 if (tree->right) {
5710                     printTypeChain(tree->right->ftype,outfile);
5711                 }
5712                 fprintf(outfile,")\n");
5713                 ast_print(tree->right,outfile,indent+2);
5714                 return ;
5715                 /*------------------------------------------------------------------*/
5716                 /*----------------------------*/
5717                 /*     label statement        */
5718                 /*----------------------------*/
5719         case LABEL :
5720                 fprintf(outfile,"LABEL (%p)\n",tree);
5721                 ast_print(tree->left,outfile,indent+2);
5722                 ast_print(tree->right,outfile,indent);
5723                 return;
5724                 /*------------------------------------------------------------------*/
5725                 /*----------------------------*/
5726                 /*     switch statement       */
5727                 /*----------------------------*/
5728         case SWITCH:
5729                 {
5730                         value *val;
5731                         fprintf(outfile,"SWITCH (%p) ",tree);
5732                         ast_print(tree->left,outfile,0);
5733                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
5734                                 INDENT(indent+2,outfile);
5735                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
5736                                         (int) floatFromVal(val),
5737                                         tree->values.switchVals.swNum,
5738                                         (int) floatFromVal(val));
5739                         }
5740                         ast_print(tree->right,outfile,indent);
5741                 }
5742                 return ;
5743                 /*------------------------------------------------------------------*/
5744                 /*----------------------------*/
5745                 /* ifx Statement              */
5746                 /*----------------------------*/
5747         case IFX:
5748                 fprintf(outfile,"IF (%p) \n",tree);
5749                 ast_print(tree->left,outfile,indent+2);
5750                 if (tree->trueLabel) {
5751                         INDENT(indent+2,outfile);
5752                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
5753                 }
5754                 if (tree->falseLabel) {
5755                         INDENT(indent+2,outfile);
5756                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
5757                 }
5758                 ast_print(tree->right,outfile,indent+2);
5759                 return ;
5760                 /*----------------------------*/
5761                 /* goto Statement              */
5762                 /*----------------------------*/
5763         case GOTO:
5764                 fprintf(outfile,"GOTO (%p) \n",tree);
5765                 ast_print(tree->left,outfile,indent+2);
5766                 fprintf(outfile,"\n");
5767                 return ;
5768                 /*------------------------------------------------------------------*/
5769                 /*----------------------------*/
5770                 /* for Statement              */
5771                 /*----------------------------*/
5772         case FOR:
5773                 fprintf(outfile,"FOR (%p) \n",tree);
5774                 if (AST_FOR( tree, initExpr)) {
5775                         INDENT(indent+2,outfile);
5776                         fprintf(outfile,"INIT EXPR ");
5777                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
5778                 }
5779                 if (AST_FOR( tree, condExpr)) {
5780                         INDENT(indent+2,outfile);
5781                         fprintf(outfile,"COND EXPR ");
5782                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
5783                 }
5784                 if (AST_FOR( tree, loopExpr)) {
5785                         INDENT(indent+2,outfile);
5786                         fprintf(outfile,"LOOP EXPR ");
5787                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
5788                 }
5789                 fprintf(outfile,"FOR LOOP BODY \n");
5790                 ast_print(tree->left,outfile,indent+2);
5791                 return ;
5792         case CRITICAL:
5793                 fprintf(outfile,"CRITICAL (%p) \n",tree);
5794                 ast_print(tree->left,outfile,indent+2);
5795         default:
5796             return ;
5797         }
5798 }
5799
5800 void PA(ast *t)
5801 {
5802         ast_print(t,stdout,0);
5803 }
5804
5805
5806
5807 /*-----------------------------------------------------------------*/
5808 /* astErrors : returns non-zero if errors present in tree          */
5809 /*-----------------------------------------------------------------*/
5810 int astErrors(ast *t)
5811 {
5812   int errors=0;
5813   
5814   if (t)
5815     {
5816       if (t->isError)
5817         errors++;
5818   
5819       if (t->type == EX_VALUE
5820           && t->opval.val->sym
5821           && t->opval.val->sym->undefined)
5822         errors++;
5823
5824       errors += astErrors(t->left);
5825       errors += astErrors(t->right);
5826     }
5827     
5828   return errors;
5829 }