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