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