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