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