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