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