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