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