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