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