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