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