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