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