fixed bug #436360 part 2
[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           fprintf (stderr, "from type '");
3168           printTypeChain (RTYPE(tree), stderr);
3169           fprintf (stderr, "' to type '");
3170           printTypeChain (currFunc->type->next, stderr);
3171           fprintf (stderr, "'\n");
3172           goto errorTreeReturn;
3173         }
3174
3175       if (IS_VOID (currFunc->type->next)
3176           && tree->right &&
3177           !IS_VOID (RTYPE (tree)))
3178         {
3179           werror (E_FUNC_VOID);
3180           goto errorTreeReturn;
3181         }
3182
3183       /* if there is going to be a casing required then add it */
3184       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
3185         {
3186 #if 0 && defined DEMAND_INTEGER_PROMOTION
3187           if (IS_INTEGRAL (currFunc->type->next))
3188             {
3189               pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right));
3190             }
3191           else
3192 #endif
3193             {
3194               tree->right =
3195                 decorateType (newNode (CAST,
3196                          newAst_LINK (copyLinkChain (currFunc->type->next)),
3197                                        tree->right));
3198             }
3199         }
3200
3201       RRVAL (tree) = 1;
3202       return tree;
3203
3204     voidcheck:
3205
3206       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
3207         {
3208           werror (E_VOID_FUNC, currFunc->name);
3209           goto errorTreeReturn;
3210         }
3211
3212       TTYPE (tree) = TETYPE (tree) = NULL;
3213       return tree;
3214
3215 /*------------------------------------------------------------------*/
3216 /*----------------------------*/
3217       /*     switch statement       */
3218 /*----------------------------*/
3219     case SWITCH:
3220       /* the switch value must be an integer */
3221       if (!IS_INTEGRAL (LTYPE (tree)))
3222         {
3223           werror (E_SWITCH_NON_INTEGER);
3224           goto errorTreeReturn;
3225         }
3226       LRVAL (tree) = 1;
3227       TTYPE (tree) = TETYPE (tree) = NULL;
3228       return tree;
3229
3230 /*------------------------------------------------------------------*/
3231 /*----------------------------*/
3232       /* ifx Statement              */
3233 /*----------------------------*/
3234     case IFX:
3235       tree->left = backPatchLabels (tree->left,
3236                                     tree->trueLabel,
3237                                     tree->falseLabel);
3238       TTYPE (tree) = TETYPE (tree) = NULL;
3239       return tree;
3240
3241 /*------------------------------------------------------------------*/
3242 /*----------------------------*/
3243       /* for Statement              */
3244 /*----------------------------*/
3245     case FOR:
3246
3247       decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
3248       decorateType (resolveSymbols (AST_FOR (tree, condExpr)));
3249       decorateType (resolveSymbols (AST_FOR (tree, loopExpr)));
3250
3251       /* if the for loop is reversible then
3252          reverse it otherwise do what we normally
3253          do */
3254       {
3255         symbol *sym;
3256         ast *init, *end;
3257
3258         if (isLoopReversible (tree, &sym, &init, &end))
3259           return reverseLoop (tree, sym, init, end);
3260         else
3261           return decorateType (createFor (AST_FOR (tree, trueLabel),
3262                                           AST_FOR (tree, continueLabel),
3263                                           AST_FOR (tree, falseLabel),
3264                                           AST_FOR (tree, condLabel),
3265                                           AST_FOR (tree, initExpr),
3266                                           AST_FOR (tree, condExpr),
3267                                           AST_FOR (tree, loopExpr),
3268                                           tree->left));
3269       }
3270     default:
3271       TTYPE (tree) = TETYPE (tree) = NULL;
3272       return tree;
3273     }
3274
3275   /* some error found this tree will be killed */
3276 errorTreeReturn:
3277   TTYPE (tree) = TETYPE (tree) = newCharLink ();
3278   tree->opval.op = NULLOP;
3279   tree->isError = 1;
3280
3281   return tree;
3282 }
3283
3284 /*-----------------------------------------------------------------*/
3285 /* sizeofOp - processes size of operation                          */
3286 /*-----------------------------------------------------------------*/
3287 value *
3288 sizeofOp (sym_link * type)
3289 {
3290   char buff[10];
3291
3292   /* make sure the type is complete and sane */
3293   checkTypeSanity(type, "(sizeof)");
3294
3295   /* get the size and convert it to character  */
3296   sprintf (buff, "%d", getSize (type));
3297
3298   /* now convert into value  */
3299   return constVal (buff);
3300 }
3301
3302
3303 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
3304 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
3305 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
3306 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
3307 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
3308 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
3309 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
3310
3311 /*-----------------------------------------------------------------*/
3312 /* backPatchLabels - change and or not operators to flow control    */
3313 /*-----------------------------------------------------------------*/
3314 ast *
3315 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
3316 {
3317
3318   if (!tree)
3319     return NULL;
3320
3321   if (!(IS_ANDORNOT (tree)))
3322     return tree;
3323
3324   /* if this an and */
3325   if (IS_AND (tree))
3326     {
3327       static int localLbl = 0;
3328       symbol *localLabel;
3329
3330       sprintf (buffer, "_and_%d", localLbl++);
3331       localLabel = newSymbol (buffer, NestLevel);
3332
3333       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
3334
3335       /* if left is already a IFX then just change the if true label in that */
3336       if (!IS_IFX (tree->left))
3337         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
3338
3339       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3340       /* right is a IFX then just join */
3341       if (IS_IFX (tree->right))
3342         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3343
3344       tree->right = createLabel (localLabel, tree->right);
3345       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3346
3347       return newNode (NULLOP, tree->left, tree->right);
3348     }
3349
3350   /* if this is an or operation */
3351   if (IS_OR (tree))
3352     {
3353       static int localLbl = 0;
3354       symbol *localLabel;
3355
3356       sprintf (buffer, "_or_%d", localLbl++);
3357       localLabel = newSymbol (buffer, NestLevel);
3358
3359       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
3360
3361       /* if left is already a IFX then just change the if true label in that */
3362       if (!IS_IFX (tree->left))
3363         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
3364
3365       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
3366       /* right is a IFX then just join */
3367       if (IS_IFX (tree->right))
3368         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
3369
3370       tree->right = createLabel (localLabel, tree->right);
3371       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
3372
3373       return newNode (NULLOP, tree->left, tree->right);
3374     }
3375
3376   /* change not */
3377   if (IS_NOT (tree))
3378     {
3379       int wasnot = IS_NOT (tree->left);
3380       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
3381
3382       /* if the left is already a IFX */
3383       if (!IS_IFX (tree->left))
3384         tree->left = newNode (IFX, tree->left, NULL);
3385
3386       if (wasnot)
3387         {
3388           tree->left->trueLabel = trueLabel;
3389           tree->left->falseLabel = falseLabel;
3390         }
3391       else
3392         {
3393           tree->left->trueLabel = falseLabel;
3394           tree->left->falseLabel = trueLabel;
3395         }
3396       return tree->left;
3397     }
3398
3399   if (IS_IFX (tree))
3400     {
3401       tree->trueLabel = trueLabel;
3402       tree->falseLabel = falseLabel;
3403     }
3404
3405   return tree;
3406 }
3407
3408
3409 /*-----------------------------------------------------------------*/
3410 /* createBlock - create expression tree for block                  */
3411 /*-----------------------------------------------------------------*/
3412 ast *
3413 createBlock (symbol * decl, ast * body)
3414 {
3415   ast *ex;
3416
3417   /* if the block has nothing */
3418   if (!body)
3419     return NULL;
3420
3421   ex = newNode (BLOCK, NULL, body);
3422   ex->values.sym = decl;
3423
3424   ex->right = ex->right;
3425   ex->level++;
3426   ex->lineno = 0;
3427   return ex;
3428 }
3429
3430 /*-----------------------------------------------------------------*/
3431 /* createLabel - creates the expression tree for labels            */
3432 /*-----------------------------------------------------------------*/
3433 ast *
3434 createLabel (symbol * label, ast * stmnt)
3435 {
3436   symbol *csym;
3437   char name[SDCC_NAME_MAX + 1];
3438   ast *rValue;
3439
3440   /* must create fresh symbol if the symbol name  */
3441   /* exists in the symbol table, since there can  */
3442   /* be a variable with the same name as the labl */
3443   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
3444       (csym->level == label->level))
3445     label = newSymbol (label->name, label->level);
3446
3447   /* change the name before putting it in add _ */
3448   sprintf (name, "%s", label->name);
3449
3450   /* put the label in the LabelSymbol table    */
3451   /* but first check if a label of the same    */
3452   /* name exists                               */
3453   if ((csym = findSym (LabelTab, NULL, name)))
3454     werror (E_DUPLICATE_LABEL, label->name);
3455   else
3456     addSym (LabelTab, label, name, label->level, 0, 0);
3457
3458   label->islbl = 1;
3459   label->key = labelKey++;
3460   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
3461   rValue->lineno = 0;
3462
3463   return rValue;
3464 }
3465
3466 /*-----------------------------------------------------------------*/
3467 /* createCase - generates the parsetree for a case statement       */
3468 /*-----------------------------------------------------------------*/
3469 ast *
3470 createCase (ast * swStat, ast * caseVal, ast * stmnt)
3471 {
3472   char caseLbl[SDCC_NAME_MAX + 1];
3473   ast *rexpr;
3474   value *val;
3475
3476   /* if the switch statement does not exist */
3477   /* then case is out of context            */
3478   if (!swStat)
3479     {
3480       werror (E_CASE_CONTEXT);
3481       return NULL;
3482     }
3483
3484   caseVal = decorateType (resolveSymbols (caseVal));
3485   /* if not a constant then error  */
3486   if (!IS_LITERAL (caseVal->ftype))
3487     {
3488       werror (E_CASE_CONSTANT);
3489       return NULL;
3490     }
3491
3492   /* if not a integer than error */
3493   if (!IS_INTEGRAL (caseVal->ftype))
3494     {
3495       werror (E_CASE_NON_INTEGER);
3496       return NULL;
3497     }
3498
3499   /* find the end of the switch values chain   */
3500   if (!(val = swStat->values.switchVals.swVals))
3501     swStat->values.switchVals.swVals = caseVal->opval.val;
3502   else
3503     {
3504       /* also order the cases according to value */
3505       value *pval = NULL;
3506       int cVal = (int) floatFromVal (caseVal->opval.val);
3507       while (val && (int) floatFromVal (val) < cVal)
3508         {
3509           pval = val;
3510           val = val->next;
3511         }
3512
3513       /* if we reached the end then */
3514       if (!val)
3515         {
3516           pval->next = caseVal->opval.val;
3517         }
3518       else
3519         {
3520           /* we found a value greater than */
3521           /* the current value we must add this */
3522           /* before the value */
3523           caseVal->opval.val->next = val;
3524
3525           /* if this was the first in chain */
3526           if (swStat->values.switchVals.swVals == val)
3527             swStat->values.switchVals.swVals =
3528               caseVal->opval.val;
3529           else
3530             pval->next = caseVal->opval.val;
3531         }
3532
3533     }
3534
3535   /* create the case label   */
3536   sprintf (caseLbl, "_case_%d_%d",
3537            swStat->values.switchVals.swNum,
3538            (int) floatFromVal (caseVal->opval.val));
3539
3540   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
3541   rexpr->lineno = 0;
3542   return rexpr;
3543 }
3544
3545 /*-----------------------------------------------------------------*/
3546 /* createDefault - creates the parse tree for the default statement */
3547 /*-----------------------------------------------------------------*/
3548 ast *
3549 createDefault (ast * swStat, ast * stmnt)
3550 {
3551   char defLbl[SDCC_NAME_MAX + 1];
3552
3553   /* if the switch statement does not exist */
3554   /* then case is out of context            */
3555   if (!swStat)
3556     {
3557       werror (E_CASE_CONTEXT);
3558       return NULL;
3559     }
3560
3561   /* turn on the default flag   */
3562   swStat->values.switchVals.swDefault = 1;
3563
3564   /* create the label  */
3565   sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
3566   return createLabel (newSymbol (defLbl, 0), stmnt);
3567 }
3568
3569 /*-----------------------------------------------------------------*/
3570 /* createIf - creates the parsetree for the if statement           */
3571 /*-----------------------------------------------------------------*/
3572 ast *
3573 createIf (ast * condAst, ast * ifBody, ast * elseBody)
3574 {
3575   static int Lblnum = 0;
3576   ast *ifTree;
3577   symbol *ifTrue, *ifFalse, *ifEnd;
3578
3579   /* if neither exists */
3580   if (!elseBody && !ifBody)
3581     return condAst;
3582
3583   /* create the labels */
3584   sprintf (buffer, "_iffalse_%d", Lblnum);
3585   ifFalse = newSymbol (buffer, NestLevel);
3586   /* if no else body then end == false */
3587   if (!elseBody)
3588     ifEnd = ifFalse;
3589   else
3590     {
3591       sprintf (buffer, "_ifend_%d", Lblnum);
3592       ifEnd = newSymbol (buffer, NestLevel);
3593     }
3594
3595   sprintf (buffer, "_iftrue_%d", Lblnum);
3596   ifTrue = newSymbol (buffer, NestLevel);
3597
3598   Lblnum++;
3599
3600   /* attach the ifTrue label to the top of it body */
3601   ifBody = createLabel (ifTrue, ifBody);
3602   /* attach a goto end to the ifBody if else is present */
3603   if (elseBody)
3604     {
3605       ifBody = newNode (NULLOP, ifBody,
3606                         newNode (GOTO,
3607                                  newAst_VALUE (symbolVal (ifEnd)),
3608                                  NULL));
3609       /* put the elseLabel on the else body */
3610       elseBody = createLabel (ifFalse, elseBody);
3611       /* out the end at the end of the body */
3612       elseBody = newNode (NULLOP,
3613                           elseBody,
3614                           createLabel (ifEnd, NULL));
3615     }
3616   else
3617     {
3618       ifBody = newNode (NULLOP, ifBody,
3619                         createLabel (ifFalse, NULL));
3620     }
3621   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
3622   if (IS_IFX (condAst))
3623     ifTree = condAst;
3624   else
3625     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
3626
3627   return newNode (NULLOP, ifTree,
3628                   newNode (NULLOP, ifBody, elseBody));
3629
3630 }
3631
3632 /*-----------------------------------------------------------------*/
3633 /* createDo - creates parse tree for do                            */
3634 /*        _dobody_n:                                               */
3635 /*            statements                                           */
3636 /*        _docontinue_n:                                           */
3637 /*            condition_expression +-> trueLabel -> _dobody_n      */
3638 /*                                 |                               */
3639 /*                                 +-> falseLabel-> _dobreak_n     */
3640 /*        _dobreak_n:                                              */
3641 /*-----------------------------------------------------------------*/
3642 ast *
3643 createDo (symbol * trueLabel, symbol * continueLabel,
3644           symbol * falseLabel, ast * condAst, ast * doBody)
3645 {
3646   ast *doTree;
3647
3648
3649   /* if the body does not exist then it is simple */
3650   if (!doBody)
3651     {
3652       condAst = backPatchLabels (condAst, continueLabel, NULL);
3653       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
3654                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
3655       doTree->trueLabel = continueLabel;
3656       doTree->falseLabel = NULL;
3657       return doTree;
3658     }
3659
3660   /* otherwise we have a body */
3661   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
3662
3663   /* attach the body label to the top */
3664   doBody = createLabel (trueLabel, doBody);
3665   /* attach the continue label to end of body */
3666   doBody = newNode (NULLOP, doBody,
3667                     createLabel (continueLabel, NULL));
3668
3669   /* now put the break label at the end */
3670   if (IS_IFX (condAst))
3671     doTree = condAst;
3672   else
3673     doTree = newIfxNode (condAst, trueLabel, falseLabel);
3674
3675   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
3676
3677   /* putting it together */
3678   return newNode (NULLOP, doBody, doTree);
3679 }
3680
3681 /*-----------------------------------------------------------------*/
3682 /* createFor - creates parse tree for 'for' statement              */
3683 /*        initExpr                                                 */
3684 /*   _forcond_n:                                                   */
3685 /*        condExpr  +-> trueLabel -> _forbody_n                    */
3686 /*                  |                                              */
3687 /*                  +-> falseLabel-> _forbreak_n                   */
3688 /*   _forbody_n:                                                   */
3689 /*        statements                                               */
3690 /*   _forcontinue_n:                                               */
3691 /*        loopExpr                                                 */
3692 /*        goto _forcond_n ;                                        */
3693 /*   _forbreak_n:                                                  */
3694 /*-----------------------------------------------------------------*/
3695 ast *
3696 createFor (symbol * trueLabel, symbol * continueLabel,
3697            symbol * falseLabel, symbol * condLabel,
3698            ast * initExpr, ast * condExpr, ast * loopExpr,
3699            ast * forBody)
3700 {
3701   ast *forTree;
3702
3703   /* if loopexpression not present then we can generate it */
3704   /* the same way as a while */
3705   if (!loopExpr)
3706     return newNode (NULLOP, initExpr,
3707                     createWhile (trueLabel, continueLabel,
3708                                  falseLabel, condExpr, forBody));
3709   /* vanilla for statement */
3710   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3711
3712   if (condExpr && !IS_IFX (condExpr))
3713     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
3714
3715
3716   /* attach condition label to condition */
3717   condExpr = createLabel (condLabel, condExpr);
3718
3719   /* attach body label to body */
3720   forBody = createLabel (trueLabel, forBody);
3721
3722   /* attach continue to forLoop expression & attach */
3723   /* goto the forcond @ and of loopExpression       */
3724   loopExpr = createLabel (continueLabel,
3725                           newNode (NULLOP,
3726                                    loopExpr,
3727                                    newNode (GOTO,
3728                                        newAst_VALUE (symbolVal (condLabel)),
3729                                             NULL)));
3730   /* now start putting them together */
3731   forTree = newNode (NULLOP, initExpr, condExpr);
3732   forTree = newNode (NULLOP, forTree, forBody);
3733   forTree = newNode (NULLOP, forTree, loopExpr);
3734   /* finally add the break label */
3735   forTree = newNode (NULLOP, forTree,
3736                      createLabel (falseLabel, NULL));
3737   return forTree;
3738 }
3739
3740 /*-----------------------------------------------------------------*/
3741 /* createWhile - creates parse tree for while statement            */
3742 /*               the while statement will be created as follows    */
3743 /*                                                                 */
3744 /*      _while_continue_n:                                         */
3745 /*            condition_expression +-> trueLabel -> _while_boby_n  */
3746 /*                                 |                               */
3747 /*                                 +-> falseLabel -> _while_break_n */
3748 /*      _while_body_n:                                             */
3749 /*            statements                                           */
3750 /*            goto _while_continue_n                               */
3751 /*      _while_break_n:                                            */
3752 /*-----------------------------------------------------------------*/
3753 ast *
3754 createWhile (symbol * trueLabel, symbol * continueLabel,
3755              symbol * falseLabel, ast * condExpr, ast * whileBody)
3756 {
3757   ast *whileTree;
3758
3759   /* put the continue label */
3760   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
3761   condExpr = createLabel (continueLabel, condExpr);
3762   condExpr->lineno = 0;
3763
3764   /* put the body label in front of the body */
3765   whileBody = createLabel (trueLabel, whileBody);
3766   whileBody->lineno = 0;
3767   /* put a jump to continue at the end of the body */
3768   /* and put break label at the end of the body */
3769   whileBody = newNode (NULLOP,
3770                        whileBody,
3771                        newNode (GOTO,
3772                                 newAst_VALUE (symbolVal (continueLabel)),
3773                                 createLabel (falseLabel, NULL)));
3774
3775   /* put it all together */
3776   if (IS_IFX (condExpr))
3777     whileTree = condExpr;
3778   else
3779     {
3780       whileTree = newNode (IFX, condExpr, NULL);
3781       /* put the true & false labels in place */
3782       whileTree->trueLabel = trueLabel;
3783       whileTree->falseLabel = falseLabel;
3784     }
3785
3786   return newNode (NULLOP, whileTree, whileBody);
3787 }
3788
3789 /*-----------------------------------------------------------------*/
3790 /* optimizeGetHbit - get highest order bit of the expression       */
3791 /*-----------------------------------------------------------------*/
3792 ast *
3793 optimizeGetHbit (ast * tree)
3794 {
3795   int i, j;
3796   /* if this is not a bit and */
3797   if (!IS_BITAND (tree))
3798     return tree;
3799
3800   /* will look for tree of the form
3801      ( expr >> ((sizeof expr) -1) ) & 1 */
3802   if (!IS_AST_LIT_VALUE (tree->right))
3803     return tree;
3804
3805   if (AST_LIT_VALUE (tree->right) != 1)
3806     return tree;
3807
3808   if (!IS_RIGHT_OP (tree->left))
3809     return tree;
3810
3811   if (!IS_AST_LIT_VALUE (tree->left->right))
3812     return tree;
3813
3814   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
3815       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
3816     return tree;
3817
3818   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
3819
3820 }
3821
3822 /*-----------------------------------------------------------------*/
3823 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
3824 /*-----------------------------------------------------------------*/
3825 ast *
3826 optimizeRRCRLC (ast * root)
3827 {
3828   /* will look for trees of the form
3829      (?expr << 1) | (?expr >> 7) or
3830      (?expr >> 7) | (?expr << 1) will make that
3831      into a RLC : operation ..
3832      Will also look for
3833      (?expr >> 1) | (?expr << 7) or
3834      (?expr << 7) | (?expr >> 1) will make that
3835      into a RRC operation
3836      note : by 7 I mean (number of bits required to hold the
3837      variable -1 ) */
3838   /* if the root operations is not a | operation the not */
3839   if (!IS_BITOR (root))
3840     return root;
3841
3842   /* I have to think of a better way to match patterns this sucks */
3843   /* that aside let start looking for the first case : I use a the
3844      negative check a lot to improve the efficiency */
3845   /* (?expr << 1) | (?expr >> 7) */
3846   if (IS_LEFT_OP (root->left) &&
3847       IS_RIGHT_OP (root->right))
3848     {
3849
3850       if (!SPEC_USIGN (TETYPE (root->left->left)))
3851         return root;
3852
3853       if (!IS_AST_LIT_VALUE (root->left->right) ||
3854           !IS_AST_LIT_VALUE (root->right->right))
3855         goto tryNext0;
3856
3857       /* make sure it is the same expression */
3858       if (!isAstEqual (root->left->left,
3859                        root->right->left))
3860         goto tryNext0;
3861
3862       if (AST_LIT_VALUE (root->left->right) != 1)
3863         goto tryNext0;
3864
3865       if (AST_LIT_VALUE (root->right->right) !=
3866           (getSize (TTYPE (root->left->left)) * 8 - 1))
3867         goto tryNext0;
3868
3869       /* whew got the first case : create the AST */
3870       return newNode (RLC, root->left->left, NULL);
3871     }
3872
3873 tryNext0:
3874   /* check for second case */
3875   /* (?expr >> 7) | (?expr << 1) */
3876   if (IS_LEFT_OP (root->right) &&
3877       IS_RIGHT_OP (root->left))
3878     {
3879
3880       if (!SPEC_USIGN (TETYPE (root->left->left)))
3881         return root;
3882
3883       if (!IS_AST_LIT_VALUE (root->left->right) ||
3884           !IS_AST_LIT_VALUE (root->right->right))
3885         goto tryNext1;
3886
3887       /* make sure it is the same symbol */
3888       if (!isAstEqual (root->left->left,
3889                        root->right->left))
3890         goto tryNext1;
3891
3892       if (AST_LIT_VALUE (root->right->right) != 1)
3893         goto tryNext1;
3894
3895       if (AST_LIT_VALUE (root->left->right) !=
3896           (getSize (TTYPE (root->left->left)) * 8 - 1))
3897         goto tryNext1;
3898
3899       /* whew got the first case : create the AST */
3900       return newNode (RLC, root->left->left, NULL);
3901
3902     }
3903
3904 tryNext1:
3905   /* third case for RRC */
3906   /*  (?symbol >> 1) | (?symbol << 7) */
3907   if (IS_LEFT_OP (root->right) &&
3908       IS_RIGHT_OP (root->left))
3909     {
3910
3911       if (!SPEC_USIGN (TETYPE (root->left->left)))
3912         return root;
3913
3914       if (!IS_AST_LIT_VALUE (root->left->right) ||
3915           !IS_AST_LIT_VALUE (root->right->right))
3916         goto tryNext2;
3917
3918       /* make sure it is the same symbol */
3919       if (!isAstEqual (root->left->left,
3920                        root->right->left))
3921         goto tryNext2;
3922
3923       if (AST_LIT_VALUE (root->left->right) != 1)
3924         goto tryNext2;
3925
3926       if (AST_LIT_VALUE (root->right->right) !=
3927           (getSize (TTYPE (root->left->left)) * 8 - 1))
3928         goto tryNext2;
3929
3930       /* whew got the first case : create the AST */
3931       return newNode (RRC, root->left->left, NULL);
3932
3933     }
3934 tryNext2:
3935   /* fourth and last case for now */
3936   /* (?symbol << 7) | (?symbol >> 1) */
3937   if (IS_RIGHT_OP (root->right) &&
3938       IS_LEFT_OP (root->left))
3939     {
3940
3941       if (!SPEC_USIGN (TETYPE (root->left->left)))
3942         return root;
3943
3944       if (!IS_AST_LIT_VALUE (root->left->right) ||
3945           !IS_AST_LIT_VALUE (root->right->right))
3946         return root;
3947
3948       /* make sure it is the same symbol */
3949       if (!isAstEqual (root->left->left,
3950                        root->right->left))
3951         return root;
3952
3953       if (AST_LIT_VALUE (root->right->right) != 1)
3954         return root;
3955
3956       if (AST_LIT_VALUE (root->left->right) !=
3957           (getSize (TTYPE (root->left->left)) * 8 - 1))
3958         return root;
3959
3960       /* whew got the first case : create the AST */
3961       return newNode (RRC, root->left->left, NULL);
3962
3963     }
3964
3965   /* not found return root */
3966   return root;
3967 }
3968
3969 /*-----------------------------------------------------------------*/
3970 /* optimizeCompare - otimizes compares for bit variables     */
3971 /*-----------------------------------------------------------------*/
3972 ast *
3973 optimizeCompare (ast * root)
3974 {
3975   ast *optExpr = NULL;
3976   value *vleft;
3977   value *vright;
3978   unsigned int litValue;
3979
3980   /* if nothing then return nothing */
3981   if (!root)
3982     return NULL;
3983
3984   /* if not a compare op then do leaves */
3985   if (!IS_COMPARE_OP (root))
3986     {
3987       root->left = optimizeCompare (root->left);
3988       root->right = optimizeCompare (root->right);
3989       return root;
3990     }
3991
3992   /* if left & right are the same then depending
3993      of the operation do */
3994   if (isAstEqual (root->left, root->right))
3995     {
3996       switch (root->opval.op)
3997         {
3998         case '>':
3999         case '<':
4000         case NE_OP:
4001           optExpr = newAst_VALUE (constVal ("0"));
4002           break;
4003         case GE_OP:
4004         case LE_OP:
4005         case EQ_OP:
4006           optExpr = newAst_VALUE (constVal ("1"));
4007           break;
4008         }
4009
4010       return decorateType (optExpr);
4011     }
4012
4013   vleft = (root->left->type == EX_VALUE ?
4014            root->left->opval.val : NULL);
4015
4016   vright = (root->right->type == EX_VALUE ?
4017             root->right->opval.val : NULL);
4018
4019   /* if left is a BITVAR in BITSPACE */
4020   /* and right is a LITERAL then opt- */
4021   /* imize else do nothing       */
4022   if (vleft && vright &&
4023       IS_BITVAR (vleft->etype) &&
4024       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
4025       IS_LITERAL (vright->etype))
4026     {
4027
4028       /* if right side > 1 then comparison may never succeed */
4029       if ((litValue = (int) floatFromVal (vright)) > 1)
4030         {
4031           werror (W_BAD_COMPARE);
4032           goto noOptimize;
4033         }
4034
4035       if (litValue)
4036         {
4037           switch (root->opval.op)
4038             {
4039             case '>':           /* bit value greater than 1 cannot be */
4040               werror (W_BAD_COMPARE);
4041               goto noOptimize;
4042               break;
4043
4044             case '<':           /* bit value < 1 means 0 */
4045             case NE_OP:
4046               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4047               break;
4048
4049             case LE_OP: /* bit value <= 1 means no check */
4050               optExpr = newAst_VALUE (vright);
4051               break;
4052
4053             case GE_OP: /* bit value >= 1 means only check for = */
4054             case EQ_OP:
4055               optExpr = newAst_VALUE (vleft);
4056               break;
4057             }
4058         }
4059       else
4060         {                       /* literal is zero */
4061           switch (root->opval.op)
4062             {
4063             case '<':           /* bit value < 0 cannot be */
4064               werror (W_BAD_COMPARE);
4065               goto noOptimize;
4066               break;
4067
4068             case '>':           /* bit value > 0 means 1 */
4069             case NE_OP:
4070               optExpr = newAst_VALUE (vleft);
4071               break;
4072
4073             case LE_OP: /* bit value <= 0 means no check */
4074             case GE_OP: /* bit value >= 0 means no check */
4075               werror (W_BAD_COMPARE);
4076               goto noOptimize;
4077               break;
4078
4079             case EQ_OP: /* bit == 0 means ! of bit */
4080               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
4081               break;
4082             }
4083         }
4084       return decorateType (resolveSymbols (optExpr));
4085     }                           /* end-of-if of BITVAR */
4086
4087 noOptimize:
4088   return root;
4089 }
4090 /*-----------------------------------------------------------------*/
4091 /* addSymToBlock : adds the symbol to the first block we find      */
4092 /*-----------------------------------------------------------------*/
4093 void 
4094 addSymToBlock (symbol * sym, ast * tree)
4095 {
4096   /* reached end of tree or a leaf */
4097   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
4098     return;
4099
4100   /* found a block */
4101   if (IS_AST_OP (tree) &&
4102       tree->opval.op == BLOCK)
4103     {
4104
4105       symbol *lsym = copySymbol (sym);
4106
4107       lsym->next = AST_VALUES (tree, sym);
4108       AST_VALUES (tree, sym) = lsym;
4109       return;
4110     }
4111
4112   addSymToBlock (sym, tree->left);
4113   addSymToBlock (sym, tree->right);
4114 }
4115
4116 /*-----------------------------------------------------------------*/
4117 /* processRegParms - do processing for register parameters         */
4118 /*-----------------------------------------------------------------*/
4119 static void 
4120 processRegParms (value * args, ast * body)
4121 {
4122   while (args)
4123     {
4124       if (IS_REGPARM (args->etype))
4125         addSymToBlock (args->sym, body);
4126       args = args->next;
4127     }
4128 }
4129
4130 /*-----------------------------------------------------------------*/
4131 /* resetParmKey - resets the operandkeys for the symbols           */
4132 /*-----------------------------------------------------------------*/
4133 DEFSETFUNC (resetParmKey)
4134 {
4135   symbol *sym = item;
4136
4137   sym->key = 0;
4138   sym->defs = NULL;
4139   sym->uses = NULL;
4140   sym->remat = 0;
4141   return 1;
4142 }
4143
4144 /*-----------------------------------------------------------------*/
4145 /* createFunction - This is the key node that calls the iCode for  */
4146 /*                  generating the code for a function. Note code  */
4147 /*                  is generated function by function, later when  */
4148 /*                  add inter-procedural analysis this will change */
4149 /*-----------------------------------------------------------------*/
4150 ast *
4151 createFunction (symbol * name, ast * body)
4152 {
4153   ast *ex;
4154   symbol *csym;
4155   int stack = 0;
4156   sym_link *fetype;
4157   iCode *piCode = NULL;
4158
4159   /* if check function return 0 then some problem */
4160   if (checkFunction (name) == 0)
4161     return NULL;
4162
4163   /* create a dummy block if none exists */
4164   if (!body)
4165     body = newNode (BLOCK, NULL, NULL);
4166
4167   noLineno++;
4168
4169   /* check if the function name already in the symbol table */
4170   if ((csym = findSym (SymbolTab, NULL, name->name)))
4171     {
4172       name = csym;
4173       /* special case for compiler defined functions
4174          we need to add the name to the publics list : this
4175          actually means we are now compiling the compiler
4176          support routine */
4177       if (name->cdef)
4178         {
4179           addSet (&publics, name);
4180         }
4181     }
4182   else
4183     {
4184       addSymChain (name);
4185       allocVariables (name);
4186     }
4187   name->lastLine = yylineno;
4188   currFunc = name;
4189   processFuncArgs (currFunc, 0);
4190
4191   /* set the stack pointer */
4192   /* PENDING: check this for the mcs51 */
4193   stackPtr = -port->stack.direction * port->stack.call_overhead;
4194   if (IS_ISR (name->etype))
4195     stackPtr -= port->stack.direction * port->stack.isr_overhead;
4196   if (IS_RENT (name->etype) || options.stackAuto)
4197     stackPtr -= port->stack.direction * port->stack.reent_overhead;
4198
4199   xstackPtr = -port->stack.direction * port->stack.call_overhead;
4200
4201   fetype = getSpec (name->type);        /* get the specifier for the function */
4202   /* if this is a reentrant function then */
4203   if (IS_RENT (fetype))
4204     reentrant++;
4205
4206   allocParms (name->args);      /* allocate the parameters */
4207
4208   /* do processing for parameters that are passed in registers */
4209   processRegParms (name->args, body);
4210
4211   /* set the stack pointer */
4212   stackPtr = 0;
4213   xstackPtr = -1;
4214
4215   /* allocate & autoinit the block variables */
4216   processBlockVars (body, &stack, ALLOCATE);
4217
4218   /* save the stack information */
4219   if (options.useXstack)
4220     name->xstack = SPEC_STAK (fetype) = stack;
4221   else
4222     name->stack = SPEC_STAK (fetype) = stack;
4223
4224   /* name needs to be mangled */
4225   sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
4226
4227   body = resolveSymbols (body); /* resolve the symbols */
4228   body = decorateType (body);   /* propagateType & do semantic checks */
4229
4230   ex = newAst_VALUE (symbolVal (name));         /* create name       */
4231   ex = newNode (FUNCTION, ex, body);
4232   ex->values.args = name->args;
4233
4234   if (fatalError)
4235     {
4236       werror (E_FUNC_NO_CODE, name->name);
4237       goto skipall;
4238     }
4239
4240   /* create the node & generate intermediate code */
4241   GcurMemmap = code;
4242   codeOutFile = code->oFile;
4243   piCode = iCodeFromAst (ex);
4244
4245   if (fatalError)
4246     {
4247       werror (E_FUNC_NO_CODE, name->name);
4248       goto skipall;
4249     }
4250
4251   eBBlockFromiCode (piCode);
4252
4253   /* if there are any statics then do them */
4254   if (staticAutos)
4255     {
4256       GcurMemmap = statsg;
4257       codeOutFile = statsg->oFile;
4258       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos))));
4259       staticAutos = NULL;
4260     }
4261
4262 skipall:
4263
4264   /* dealloc the block variables */
4265   processBlockVars (body, &stack, DEALLOCATE);
4266   /* deallocate paramaters */
4267   deallocParms (name->args);
4268
4269   if (IS_RENT (fetype))
4270     reentrant--;
4271
4272   /* we are done freeup memory & cleanup */
4273   noLineno--;
4274   labelKey = 1;
4275   name->key = 0;
4276   name->fbody = 1;
4277   addSet (&operKeyReset, name);
4278   applyToSet (operKeyReset, resetParmKey);
4279
4280   if (options.debug)
4281     cdbStructBlock (1, cdbFile);
4282
4283   cleanUpLevel (LabelTab, 0);
4284   cleanUpBlock (StructTab, 1);
4285   cleanUpBlock (TypedefTab, 1);
4286
4287   xstack->syms = NULL;
4288   istack->syms = NULL;
4289   return NULL;
4290 }
4291
4292
4293 #define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
4294 /*-----------------------------------------------------------------*/
4295 /* ast_print : prints the ast (for debugging purposes)             */
4296 /*-----------------------------------------------------------------*/
4297
4298 void ast_print (ast * tree, FILE *outfile, int indent)
4299 {
4300         
4301         if (!tree) return ;
4302
4303         /* can print only decorated trees */
4304         if (!tree->decorated) return;
4305
4306         /* if any child is an error | this one is an error do nothing */
4307         if (tree->isError ||
4308             (tree->left && tree->left->isError) ||
4309             (tree->right && tree->right->isError)) {
4310                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
4311         }
4312
4313         
4314         /* print the line          */
4315         /* if not block & function */
4316         if (tree->type == EX_OP &&
4317             (tree->opval.op != FUNCTION &&
4318              tree->opval.op != BLOCK &&
4319              tree->opval.op != NULLOP)) {
4320         }
4321         
4322         if (tree->opval.op == FUNCTION) {
4323                 fprintf(outfile,"FUNCTION (%p) type (",tree);
4324                 printTypeChain (tree->ftype,outfile);
4325                 fprintf(outfile,")\n");
4326                 ast_print(tree->left,outfile,indent+4);
4327                 ast_print(tree->right,outfile,indent+4);
4328                 return ;
4329         }
4330         if (tree->opval.op == BLOCK) {
4331                 symbol *decls = tree->values.sym;
4332                 fprintf(outfile,"{\n");
4333                 while (decls) {
4334                         INDENT(indent+4,outfile);
4335                         fprintf(outfile,"DECLARE SYMBOL %s, type(",decls->name);
4336                         printTypeChain(decls->type,outfile);
4337                         fprintf(outfile,")\n");
4338                         
4339                         decls = decls->next;                    
4340                 }
4341                 ast_print(tree->right,outfile,indent+4);
4342                 fprintf(outfile,"}\n");
4343                 return;
4344         }
4345         if (tree->opval.op == NULLOP) {
4346                 fprintf(outfile,"\n");
4347                 ast_print(tree->left,outfile,indent);
4348                 fprintf(outfile,"\n");
4349                 ast_print(tree->right,outfile,indent);
4350                 return ;
4351         }
4352         INDENT(indent,outfile);
4353
4354         /*------------------------------------------------------------------*/
4355         /*----------------------------*/
4356         /*   leaf has been reached    */
4357         /*----------------------------*/
4358         /* if this is of type value */
4359         /* just get the type        */
4360         if (tree->type == EX_VALUE) {
4361
4362                 if (IS_LITERAL (tree->opval.val->etype)) {                      
4363                         fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
4364                                 (int) floatFromVal(tree->opval.val),
4365                                 (int) floatFromVal(tree->opval.val),
4366                                 floatFromVal(tree->opval.val));
4367                 } else if (tree->opval.val->sym) {
4368                         /* if the undefined flag is set then give error message */
4369                         if (tree->opval.val->sym->undefined) {
4370                                 fprintf(outfile,"UNDEFINED SYMBOL ");
4371                         } else {
4372                                 fprintf(outfile,"SYMBOL ");
4373                         }
4374                         fprintf(outfile,"(%p) name= %s ",tree,tree->opval.val->sym->name);
4375                 }
4376                 if (tree->ftype) {
4377                         fprintf(outfile," type (");
4378                         printTypeChain(tree->ftype,outfile);
4379                         fprintf(outfile,")\n");
4380                 } else {
4381                         fprintf(outfile,"\n");
4382                 }
4383                 return ;
4384         }
4385
4386         /* if type link for the case of cast */
4387         if (tree->type == EX_LINK) {
4388                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
4389                 printTypeChain(tree->opval.lnk,outfile);
4390                 fprintf(outfile,")\n");
4391                 return ;
4392         }
4393
4394
4395         /* depending on type of operator do */
4396         
4397         switch (tree->opval.op) {
4398                 /*------------------------------------------------------------------*/
4399                 /*----------------------------*/
4400                 /*        array node          */
4401                 /*----------------------------*/
4402         case '[':
4403                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
4404                 printTypeChain(tree->ftype,outfile);
4405                 fprintf(outfile,")\n");
4406                 ast_print(tree->left,outfile,indent+4);
4407                 ast_print(tree->right,outfile,indent+4);
4408                 return;
4409
4410                 /*------------------------------------------------------------------*/
4411                 /*----------------------------*/
4412                 /*      struct/union          */
4413                 /*----------------------------*/
4414         case '.':
4415                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
4416                 printTypeChain(tree->ftype,outfile);
4417                 fprintf(outfile,")\n");
4418                 ast_print(tree->left,outfile,indent+4);
4419                 ast_print(tree->right,outfile,indent+4);
4420                 return ;
4421
4422                 /*------------------------------------------------------------------*/
4423                 /*----------------------------*/
4424                 /*    struct/union pointer    */
4425                 /*----------------------------*/
4426         case PTR_OP:
4427                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
4428                 printTypeChain(tree->ftype,outfile);
4429                 fprintf(outfile,")\n");
4430                 ast_print(tree->left,outfile,indent+4);
4431                 ast_print(tree->right,outfile,indent+4);
4432                 return ;
4433
4434                 /*------------------------------------------------------------------*/
4435                 /*----------------------------*/
4436                 /*  ++/-- operation           */
4437                 /*----------------------------*/
4438         case INC_OP:            /* incerement operator unary so left only */
4439                 fprintf(outfile,"INC_OP (%p) type (",tree);
4440                 printTypeChain(tree->ftype,outfile);
4441                 fprintf(outfile,")\n");
4442                 ast_print(tree->left,outfile,indent+4);
4443                 return ;
4444
4445         case DEC_OP:
4446                 fprintf(outfile,"DEC_OP (%p) type (",tree);
4447                 printTypeChain(tree->ftype,outfile);
4448                 fprintf(outfile,")\n");
4449                 ast_print(tree->left,outfile,indent+4);
4450                 return ;
4451
4452                 /*------------------------------------------------------------------*/
4453                 /*----------------------------*/
4454                 /*  bitwise and               */
4455                 /*----------------------------*/
4456         case '&':                       
4457                 if (tree->right) {
4458                         fprintf(outfile,"& (%p) type (",tree);
4459                         printTypeChain(tree->ftype,outfile);
4460                         fprintf(outfile,")\n");
4461                         ast_print(tree->left,outfile,indent+4);
4462                         ast_print(tree->right,outfile,indent+4);
4463                 } else {
4464                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
4465                         printTypeChain(tree->ftype,outfile);
4466                         fprintf(outfile,")\n");
4467                         ast_print(tree->left,outfile,indent+4);
4468                         ast_print(tree->right,outfile,indent+4);
4469                 }
4470                 return ;
4471                 /*----------------------------*/
4472                 /*  bitwise or                */
4473                 /*----------------------------*/
4474         case '|':
4475                 fprintf(outfile,"OR (%p) type (",tree);
4476                 printTypeChain(tree->ftype,outfile);
4477                 fprintf(outfile,")\n");
4478                 ast_print(tree->left,outfile,indent+4);
4479                 ast_print(tree->right,outfile,indent+4);
4480                 return ;
4481                 /*------------------------------------------------------------------*/
4482                 /*----------------------------*/
4483                 /*  bitwise xor               */
4484                 /*----------------------------*/
4485         case '^':
4486                 fprintf(outfile,"XOR (%p) type (",tree);
4487                 printTypeChain(tree->ftype,outfile);
4488                 fprintf(outfile,")\n");
4489                 ast_print(tree->left,outfile,indent+4);
4490                 ast_print(tree->right,outfile,indent+4);
4491                 return ;
4492                 
4493                 /*------------------------------------------------------------------*/
4494                 /*----------------------------*/
4495                 /*  division                  */
4496                 /*----------------------------*/
4497         case '/':
4498                 fprintf(outfile,"DIV (%p) type (",tree);
4499                 printTypeChain(tree->ftype,outfile);
4500                 fprintf(outfile,")\n");
4501                 ast_print(tree->left,outfile,indent+4);
4502                 ast_print(tree->right,outfile,indent+4);
4503                 return ;
4504                 /*------------------------------------------------------------------*/
4505                 /*----------------------------*/
4506                 /*            modulus         */
4507                 /*----------------------------*/
4508         case '%':
4509                 fprintf(outfile,"MOD (%p) type (",tree);
4510                 printTypeChain(tree->ftype,outfile);
4511                 fprintf(outfile,")\n");
4512                 ast_print(tree->left,outfile,indent+4);
4513                 ast_print(tree->right,outfile,indent+4);
4514                 return ;
4515
4516                 /*------------------------------------------------------------------*/
4517                 /*----------------------------*/
4518                 /*  address dereference       */
4519                 /*----------------------------*/
4520         case '*':                       /* can be unary  : if right is null then unary operation */
4521                 if (!tree->right) {
4522                         fprintf(outfile,"DEREF (%p) type (",tree);
4523                         printTypeChain(tree->ftype,outfile);
4524                         fprintf(outfile,")\n");
4525                         ast_print(tree->left,outfile,indent+4);
4526                         return ;
4527                 }                       
4528                 /*------------------------------------------------------------------*/
4529                 /*----------------------------*/
4530                 /*      multiplication        */
4531                 /*----------------------------*/                
4532                 fprintf(outfile,"MULT (%p) type (",tree);
4533                 printTypeChain(tree->ftype,outfile);
4534                 fprintf(outfile,")\n");
4535                 ast_print(tree->left,outfile,indent+4);
4536                 ast_print(tree->right,outfile,indent+4);
4537                 return ;
4538
4539
4540                 /*------------------------------------------------------------------*/
4541                 /*----------------------------*/
4542                 /*    unary '+' operator      */
4543                 /*----------------------------*/
4544         case '+':
4545                 /* if unary plus */
4546                 if (!tree->right) {
4547                         fprintf(outfile,"UPLUS (%p) type (",tree);
4548                         printTypeChain(tree->ftype,outfile);
4549                         fprintf(outfile,")\n");
4550                         ast_print(tree->left,outfile,indent+4);
4551                 } else {
4552                         /*------------------------------------------------------------------*/
4553                         /*----------------------------*/
4554                         /*      addition              */
4555                         /*----------------------------*/
4556                         fprintf(outfile,"ADD (%p) type (",tree);
4557                         printTypeChain(tree->ftype,outfile);
4558                         fprintf(outfile,")\n");
4559                         ast_print(tree->left,outfile,indent+4);
4560                         ast_print(tree->right,outfile,indent+4);
4561                 }
4562                 return;
4563                 /*------------------------------------------------------------------*/
4564                 /*----------------------------*/
4565                 /*      unary '-'             */
4566                 /*----------------------------*/
4567         case '-':                       /* can be unary   */
4568                 if (!tree->right) {
4569                         fprintf(outfile,"UMINUS (%p) type (",tree);
4570                         printTypeChain(tree->ftype,outfile);
4571                         fprintf(outfile,")\n");
4572                         ast_print(tree->left,outfile,indent+4);
4573                 } else {
4574                         /*------------------------------------------------------------------*/
4575                         /*----------------------------*/
4576                         /*      subtraction           */
4577                         /*----------------------------*/
4578                         fprintf(outfile,"SUB (%p) type (",tree);
4579                         printTypeChain(tree->ftype,outfile);
4580                         fprintf(outfile,")\n");
4581                         ast_print(tree->left,outfile,indent+4);
4582                         ast_print(tree->right,outfile,indent+4);
4583                 }
4584                 return;
4585                 /*------------------------------------------------------------------*/
4586                 /*----------------------------*/
4587                 /*    compliment              */
4588                 /*----------------------------*/
4589         case '~':
4590                 fprintf(outfile,"COMPL (%p) type (",tree);
4591                 printTypeChain(tree->ftype,outfile);
4592                 fprintf(outfile,")\n");
4593                 ast_print(tree->left,outfile,indent+4);
4594                 return ;
4595                 /*------------------------------------------------------------------*/
4596                 /*----------------------------*/
4597                 /*           not              */
4598                 /*----------------------------*/
4599         case '!':
4600                 fprintf(outfile,"NOT (%p) type (",tree);
4601                 printTypeChain(tree->ftype,outfile);
4602                 fprintf(outfile,")\n");
4603                 ast_print(tree->left,outfile,indent+4);
4604                 return ;
4605                 /*------------------------------------------------------------------*/
4606                 /*----------------------------*/
4607                 /*           shift            */
4608                 /*----------------------------*/
4609         case RRC:
4610                 fprintf(outfile,"RRC (%p) type (",tree);
4611                 printTypeChain(tree->ftype,outfile);
4612                 fprintf(outfile,")\n");
4613                 ast_print(tree->left,outfile,indent+4);
4614                 return ;
4615
4616         case RLC:
4617                 fprintf(outfile,"RLC (%p) type (",tree);
4618                 printTypeChain(tree->ftype,outfile);
4619                 fprintf(outfile,")\n");
4620                 ast_print(tree->left,outfile,indent+4);
4621                 return ;
4622         case GETHBIT:
4623                 fprintf(outfile,"GETHBIT (%p) type (",tree);
4624                 printTypeChain(tree->ftype,outfile);
4625                 fprintf(outfile,")\n");
4626                 ast_print(tree->left,outfile,indent+4);
4627                 return ;
4628         case LEFT_OP:
4629                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
4630                 printTypeChain(tree->ftype,outfile);
4631                 fprintf(outfile,")\n");
4632                 ast_print(tree->left,outfile,indent+4);
4633                 ast_print(tree->right,outfile,indent+4);
4634                 return ;
4635         case RIGHT_OP:
4636                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
4637                 printTypeChain(tree->ftype,outfile);
4638                 fprintf(outfile,")\n");
4639                 ast_print(tree->left,outfile,indent+4);
4640                 ast_print(tree->right,outfile,indent+4);
4641                 return ;
4642                 /*------------------------------------------------------------------*/
4643                 /*----------------------------*/
4644                 /*         casting            */
4645                 /*----------------------------*/
4646         case CAST:                      /* change the type   */
4647                 fprintf(outfile,"CAST (%p) type (",tree);
4648                 printTypeChain(tree->ftype,outfile);
4649                 fprintf(outfile,")\n");
4650                 ast_print(tree->right,outfile,indent+4);
4651                 return ;
4652                 
4653         case AND_OP:
4654                 fprintf(outfile,"ANDAND (%p) type (",tree);
4655                 printTypeChain(tree->ftype,outfile);
4656                 fprintf(outfile,")\n");
4657                 ast_print(tree->left,outfile,indent+4);
4658                 ast_print(tree->right,outfile,indent+4);
4659                 return ;
4660         case OR_OP:
4661                 fprintf(outfile,"OROR (%p) type (",tree);
4662                 printTypeChain(tree->ftype,outfile);
4663                 fprintf(outfile,")\n");
4664                 ast_print(tree->left,outfile,indent+4);
4665                 ast_print(tree->right,outfile,indent+4);
4666                 return ;
4667                 
4668                 /*------------------------------------------------------------------*/
4669                 /*----------------------------*/
4670                 /*     comparison operators   */
4671                 /*----------------------------*/
4672         case '>':
4673                 fprintf(outfile,"GT(>) (%p) type (",tree);
4674                 printTypeChain(tree->ftype,outfile);
4675                 fprintf(outfile,")\n");
4676                 ast_print(tree->left,outfile,indent+4);
4677                 ast_print(tree->right,outfile,indent+4);
4678                 return ;
4679         case '<':
4680                 fprintf(outfile,"LT(<) (%p) type (",tree);
4681                 printTypeChain(tree->ftype,outfile);
4682                 fprintf(outfile,")\n");
4683                 ast_print(tree->left,outfile,indent+4);
4684                 ast_print(tree->right,outfile,indent+4);
4685                 return ;
4686         case LE_OP:
4687                 fprintf(outfile,"LE(<=) (%p) type (",tree);
4688                 printTypeChain(tree->ftype,outfile);
4689                 fprintf(outfile,")\n");
4690                 ast_print(tree->left,outfile,indent+4);
4691                 ast_print(tree->right,outfile,indent+4);
4692                 return ;
4693         case GE_OP:
4694                 fprintf(outfile,"GE(>=) (%p) type (",tree);
4695                 printTypeChain(tree->ftype,outfile);
4696                 fprintf(outfile,")\n");
4697                 ast_print(tree->left,outfile,indent+4);
4698                 ast_print(tree->right,outfile,indent+4);
4699                 return ;
4700         case EQ_OP:
4701                 fprintf(outfile,"EQ(==) (%p) type (",tree);
4702                 printTypeChain(tree->ftype,outfile);
4703                 fprintf(outfile,")\n");
4704                 ast_print(tree->left,outfile,indent+4);
4705                 ast_print(tree->right,outfile,indent+4);
4706                 return ;
4707         case NE_OP:
4708                 fprintf(outfile,"NE(!=) (%p) type (",tree);
4709                 printTypeChain(tree->ftype,outfile);
4710                 fprintf(outfile,")\n");
4711                 ast_print(tree->left,outfile,indent+4);
4712                 ast_print(tree->right,outfile,indent+4);
4713                 /*------------------------------------------------------------------*/
4714                 /*----------------------------*/
4715                 /*             sizeof         */
4716                 /*----------------------------*/
4717         case SIZEOF:            /* evaluate wihout code generation */
4718                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
4719                 return ;
4720
4721                 /*------------------------------------------------------------------*/
4722                 /*----------------------------*/
4723                 /* conditional operator  '?'  */
4724                 /*----------------------------*/
4725         case '?':
4726                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
4727                 printTypeChain(tree->ftype,outfile);
4728                 fprintf(outfile,")\n");
4729                 ast_print(tree->left,outfile,indent+4);
4730                 ast_print(tree->right,outfile,indent+4);
4731
4732         case ':':
4733                 fprintf(outfile,"COLON(:) (%p) type (",tree);
4734                 printTypeChain(tree->ftype,outfile);
4735                 fprintf(outfile,")\n");
4736                 ast_print(tree->left,outfile,indent+4);
4737                 ast_print(tree->right,outfile,indent+4);
4738                 return ;
4739                 
4740                 /*------------------------------------------------------------------*/
4741                 /*----------------------------*/
4742                 /*    assignment operators    */
4743                 /*----------------------------*/
4744         case MUL_ASSIGN:
4745                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
4746                 printTypeChain(tree->ftype,outfile);
4747                 fprintf(outfile,")\n");
4748                 ast_print(tree->left,outfile,indent+4);
4749                 ast_print(tree->right,outfile,indent+4);
4750                 return;
4751         case DIV_ASSIGN:
4752                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
4753                 printTypeChain(tree->ftype,outfile);
4754                 fprintf(outfile,")\n");
4755                 ast_print(tree->left,outfile,indent+4);
4756                 ast_print(tree->right,outfile,indent+4);
4757                 return;
4758         case AND_ASSIGN:
4759                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
4760                 printTypeChain(tree->ftype,outfile);
4761                 fprintf(outfile,")\n");
4762                 ast_print(tree->left,outfile,indent+4);
4763                 ast_print(tree->right,outfile,indent+4);
4764                 return;
4765         case OR_ASSIGN:
4766                 fprintf(outfile,"ORASS(*=) (%p) type (",tree);
4767                 printTypeChain(tree->ftype,outfile);
4768                 fprintf(outfile,")\n");
4769                 ast_print(tree->left,outfile,indent+4);
4770                 ast_print(tree->right,outfile,indent+4);
4771                 return;
4772         case XOR_ASSIGN:
4773                 fprintf(outfile,"XORASS(*=) (%p) type (",tree);
4774                 printTypeChain(tree->ftype,outfile);
4775                 fprintf(outfile,")\n");
4776                 ast_print(tree->left,outfile,indent+4);
4777                 ast_print(tree->right,outfile,indent+4);
4778                 return;
4779         case RIGHT_ASSIGN:
4780                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
4781                 printTypeChain(tree->ftype,outfile);
4782                 fprintf(outfile,")\n");
4783                 ast_print(tree->left,outfile,indent+4);
4784                 ast_print(tree->right,outfile,indent+4);
4785                 return;
4786         case LEFT_ASSIGN:
4787                 fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
4788                 printTypeChain(tree->ftype,outfile);
4789                 fprintf(outfile,")\n");
4790                 ast_print(tree->left,outfile,indent+4);
4791                 ast_print(tree->right,outfile,indent+4);
4792                 return;
4793                 /*------------------------------------------------------------------*/
4794                 /*----------------------------*/
4795                 /*    -= operator             */
4796                 /*----------------------------*/
4797         case SUB_ASSIGN:
4798                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
4799                 printTypeChain(tree->ftype,outfile);
4800                 fprintf(outfile,")\n");
4801                 ast_print(tree->left,outfile,indent+4);
4802                 ast_print(tree->right,outfile,indent+4);
4803                 return;
4804                 /*------------------------------------------------------------------*/
4805                 /*----------------------------*/
4806                 /*          += operator       */
4807                 /*----------------------------*/
4808         case ADD_ASSIGN:
4809                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
4810                 printTypeChain(tree->ftype,outfile);
4811                 fprintf(outfile,")\n");
4812                 ast_print(tree->left,outfile,indent+4);
4813                 ast_print(tree->right,outfile,indent+4);
4814                 return;
4815                 /*------------------------------------------------------------------*/
4816                 /*----------------------------*/
4817                 /*      straight assignemnt   */
4818                 /*----------------------------*/
4819         case '=':
4820                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
4821                 printTypeChain(tree->ftype,outfile);
4822                 fprintf(outfile,")\n");
4823                 ast_print(tree->left,outfile,indent+4);
4824                 ast_print(tree->right,outfile,indent+4);
4825                 return;     
4826                 /*------------------------------------------------------------------*/
4827                 /*----------------------------*/
4828                 /*      comma operator        */
4829                 /*----------------------------*/
4830         case ',':
4831                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
4832                 printTypeChain(tree->ftype,outfile);
4833                 fprintf(outfile,")\n");
4834                 ast_print(tree->left,outfile,indent+4);
4835                 ast_print(tree->right,outfile,indent+4);
4836                 return;
4837                 /*------------------------------------------------------------------*/
4838                 /*----------------------------*/
4839                 /*       function call        */
4840                 /*----------------------------*/
4841         case CALL:
4842         case PCALL:
4843                 fprintf(outfile,"CALL (%p) type (",tree);
4844                 printTypeChain(tree->ftype,outfile);
4845                 fprintf(outfile,")\n");
4846                 ast_print(tree->left,outfile,indent+4);
4847                 ast_print(tree->right,outfile,indent+4);
4848                 return;
4849         case PARAM:
4850                 fprintf(outfile,"PARM ");
4851                 ast_print(tree->left,outfile,indent+4);
4852                 if (tree->right && !IS_AST_PARAM(tree->right)) {
4853                         fprintf(outfile,"PARM ");
4854                         ast_print(tree->right,outfile,indent+4);
4855                 }
4856                 return ;
4857                 /*------------------------------------------------------------------*/
4858                 /*----------------------------*/
4859                 /*     return statement       */
4860                 /*----------------------------*/
4861         case RETURN:
4862                 fprintf(outfile,"RETURN (%p) type (",tree);
4863                 printTypeChain(tree->right->ftype,outfile);
4864                 fprintf(outfile,")\n");
4865                 ast_print(tree->right,outfile,indent+4);
4866                 return ;
4867                 /*------------------------------------------------------------------*/
4868                 /*----------------------------*/
4869                 /*     label statement        */
4870                 /*----------------------------*/
4871         case LABEL :
4872                 fprintf(outfile,"LABEL (%p)",tree);
4873                 ast_print(tree->left,outfile,indent+4);
4874                 ast_print(tree->right,outfile,indent);
4875                 return;
4876                 /*------------------------------------------------------------------*/
4877                 /*----------------------------*/
4878                 /*     switch statement       */
4879                 /*----------------------------*/
4880         case SWITCH:
4881                 {
4882                         value *val;
4883                         fprintf(outfile,"SWITCH (%p) ",tree);
4884                         ast_print(tree->left,outfile,0);
4885                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
4886                                 INDENT(indent+4,outfile);
4887                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
4888                                         (int) floatFromVal(val),
4889                                         tree->values.switchVals.swNum,
4890                                         (int) floatFromVal(val));
4891                         }
4892                         ast_print(tree->right,outfile,indent);
4893                 }
4894                 return ;
4895                 /*------------------------------------------------------------------*/
4896                 /*----------------------------*/
4897                 /* ifx Statement              */
4898                 /*----------------------------*/
4899         case IFX:
4900                 ast_print(tree->left,outfile,indent);
4901                 INDENT(indent,outfile);
4902                 fprintf(outfile,"IF (%p) \n",tree);
4903                 if (tree->trueLabel) {
4904                         INDENT(indent,outfile);
4905                         fprintf(outfile,"NE(==) 0 goto %s\n",tree->trueLabel->name);
4906                 }
4907                 if (tree->falseLabel) {
4908                         INDENT(indent,outfile);
4909                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
4910                 }
4911                 ast_print(tree->right,outfile,indent);
4912                 return ;
4913                 /*------------------------------------------------------------------*/
4914                 /*----------------------------*/
4915                 /* for Statement              */
4916                 /*----------------------------*/
4917         case FOR:
4918                 fprintf(outfile,"FOR (%p) \n",tree);
4919                 if (AST_FOR( tree, initExpr)) {
4920                         INDENT(indent+4,outfile);
4921                         fprintf(outfile,"INIT EXPR ");
4922                         ast_print(AST_FOR(tree, initExpr),outfile,indent+4);
4923                 }
4924                 if (AST_FOR( tree, condExpr)) {
4925                         INDENT(indent+4,outfile);
4926                         fprintf(outfile,"COND EXPR ");
4927                         ast_print(AST_FOR(tree, condExpr),outfile,indent+4);
4928                 }
4929                 if (AST_FOR( tree, loopExpr)) {
4930                         INDENT(indent+4,outfile);
4931                         fprintf(outfile,"LOOP EXPR ");
4932                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+4);
4933                 }
4934                 fprintf(outfile,"FOR LOOP BODY \n");
4935                 ast_print(tree->left,outfile,indent+4);
4936                 return ;
4937         default:
4938             return ;
4939         }
4940 }
4941
4942 void PA(ast *t)
4943 {
4944         ast_print(t,stdout,1);
4945 }