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