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