* as/hc08/asmain.c (asexit),
[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       IS_ANDORNOT (tree->right))
4798     {
4799       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4800       return tree;
4801     }
4802
4803   if (!(IS_ANDORNOT (tree)))
4804     return tree;
4805
4806   /* if this an and */
4807   if (IS_AND (tree))
4808     {
4809       static int localLbl = 0;
4810       symbol *localLabel;
4811
4812       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4813       localLabel = newSymbol (buffer, NestLevel);
4814
4815       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4816
4817       /* if left is already a IFX then just change the if true label in that */
4818       if (!IS_IFX (tree->left))
4819         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4820
4821       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4822       /* right is a IFX then just join */
4823       if (IS_IFX (tree->right))
4824         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4825
4826       tree->right = createLabel (localLabel, tree->right);
4827       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4828
4829       return newNode (NULLOP, tree->left, tree->right);
4830     }
4831
4832   /* if this is an or operation */
4833   if (IS_OR (tree))
4834     {
4835       static int localLbl = 0;
4836       symbol *localLabel;
4837
4838       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4839       localLabel = newSymbol (buffer, NestLevel);
4840
4841       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4842
4843       /* if left is already a IFX then just change the if true label in that */
4844       if (!IS_IFX (tree->left))
4845         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4846
4847       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4848       /* right is a IFX then just join */
4849       if (IS_IFX (tree->right))
4850         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4851
4852       tree->right = createLabel (localLabel, tree->right);
4853       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4854
4855       return newNode (NULLOP, tree->left, tree->right);
4856     }
4857
4858   /* change not */
4859   if (IS_NOT (tree))
4860     {
4861       /* call with exchanged labels */
4862       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4863
4864       /* if left isn't already a IFX */
4865       if (!IS_IFX (tree->left))
4866         {
4867           tree->left = newNode (IFX, tree->left, NULL);
4868           tree->left->trueLabel = falseLabel;
4869           tree->left->falseLabel = trueLabel;
4870         }
4871       return tree->left;
4872      }
4873
4874   if (IS_IFX (tree))
4875     {
4876       tree->trueLabel = trueLabel;
4877       tree->falseLabel = falseLabel;
4878     }
4879
4880   return tree;
4881 }
4882
4883
4884 /*-----------------------------------------------------------------*/
4885 /* createBlock - create expression tree for block                  */
4886 /*-----------------------------------------------------------------*/
4887 ast *
4888 createBlock (symbol * decl, ast * body)
4889 {
4890   ast *ex;
4891
4892   /* if the block has nothing */
4893   if (!body && !decl)
4894     return NULL;
4895
4896   ex = newNode (BLOCK, NULL, body);
4897   ex->values.sym = decl;
4898
4899   ex->level++;
4900   ex->lineno = 0;
4901   return ex;
4902 }
4903
4904 /*-----------------------------------------------------------------*/
4905 /* createLabel - creates the expression tree for labels            */
4906 /*-----------------------------------------------------------------*/
4907 ast *
4908 createLabel (symbol * label, ast * stmnt)
4909 {
4910   symbol *csym;
4911   char name[SDCC_NAME_MAX + 1];
4912   ast *rValue;
4913
4914   /* must create fresh symbol if the symbol name  */
4915   /* exists in the symbol table, since there can  */
4916   /* be a variable with the same name as the labl */
4917   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4918       (csym->level == label->level))
4919     label = newSymbol (label->name, label->level);
4920
4921   /* change the name before putting it in add _ */
4922   SNPRINTF(name, sizeof(name), "%s", label->name);
4923
4924   /* put the label in the LabelSymbol table    */
4925   /* but first check if a label of the same    */
4926   /* name exists                               */
4927   if ((csym = findSym (LabelTab, NULL, name)))
4928     werror (E_DUPLICATE_LABEL, label->name);
4929   else
4930     addSym (LabelTab, label, name, label->level, 0, 0);
4931
4932   label->isitmp = 1;
4933   label->islbl = 1;
4934   label->key = labelKey++;
4935   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4936   rValue->lineno = 0;
4937
4938   return rValue;
4939 }
4940
4941 /*-----------------------------------------------------------------*/
4942 /* createCase - generates the parsetree for a case statement       */
4943 /*-----------------------------------------------------------------*/
4944 ast *
4945 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4946 {
4947   char caseLbl[SDCC_NAME_MAX + 1];
4948   ast *rexpr;
4949   value *val;
4950
4951   /* if the switch statement does not exist */
4952   /* then case is out of context            */
4953   if (!swStat)
4954     {
4955       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4956       return NULL;
4957     }
4958
4959   caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4960   /* if not a constant then error  */
4961   if (!IS_LITERAL (caseVal->ftype))
4962     {
4963       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4964       return NULL;
4965     }
4966
4967   /* if not a integer than error */
4968   if (!IS_INTEGRAL (caseVal->ftype))
4969     {
4970       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4971       return NULL;
4972     }
4973
4974   /* find the end of the switch values chain   */
4975   if (!(val = swStat->values.switchVals.swVals))
4976     swStat->values.switchVals.swVals = caseVal->opval.val;
4977   else
4978     {
4979       /* also order the cases according to value */
4980       value *pval = NULL;
4981       int cVal = (int) floatFromVal (caseVal->opval.val);
4982       while (val && (int) floatFromVal (val) < cVal)
4983         {
4984           pval = val;
4985           val = val->next;
4986         }
4987
4988       /* if we reached the end then */
4989       if (!val)
4990         {
4991           pval->next = caseVal->opval.val;
4992         }
4993       else if ((int) floatFromVal (val) == cVal)
4994         {
4995           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
4996                     "case");
4997           return NULL;
4998         }
4999       else
5000         {
5001           /* we found a value greater than */
5002           /* the current value we must add this */
5003           /* before the value */
5004           caseVal->opval.val->next = val;
5005
5006           /* if this was the first in chain */
5007           if (swStat->values.switchVals.swVals == val)
5008             swStat->values.switchVals.swVals =
5009               caseVal->opval.val;
5010           else
5011             pval->next = caseVal->opval.val;
5012         }
5013
5014     }
5015
5016   /* create the case label   */
5017   SNPRINTF(caseLbl, sizeof(caseLbl),
5018            "_case_%d_%d",
5019            swStat->values.switchVals.swNum,
5020            (int) floatFromVal (caseVal->opval.val));
5021
5022   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5023   rexpr->lineno = 0;
5024   return rexpr;
5025 }
5026
5027 /*-----------------------------------------------------------------*/
5028 /* createDefault - creates the parse tree for the default statement */
5029 /*-----------------------------------------------------------------*/
5030 ast *
5031 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5032 {
5033   char defLbl[SDCC_NAME_MAX + 1];
5034
5035   /* if the switch statement does not exist */
5036   /* then case is out of context            */
5037   if (!swStat)
5038     {
5039       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5040       return NULL;
5041     }
5042
5043   if (swStat->values.switchVals.swDefault)
5044     {
5045       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5046                 "default");
5047       return NULL;
5048     }
5049
5050   /* turn on the default flag   */
5051   swStat->values.switchVals.swDefault = 1;
5052
5053   /* create the label  */
5054   SNPRINTF (defLbl, sizeof(defLbl),
5055             "_default_%d", swStat->values.switchVals.swNum);
5056   return createLabel (newSymbol (defLbl, 0), stmnt);
5057 }
5058
5059 /*-----------------------------------------------------------------*/
5060 /* createIf - creates the parsetree for the if statement           */
5061 /*-----------------------------------------------------------------*/
5062 ast *
5063 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5064 {
5065   static int Lblnum = 0;
5066   ast *ifTree;
5067   symbol *ifTrue, *ifFalse, *ifEnd;
5068
5069   /* if neither exists */
5070   if (!elseBody && !ifBody) {
5071     // if there are no side effects (i++, j() etc)
5072     if (!hasSEFcalls(condAst)) {
5073       return condAst;
5074     }
5075   }
5076
5077   /* create the labels */
5078   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5079   ifFalse = newSymbol (buffer, NestLevel);
5080   /* if no else body then end == false */
5081   if (!elseBody)
5082     ifEnd = ifFalse;
5083   else
5084     {
5085       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5086       ifEnd = newSymbol (buffer, NestLevel);
5087     }
5088
5089   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5090   ifTrue = newSymbol (buffer, NestLevel);
5091
5092   Lblnum++;
5093
5094   /* attach the ifTrue label to the top of it body */
5095   ifBody = createLabel (ifTrue, ifBody);
5096   /* attach a goto end to the ifBody if else is present */
5097   if (elseBody)
5098     {
5099       ifBody = newNode (NULLOP, ifBody,
5100                         newNode (GOTO,
5101                                  newAst_VALUE (symbolVal (ifEnd)),
5102                                  NULL));
5103       /* put the elseLabel on the else body */
5104       elseBody = createLabel (ifFalse, elseBody);
5105       /* out the end at the end of the body */
5106       elseBody = newNode (NULLOP,
5107                           elseBody,
5108                           createLabel (ifEnd, NULL));
5109     }
5110   else
5111     {
5112       ifBody = newNode (NULLOP, ifBody,
5113                         createLabel (ifFalse, NULL));
5114     }
5115   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5116   if (IS_IFX (condAst))
5117     ifTree = condAst;
5118   else
5119     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5120
5121   return newNode (NULLOP, ifTree,
5122                   newNode (NULLOP, ifBody, elseBody));
5123
5124 }
5125
5126 /*-----------------------------------------------------------------*/
5127 /* createDo - creates parse tree for do                            */
5128 /*        _dobody_n:                                               */
5129 /*            statements                                           */
5130 /*        _docontinue_n:                                           */
5131 /*            condition_expression +-> trueLabel -> _dobody_n      */
5132 /*                                 |                               */
5133 /*                                 +-> falseLabel-> _dobreak_n     */
5134 /*        _dobreak_n:                                              */
5135 /*-----------------------------------------------------------------*/
5136 ast *
5137 createDo (symbol * trueLabel, symbol * continueLabel,
5138           symbol * falseLabel, ast * condAst, ast * doBody)
5139 {
5140   ast *doTree;
5141
5142
5143   /* if the body does not exist then it is simple */
5144   if (!doBody)
5145     {
5146       condAst = backPatchLabels (condAst, continueLabel, NULL);
5147       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5148                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5149       doTree->trueLabel = continueLabel;
5150       doTree->falseLabel = NULL;
5151       return doTree;
5152     }
5153
5154   /* otherwise we have a body */
5155   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5156
5157   /* attach the body label to the top */
5158   doBody = createLabel (trueLabel, doBody);
5159   /* attach the continue label to end of body */
5160   doBody = newNode (NULLOP, doBody,
5161                     createLabel (continueLabel, NULL));
5162
5163   /* now put the break label at the end */
5164   if (IS_IFX (condAst))
5165     doTree = condAst;
5166   else
5167     doTree = newIfxNode (condAst, trueLabel, falseLabel);
5168
5169   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5170
5171   /* putting it together */
5172   return newNode (NULLOP, doBody, doTree);
5173 }
5174
5175 /*-----------------------------------------------------------------*/
5176 /* createFor - creates parse tree for 'for' statement              */
5177 /*        initExpr                                                 */
5178 /*   _forcond_n:                                                   */
5179 /*        condExpr  +-> trueLabel -> _forbody_n                    */
5180 /*                  |                                              */
5181 /*                  +-> falseLabel-> _forbreak_n                   */
5182 /*   _forbody_n:                                                   */
5183 /*        statements                                               */
5184 /*   _forcontinue_n:                                               */
5185 /*        loopExpr                                                 */
5186 /*        goto _forcond_n ;                                        */
5187 /*   _forbreak_n:                                                  */
5188 /*-----------------------------------------------------------------*/
5189 ast *
5190 createFor (symbol * trueLabel, symbol * continueLabel,
5191            symbol * falseLabel, symbol * condLabel,
5192            ast * initExpr, ast * condExpr, ast * loopExpr,
5193            ast * forBody)
5194 {
5195   ast *forTree;
5196
5197   /* if loopexpression not present then we can generate it */
5198   /* the same way as a while */
5199   if (!loopExpr)
5200     return newNode (NULLOP, initExpr,
5201                     createWhile (trueLabel, continueLabel,
5202                                  falseLabel, condExpr, forBody));
5203   /* vanilla for statement */
5204   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5205
5206   if (condExpr && !IS_IFX (condExpr))
5207     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5208
5209
5210   /* attach condition label to condition */
5211   condExpr = createLabel (condLabel, condExpr);
5212
5213   /* attach body label to body */
5214   forBody = createLabel (trueLabel, forBody);
5215
5216   /* attach continue to forLoop expression & attach */
5217   /* goto the forcond @ and of loopExpression       */
5218   loopExpr = createLabel (continueLabel,
5219                           newNode (NULLOP,
5220                                    loopExpr,
5221                                    newNode (GOTO,
5222                                        newAst_VALUE (symbolVal (condLabel)),
5223                                             NULL)));
5224   /* now start putting them together */
5225   forTree = newNode (NULLOP, initExpr, condExpr);
5226   forTree = newNode (NULLOP, forTree, forBody);
5227   forTree = newNode (NULLOP, forTree, loopExpr);
5228   /* finally add the break label */
5229   forTree = newNode (NULLOP, forTree,
5230                      createLabel (falseLabel, NULL));
5231   return forTree;
5232 }
5233
5234 /*-----------------------------------------------------------------*/
5235 /* createWhile - creates parse tree for while statement            */
5236 /*               the while statement will be created as follows    */
5237 /*                                                                 */
5238 /*      _while_continue_n:                                         */
5239 /*            condition_expression +-> trueLabel -> _while_boby_n  */
5240 /*                                 |                               */
5241 /*                                 +-> falseLabel -> _while_break_n */
5242 /*      _while_body_n:                                             */
5243 /*            statements                                           */
5244 /*            goto _while_continue_n                               */
5245 /*      _while_break_n:                                            */
5246 /*-----------------------------------------------------------------*/
5247 ast *
5248 createWhile (symbol * trueLabel, symbol * continueLabel,
5249              symbol * falseLabel, ast * condExpr, ast * whileBody)
5250 {
5251   ast *whileTree;
5252
5253   /* put the continue label */
5254   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5255   condExpr = createLabel (continueLabel, condExpr);
5256   condExpr->lineno = 0;
5257
5258   /* put the body label in front of the body */
5259   whileBody = createLabel (trueLabel, whileBody);
5260   whileBody->lineno = 0;
5261   /* put a jump to continue at the end of the body */
5262   /* and put break label at the end of the body */
5263   whileBody = newNode (NULLOP,
5264                        whileBody,
5265                        newNode (GOTO,
5266                                 newAst_VALUE (symbolVal (continueLabel)),
5267                                 createLabel (falseLabel, NULL)));
5268
5269   /* put it all together */
5270   if (IS_IFX (condExpr))
5271     whileTree = condExpr;
5272   else
5273     {
5274       whileTree = newNode (IFX, condExpr, NULL);
5275       /* put the true & false labels in place */
5276       whileTree->trueLabel = trueLabel;
5277       whileTree->falseLabel = falseLabel;
5278     }
5279
5280   return newNode (NULLOP, whileTree, whileBody);
5281 }
5282
5283 /*-----------------------------------------------------------------*/
5284 /* isShiftRightLitVal _BitAndLitVal - helper function              */
5285 /*-----------------------------------------------------------------*/
5286 static ast *
5287 isShiftRightLitVal_BitAndLitVal (ast * tree)
5288 {
5289   /* if this is not a bit and */
5290   if (!IS_BITAND (tree))
5291     return NULL;
5292
5293   /* will look for tree of the form
5294      ( expr >> litval2) & litval1 */
5295   if (!IS_AST_LIT_VALUE (tree->right))
5296     return NULL;
5297
5298   if (!IS_RIGHT_OP (tree->left))
5299     return NULL;
5300
5301   if (!IS_AST_LIT_VALUE (tree->left->right))
5302     return NULL;
5303
5304   return tree->left->left;
5305 }
5306
5307 /*-----------------------------------------------------------------*/
5308 /* isBitAndPowOf2 - helper function                                */
5309 /*-----------------------------------------------------------------*/
5310 static int
5311 isBitAndPow2 (ast * tree)
5312 {
5313   /* if this is not a bit and */
5314   if (!IS_BITAND (tree))
5315     return -1;
5316
5317   /* will look for tree of the form
5318      ( expr & (1 << litval) */
5319   if (!IS_AST_LIT_VALUE (tree->right))
5320     return -1;
5321
5322   return powof2 ((TYPE_UDWORD)AST_LIT_VALUE (tree->right));
5323 }
5324
5325 /*-----------------------------------------------------------------*/
5326 /* optimizeGetHbit - get highest order bit of the expression       */
5327 /*-----------------------------------------------------------------*/
5328 ast *
5329 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5330 {
5331   int i, j;
5332   ast * expr;
5333
5334   expr = isShiftRightLitVal_BitAndLitVal(tree);
5335   if (expr)
5336     {
5337       if ((AST_LIT_VALUE (tree->right) != 1) ||
5338           ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5339           (j = (getSize (TTYPE (expr)) * 8 - 1))))
5340         expr = NULL;
5341     }
5342   if (!expr && (resultType == RESULT_TYPE_BIT))
5343     {
5344       expr = tree->left;
5345       if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5346         expr = NULL;
5347     }
5348   if (!expr)
5349     return tree;
5350
5351   /* make sure the port supports GETHBIT */
5352   if (port->hasExtBitOp
5353       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5354     return tree;
5355
5356   return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5357 }
5358
5359 /*-----------------------------------------------------------------*/
5360 /* optimizeGetAbit - get a single bit of the expression            */
5361 /*-----------------------------------------------------------------*/
5362 ast *
5363 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5364 {
5365   ast * expr;
5366   ast * count = NULL;
5367
5368   expr = isShiftRightLitVal_BitAndLitVal(tree);
5369   if (expr)
5370     {
5371   if (AST_LIT_VALUE (tree->right) != 1)
5372         expr = NULL;
5373       count = tree->left->right;
5374     }
5375   if (!expr && (resultType == RESULT_TYPE_BIT))
5376     {
5377       int p2 = isBitAndPow2 (tree);
5378       if (p2 >= 0)
5379         {
5380           expr = tree->left;
5381           count = newAst_VALUE (valueFromLit (p2));
5382         }
5383     }
5384   if (!expr)
5385     return tree;
5386
5387   /* make sure the port supports GETABIT */
5388   if (port->hasExtBitOp
5389       && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5390     return tree;
5391
5392   return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5393
5394 }
5395
5396 /*-----------------------------------------------------------------*/
5397 /* optimizeGetByte - get a byte of the expression                  */
5398 /*-----------------------------------------------------------------*/
5399 ast *
5400 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5401 {
5402   unsigned int i = 0;
5403   ast * expr;
5404   ast * count = NULL;
5405
5406   expr = isShiftRightLitVal_BitAndLitVal(tree);
5407   if (expr)
5408     {
5409       i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5410       count = tree->left->right;
5411       if (AST_LIT_VALUE (tree->right) != 0xFF)
5412         expr = NULL;
5413     }
5414   if (!expr && resultType == RESULT_TYPE_CHAR)
5415     {
5416       /* if this is a right shift over a multiple of 8 */
5417       if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5418         {
5419           i = (unsigned int) AST_LIT_VALUE (tree->right);
5420           count = tree->right;
5421             expr = tree->left;
5422         }
5423     }
5424   if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5425     return tree;
5426
5427   /* make sure the port supports GETBYTE */
5428   if (port->hasExtBitOp
5429       && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5430     return tree;
5431
5432   return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5433 }
5434
5435 /*-----------------------------------------------------------------*/
5436 /* optimizeGetWord - get two bytes of the expression               */
5437 /*-----------------------------------------------------------------*/
5438 ast *
5439 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5440 {
5441   unsigned int i = 0;
5442   ast * expr;
5443   ast * count = NULL;
5444
5445   expr = isShiftRightLitVal_BitAndLitVal(tree);
5446   if (expr)
5447     {
5448       i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5449       count = tree->left->right;
5450       if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5451         expr = NULL;
5452     }
5453   if (!expr && resultType == RESULT_TYPE_INT)
5454     {
5455       /* if this is a right shift over a multiple of 8 */
5456       if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5457         {
5458           i = (unsigned int) AST_LIT_VALUE (tree->right);
5459           count = tree->right;
5460             expr = tree->left;
5461         }
5462     }
5463   if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5464     return tree;
5465
5466   /* make sure the port supports GETWORD */
5467   if (port->hasExtBitOp
5468       && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5469     return tree;
5470
5471   return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5472 }
5473
5474 /*-----------------------------------------------------------------*/
5475 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
5476 /*-----------------------------------------------------------------*/
5477 ast *
5478 optimizeRRCRLC (ast * root)
5479 {
5480   /* will look for trees of the form
5481      (?expr << 1) | (?expr >> 7) or
5482      (?expr >> 7) | (?expr << 1) will make that
5483      into a RLC : operation ..
5484      Will also look for
5485      (?expr >> 1) | (?expr << 7) or
5486      (?expr << 7) | (?expr >> 1) will make that
5487      into a RRC operation
5488      note : by 7 I mean (number of bits required to hold the
5489      variable -1 ) */
5490   /* if the root operation is not a | operation then not */
5491   if (!IS_BITOR (root))
5492     return root;
5493
5494   /* I have to think of a better way to match patterns this sucks */
5495   /* that aside let's start looking for the first case : I use a
5496      negative check a lot to improve the efficiency */
5497   /* (?expr << 1) | (?expr >> 7) */
5498   if (IS_LEFT_OP (root->left) &&
5499       IS_RIGHT_OP (root->right))
5500     {
5501
5502       if (!SPEC_USIGN (TETYPE (root->left->left)))
5503         return root;
5504
5505       if (!IS_AST_LIT_VALUE (root->left->right) ||
5506           !IS_AST_LIT_VALUE (root->right->right))
5507         goto tryNext0;
5508
5509       /* make sure it is the same expression */
5510       if (!isAstEqual (root->left->left,
5511                        root->right->left))
5512         goto tryNext0;
5513
5514       if (AST_LIT_VALUE (root->left->right) != 1)
5515         goto tryNext0;
5516
5517       if (AST_LIT_VALUE (root->right->right) !=
5518           (getSize (TTYPE (root->left->left)) * 8 - 1))
5519         goto tryNext0;
5520
5521       /* make sure the port supports RLC */
5522       if (port->hasExtBitOp
5523           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5524         return root;
5525
5526       /* whew got the first case : create the AST */
5527       return newNode (RLC, root->left->left, NULL);
5528     }
5529
5530 tryNext0:
5531   /* check for second case */
5532   /* (?expr >> 7) | (?expr << 1) */
5533   if (IS_LEFT_OP (root->right) &&
5534       IS_RIGHT_OP (root->left))
5535     {
5536
5537       if (!SPEC_USIGN (TETYPE (root->left->left)))
5538         return root;
5539
5540       if (!IS_AST_LIT_VALUE (root->left->right) ||
5541           !IS_AST_LIT_VALUE (root->right->right))
5542         goto tryNext1;
5543
5544       /* make sure it is the same symbol */
5545       if (!isAstEqual (root->left->left,
5546                        root->right->left))
5547         goto tryNext1;
5548
5549       if (AST_LIT_VALUE (root->right->right) != 1)
5550         goto tryNext1;
5551
5552       if (AST_LIT_VALUE (root->left->right) !=
5553           (getSize (TTYPE (root->left->left)) * 8 - 1))
5554         goto tryNext1;
5555
5556       /* make sure the port supports RLC */
5557       if (port->hasExtBitOp
5558           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5559         return root;
5560
5561       /* whew got the first case : create the AST */
5562       return newNode (RLC, root->left->left, NULL);
5563
5564     }
5565
5566 tryNext1:
5567   /* third case for RRC */
5568   /*  (?symbol >> 1) | (?symbol << 7) */
5569   if (IS_LEFT_OP (root->right) &&
5570       IS_RIGHT_OP (root->left))
5571     {
5572
5573       if (!SPEC_USIGN (TETYPE (root->left->left)))
5574         return root;
5575
5576       if (!IS_AST_LIT_VALUE (root->left->right) ||
5577           !IS_AST_LIT_VALUE (root->right->right))
5578         goto tryNext2;
5579
5580       /* make sure it is the same symbol */
5581       if (!isAstEqual (root->left->left,
5582                        root->right->left))
5583         goto tryNext2;
5584
5585       if (AST_LIT_VALUE (root->left->right) != 1)
5586         goto tryNext2;
5587
5588       if (AST_LIT_VALUE (root->right->right) !=
5589           (getSize (TTYPE (root->left->left)) * 8 - 1))
5590         goto tryNext2;
5591
5592       /* make sure the port supports RRC */
5593       if (port->hasExtBitOp
5594           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5595         return root;
5596
5597       /* whew got the first case : create the AST */
5598       return newNode (RRC, root->left->left, NULL);
5599
5600     }
5601 tryNext2:
5602   /* fourth and last case for now */
5603   /* (?symbol << 7) | (?symbol >> 1) */
5604   if (IS_RIGHT_OP (root->right) &&
5605       IS_LEFT_OP (root->left))
5606     {
5607
5608       if (!SPEC_USIGN (TETYPE (root->left->left)))
5609         return root;
5610
5611       if (!IS_AST_LIT_VALUE (root->left->right) ||
5612           !IS_AST_LIT_VALUE (root->right->right))
5613         return root;
5614
5615       /* make sure it is the same symbol */
5616       if (!isAstEqual (root->left->left,
5617                        root->right->left))
5618         return root;
5619
5620       if (AST_LIT_VALUE (root->right->right) != 1)
5621         return root;
5622
5623       if (AST_LIT_VALUE (root->left->right) !=
5624           (getSize (TTYPE (root->left->left)) * 8 - 1))
5625         return root;
5626
5627       /* make sure the port supports RRC */
5628       if (port->hasExtBitOp
5629           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5630         return root;
5631
5632       /* whew got the first case : create the AST */
5633       return newNode (RRC, root->left->left, NULL);
5634
5635     }
5636
5637   /* not found return root */
5638   return root;
5639 }
5640
5641 /*-----------------------------------------------------------------*/
5642 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
5643 /*-----------------------------------------------------------------*/
5644 ast *
5645 optimizeSWAP (ast * root)
5646 {
5647   /* will look for trees of the form
5648      (?expr << 4) | (?expr >> 4) or
5649      (?expr >> 4) | (?expr << 4) will make that
5650      into a SWAP : operation ..
5651      note : by 4 I mean (number of bits required to hold the
5652      variable /2 ) */
5653   /* if the root operation is not a | operation then not */
5654   if (!IS_BITOR (root))
5655     return root;
5656
5657   /* (?expr << 4) | (?expr >> 4) */
5658   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5659       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5660     {
5661
5662       if (!SPEC_USIGN (TETYPE (root->left->left)))
5663         return root;
5664
5665       if (!IS_AST_LIT_VALUE (root->left->right) ||
5666           !IS_AST_LIT_VALUE (root->right->right))
5667         return root;
5668
5669       /* make sure it is the same expression */
5670       if (!isAstEqual (root->left->left,
5671                        root->right->left))
5672         return root;
5673
5674       if (AST_LIT_VALUE (root->left->right) !=
5675           (getSize (TTYPE (root->left->left)) * 4))
5676         return root;
5677
5678       if (AST_LIT_VALUE (root->right->right) !=
5679           (getSize (TTYPE (root->left->left)) * 4))
5680         return root;
5681
5682       /* make sure the port supports SWAP */
5683       if (port->hasExtBitOp
5684           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5685         return root;
5686
5687       /* found it : create the AST */
5688       return newNode (SWAP, root->left->left, NULL);
5689     }
5690
5691
5692   /* not found return root */
5693   return root;
5694 }
5695
5696 /*-----------------------------------------------------------------*/
5697 /* optimizeCompare - optimizes compares for bit variables          */
5698 /*-----------------------------------------------------------------*/
5699 static ast *
5700 optimizeCompare (ast * root)
5701 {
5702   ast *optExpr = NULL;
5703   value *vleft;
5704   value *vright;
5705   unsigned int litValue;
5706
5707   /* if nothing then return nothing */
5708   if (!root)
5709     return NULL;
5710
5711   /* if not a compare op then do leaves */
5712   if (!IS_COMPARE_OP (root))
5713     {
5714       root->left = optimizeCompare (root->left);
5715       root->right = optimizeCompare (root->right);
5716       return root;
5717     }
5718
5719   /* if left & right are the same then depending
5720      of the operation do */
5721   if (isAstEqual (root->left, root->right))
5722     {
5723       switch (root->opval.op)
5724         {
5725         case '>':
5726         case '<':
5727         case NE_OP:
5728           optExpr = newAst_VALUE (constVal ("0"));
5729           break;
5730         case GE_OP:
5731         case LE_OP:
5732         case EQ_OP:
5733           optExpr = newAst_VALUE (constVal ("1"));
5734           break;
5735         }
5736
5737       return decorateType (optExpr, RESULT_TYPE_NONE);
5738     }
5739
5740   vleft = (root->left->type == EX_VALUE ?
5741            root->left->opval.val : NULL);
5742
5743   vright = (root->right->type == EX_VALUE ?
5744             root->right->opval.val : NULL);
5745
5746   /* if left is a BITVAR in BITSPACE */
5747   /* and right is a LITERAL then opt- */
5748   /* imize else do nothing       */
5749   if (vleft && vright &&
5750       IS_BITVAR (vleft->etype) &&
5751       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5752       IS_LITERAL (vright->etype))
5753     {
5754
5755       /* if right side > 1 then comparison may never succeed */
5756       if ((litValue = (int) floatFromVal (vright)) > 1)
5757         {
5758           werror (W_BAD_COMPARE);
5759           goto noOptimize;
5760         }
5761
5762       if (litValue)
5763         {
5764           switch (root->opval.op)
5765             {
5766             case '>':           /* bit value greater than 1 cannot be */
5767               werror (W_BAD_COMPARE);
5768               goto noOptimize;
5769               break;
5770
5771             case '<':           /* bit value < 1 means 0 */
5772             case NE_OP:
5773               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5774               break;
5775
5776             case LE_OP: /* bit value <= 1 means no check */
5777               optExpr = newAst_VALUE (vright);
5778               break;
5779
5780             case GE_OP: /* bit value >= 1 means only check for = */
5781             case EQ_OP:
5782               optExpr = newAst_VALUE (vleft);
5783               break;
5784             }
5785         }
5786       else
5787         {                       /* literal is zero */
5788           switch (root->opval.op)
5789             {
5790             case '<':           /* bit value < 0 cannot be */
5791               werror (W_BAD_COMPARE);
5792               goto noOptimize;
5793               break;
5794
5795             case '>':           /* bit value > 0 means 1 */
5796             case NE_OP:
5797               optExpr = newAst_VALUE (vleft);
5798               break;
5799
5800             case LE_OP: /* bit value <= 0 means no check */
5801             case GE_OP: /* bit value >= 0 means no check */
5802               werror (W_BAD_COMPARE);
5803               goto noOptimize;
5804               break;
5805
5806             case EQ_OP: /* bit == 0 means ! of bit */
5807               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5808               break;
5809             }
5810         }
5811       return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5812     }                           /* end-of-if of BITVAR */
5813
5814 noOptimize:
5815   return root;
5816 }
5817 /*-----------------------------------------------------------------*/
5818 /* addSymToBlock : adds the symbol to the first block we find      */
5819 /*-----------------------------------------------------------------*/
5820 void
5821 addSymToBlock (symbol * sym, ast * tree)
5822 {
5823   /* reached end of tree or a leaf */
5824   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5825     return;
5826
5827   /* found a block */
5828   if (IS_AST_OP (tree) &&
5829       tree->opval.op == BLOCK)
5830     {
5831
5832       symbol *lsym = copySymbol (sym);
5833
5834       lsym->next = AST_VALUES (tree, sym);
5835       AST_VALUES (tree, sym) = lsym;
5836       return;
5837     }
5838
5839   addSymToBlock (sym, tree->left);
5840   addSymToBlock (sym, tree->right);
5841 }
5842
5843 /*-----------------------------------------------------------------*/
5844 /* processRegParms - do processing for register parameters         */
5845 /*-----------------------------------------------------------------*/
5846 static void
5847 processRegParms (value * args, ast * body)
5848 {
5849   while (args)
5850     {
5851       if (IS_REGPARM (args->etype))
5852         addSymToBlock (args->sym, body);
5853       args = args->next;
5854     }
5855 }
5856
5857 /*-----------------------------------------------------------------*/
5858 /* resetParmKey - resets the operandkeys for the symbols           */
5859 /*-----------------------------------------------------------------*/
5860 DEFSETFUNC (resetParmKey)
5861 {
5862   symbol *sym = item;
5863
5864   sym->key = 0;
5865   sym->defs = NULL;
5866   sym->uses = NULL;
5867   sym->remat = 0;
5868   return 1;
5869 }
5870
5871 /*-----------------------------------------------------------------*/
5872 /* createFunction - This is the key node that calls the iCode for  */
5873 /*                  generating the code for a function. Note code  */
5874 /*                  is generated function by function, later when  */
5875 /*                  add inter-procedural analysis this will change */
5876 /*-----------------------------------------------------------------*/
5877 ast *
5878 createFunction (symbol * name, ast * body)
5879 {
5880   ast *ex;
5881   symbol *csym;
5882   int stack = 0;
5883   sym_link *fetype;
5884   iCode *piCode = NULL;
5885
5886   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5887     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5888
5889   /* if check function return 0 then some problem */
5890   if (checkFunction (name, NULL) == 0)
5891     return NULL;
5892
5893   /* create a dummy block if none exists */
5894   if (!body)
5895     body = newNode (BLOCK, NULL, NULL);
5896
5897   noLineno++;
5898
5899   /* check if the function name already in the symbol table */
5900   if ((csym = findSym (SymbolTab, NULL, name->name)))
5901     {
5902       name = csym;
5903       /* special case for compiler defined functions
5904          we need to add the name to the publics list : this
5905          actually means we are now compiling the compiler
5906          support routine */
5907       if (name->cdef)
5908         {
5909           addSet (&publics, name);
5910         }
5911     }
5912   else
5913     {
5914       addSymChain (&name);
5915       allocVariables (name);
5916     }
5917   name->lastLine = mylineno;
5918   currFunc = name;
5919
5920   /* set the stack pointer */
5921   stackPtr  = -port->stack.direction * port->stack.call_overhead;
5922   xstackPtr = 0;
5923
5924   if (IFFUNC_ISISR (name->type))
5925     stackPtr -= port->stack.direction * port->stack.isr_overhead;
5926
5927   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5928     {
5929       if (options.useXstack)
5930         xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5931       else
5932         stackPtr  -= port->stack.direction * port->stack.reent_overhead;
5933     }
5934
5935   fetype = getSpec (name->type);        /* get the specifier for the function */
5936   /* if this is a reentrant function then */
5937   if (IFFUNC_ISREENT (name->type))
5938     reentrant++;
5939
5940   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
5941
5942   /* do processing for parameters that are passed in registers */
5943   processRegParms (FUNC_ARGS(name->type), body);
5944
5945   /* set the stack pointer */
5946   stackPtr = 0;
5947   xstackPtr = -1;
5948
5949   gatherImplicitVariables (body, NULL);  /* move implicit variables into blocks */
5950
5951   /* allocate & autoinit the block variables */
5952   processBlockVars (body, &stack, ALLOCATE);
5953
5954   /* name needs to be mangled */
5955   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5956
5957   body = resolveSymbols (body); /* resolve the symbols */
5958   body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5959
5960   /* save the stack information */
5961   if (options.useXstack)
5962     name->xstack = SPEC_STAK (fetype) = stack;
5963   else
5964     name->stack = SPEC_STAK (fetype) = stack;
5965
5966   ex = newAst_VALUE (symbolVal (name)); /* create name */
5967   ex = newNode (FUNCTION, ex, body);
5968   ex->values.args = FUNC_ARGS(name->type);
5969   ex->decorated=1;
5970   if (options.dump_tree) PA(ex);
5971   if (fatalError)
5972     {
5973       werror (E_FUNC_NO_CODE, name->name);
5974       goto skipall;
5975     }
5976
5977   /* create the node & generate intermediate code */
5978   GcurMemmap = code;
5979   codeOutFile = code->oFile;
5980   piCode = iCodeFromAst (ex);
5981
5982   if (fatalError)
5983     {
5984       werror (E_FUNC_NO_CODE, name->name);
5985       goto skipall;
5986     }
5987
5988   eBBlockFromiCode (piCode);
5989
5990   /* if there are any statics then do them */
5991   if (staticAutos)
5992     {
5993       GcurMemmap = statsg;
5994       codeOutFile = statsg->oFile;
5995       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
5996       staticAutos = NULL;
5997     }
5998
5999 skipall:
6000
6001   /* dealloc the block variables */
6002   processBlockVars (body, &stack, DEALLOCATE);
6003   outputDebugStackSymbols();
6004   /* deallocate paramaters */
6005   deallocParms (FUNC_ARGS(name->type));
6006
6007   if (IFFUNC_ISREENT (name->type))
6008     reentrant--;
6009
6010   /* we are done freeup memory & cleanup */
6011   noLineno--;
6012   if (port->reset_labelKey) labelKey = 1;
6013   name->key = 0;
6014   FUNC_HASBODY(name->type) = 1;
6015   addSet (&operKeyReset, name);
6016   applyToSet (operKeyReset, resetParmKey);
6017
6018   if (options.debug)
6019     cdbStructBlock(1);
6020
6021   cleanUpLevel (LabelTab, 0);
6022   cleanUpBlock (StructTab, 1);
6023   cleanUpBlock (TypedefTab, 1);
6024
6025   xstack->syms = NULL;
6026   istack->syms = NULL;
6027   return NULL;
6028 }
6029
6030
6031 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6032 /*-----------------------------------------------------------------*/
6033 /* ast_print : prints the ast (for debugging purposes)             */
6034 /*-----------------------------------------------------------------*/
6035
6036 void ast_print (ast * tree, FILE *outfile, int indent)
6037 {
6038
6039         if (!tree) return ;
6040
6041         /* can print only decorated trees */
6042         if (!tree->decorated) return;
6043
6044         /* if any child is an error | this one is an error do nothing */
6045         if (tree->isError ||
6046             (tree->left && tree->left->isError) ||
6047             (tree->right && tree->right->isError)) {
6048                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6049         }
6050
6051
6052         /* print the line          */
6053         /* if not block & function */
6054         if (tree->type == EX_OP &&
6055             (tree->opval.op != FUNCTION &&
6056              tree->opval.op != BLOCK &&
6057              tree->opval.op != NULLOP)) {
6058         }
6059
6060         if (tree->opval.op == FUNCTION) {
6061                 int arg=0;
6062                 value *args=FUNC_ARGS(tree->left->opval.val->type);
6063                 fprintf(outfile,"FUNCTION (%s=%p) type (",
6064                         tree->left->opval.val->name, tree);
6065                 printTypeChain (tree->left->opval.val->type->next,outfile);
6066                 fprintf(outfile,") args (");
6067                 do {
6068                   if (arg) {
6069                     fprintf (outfile, ", ");
6070                   }
6071                   printTypeChain (args ? args->type : NULL, outfile);
6072                   arg++;
6073                   args= args ? args->next : NULL;
6074                 } while (args);
6075                 fprintf(outfile,")\n");
6076                 ast_print(tree->left,outfile,indent);
6077                 ast_print(tree->right,outfile,indent);
6078                 return ;
6079         }
6080         if (tree->opval.op == BLOCK) {
6081                 symbol *decls = tree->values.sym;
6082                 INDENT(indent,outfile);
6083                 fprintf(outfile,"{\n");
6084                 while (decls) {
6085                         INDENT(indent+2,outfile);
6086                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6087                                 decls->name, decls);
6088                         printTypeChain(decls->type,outfile);
6089                         fprintf(outfile,")\n");
6090
6091                         decls = decls->next;
6092                 }
6093                 ast_print(tree->right,outfile,indent+2);
6094                 INDENT(indent,outfile);
6095                 fprintf(outfile,"}\n");
6096                 return;
6097         }
6098         if (tree->opval.op == NULLOP) {
6099                 ast_print(tree->left,outfile,indent);
6100                 ast_print(tree->right,outfile,indent);
6101                 return ;
6102         }
6103         INDENT(indent,outfile);
6104
6105         /*------------------------------------------------------------------*/
6106         /*----------------------------*/
6107         /*   leaf has been reached    */
6108         /*----------------------------*/
6109         /* if this is of type value */
6110         /* just get the type        */
6111         if (tree->type == EX_VALUE) {
6112
6113                 if (IS_LITERAL (tree->opval.val->etype)) {
6114                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
6115                         if (SPEC_USIGN (tree->opval.val->etype))
6116                                 fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
6117                         else
6118                                 fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
6119                         fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val),
6120                                                       floatFromVal(tree->opval.val));
6121                 } else if (tree->opval.val->sym) {
6122                         /* if the undefined flag is set then give error message */
6123                         if (tree->opval.val->sym->undefined) {
6124                                 fprintf(outfile,"UNDEFINED SYMBOL ");
6125                         } else {
6126                                 fprintf(outfile,"SYMBOL ");
6127                         }
6128                         fprintf(outfile,"(%s=%p @ %p)",
6129                                 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6130                 }
6131                 if (tree->ftype) {
6132                         fprintf(outfile," type (");
6133                         printTypeChain(tree->ftype,outfile);
6134                         fprintf(outfile,")\n");
6135                 } else {
6136                         fprintf(outfile,"\n");
6137                 }
6138                 return ;
6139         }
6140
6141         /* if type link for the case of cast */
6142         if (tree->type == EX_LINK) {
6143                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6144                 printTypeChain(tree->opval.lnk,outfile);
6145                 fprintf(outfile,")\n");
6146                 return ;
6147         }
6148
6149
6150         /* depending on type of operator do */
6151
6152         switch (tree->opval.op) {
6153                 /*------------------------------------------------------------------*/
6154                 /*----------------------------*/
6155                 /*        array node          */
6156                 /*----------------------------*/
6157         case '[':
6158                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6159                 printTypeChain(tree->ftype,outfile);
6160                 fprintf(outfile,")\n");
6161                 ast_print(tree->left,outfile,indent+2);
6162                 ast_print(tree->right,outfile,indent+2);
6163                 return;
6164
6165                 /*------------------------------------------------------------------*/
6166                 /*----------------------------*/
6167                 /*      struct/union          */
6168                 /*----------------------------*/
6169         case '.':
6170                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6171                 printTypeChain(tree->ftype,outfile);
6172                 fprintf(outfile,")\n");
6173                 ast_print(tree->left,outfile,indent+2);
6174                 ast_print(tree->right,outfile,indent+2);
6175                 return ;
6176
6177                 /*------------------------------------------------------------------*/
6178                 /*----------------------------*/
6179                 /*    struct/union pointer    */
6180                 /*----------------------------*/
6181         case PTR_OP:
6182                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6183                 printTypeChain(tree->ftype,outfile);
6184                 fprintf(outfile,")\n");
6185                 ast_print(tree->left,outfile,indent+2);
6186                 ast_print(tree->right,outfile,indent+2);
6187                 return ;
6188
6189                 /*------------------------------------------------------------------*/
6190                 /*----------------------------*/
6191                 /*  ++/-- operation           */
6192                 /*----------------------------*/
6193         case INC_OP:
6194                 if (tree->left)
6195                   fprintf(outfile,"post-");
6196                 else
6197                   fprintf(outfile,"pre-");
6198                 fprintf(outfile,"INC_OP (%p) type (",tree);
6199                 printTypeChain(tree->ftype,outfile);
6200                 fprintf(outfile,")\n");
6201                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6202                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6203                 return ;
6204
6205         case DEC_OP:
6206                 if (tree->left)
6207                   fprintf(outfile,"post-");
6208                 else
6209                   fprintf(outfile,"pre-");
6210                 fprintf(outfile,"DEC_OP (%p) type (",tree);
6211                 printTypeChain(tree->ftype,outfile);
6212                 fprintf(outfile,")\n");
6213                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6214                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6215                 return ;
6216
6217                 /*------------------------------------------------------------------*/
6218                 /*----------------------------*/
6219                 /*  bitwise and               */
6220                 /*----------------------------*/
6221         case '&':
6222                 if (tree->right) {
6223                         fprintf(outfile,"& (%p) type (",tree);
6224                         printTypeChain(tree->ftype,outfile);
6225                         fprintf(outfile,")\n");
6226                         ast_print(tree->left,outfile,indent+2);
6227                         ast_print(tree->right,outfile,indent+2);
6228                 } else {
6229                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6230                         printTypeChain(tree->ftype,outfile);
6231                         fprintf(outfile,")\n");
6232                         ast_print(tree->left,outfile,indent+2);
6233                         ast_print(tree->right,outfile,indent+2);
6234                 }
6235                 return ;
6236                 /*----------------------------*/
6237                 /*  bitwise or                */
6238                 /*----------------------------*/
6239         case '|':
6240                 fprintf(outfile,"OR (%p) type (",tree);
6241                 printTypeChain(tree->ftype,outfile);
6242                 fprintf(outfile,")\n");
6243                 ast_print(tree->left,outfile,indent+2);
6244                 ast_print(tree->right,outfile,indent+2);
6245                 return ;
6246                 /*------------------------------------------------------------------*/
6247                 /*----------------------------*/
6248                 /*  bitwise xor               */
6249                 /*----------------------------*/
6250         case '^':
6251                 fprintf(outfile,"XOR (%p) type (",tree);
6252                 printTypeChain(tree->ftype,outfile);
6253                 fprintf(outfile,")\n");
6254                 ast_print(tree->left,outfile,indent+2);
6255                 ast_print(tree->right,outfile,indent+2);
6256                 return ;
6257
6258                 /*------------------------------------------------------------------*/
6259                 /*----------------------------*/
6260                 /*  division                  */
6261                 /*----------------------------*/
6262         case '/':
6263                 fprintf(outfile,"DIV (%p) type (",tree);
6264                 printTypeChain(tree->ftype,outfile);
6265                 fprintf(outfile,")\n");
6266                 ast_print(tree->left,outfile,indent+2);
6267                 ast_print(tree->right,outfile,indent+2);
6268                 return ;
6269                 /*------------------------------------------------------------------*/
6270                 /*----------------------------*/
6271                 /*            modulus         */
6272                 /*----------------------------*/
6273         case '%':
6274                 fprintf(outfile,"MOD (%p) type (",tree);
6275                 printTypeChain(tree->ftype,outfile);
6276                 fprintf(outfile,")\n");
6277                 ast_print(tree->left,outfile,indent+2);
6278                 ast_print(tree->right,outfile,indent+2);
6279                 return ;
6280
6281                 /*------------------------------------------------------------------*/
6282                 /*----------------------------*/
6283                 /*  address dereference       */
6284                 /*----------------------------*/
6285         case '*':                       /* can be unary  : if right is null then unary operation */
6286                 if (!tree->right) {
6287                         fprintf(outfile,"DEREF (%p) type (",tree);
6288                         printTypeChain(tree->ftype,outfile);
6289                         fprintf(outfile,")\n");
6290                         ast_print(tree->left,outfile,indent+2);
6291                         return ;
6292                 }
6293                 /*------------------------------------------------------------------*/
6294                 /*----------------------------*/
6295                 /*      multiplication        */
6296                 /*----------------------------*/
6297                 fprintf(outfile,"MULT (%p) type (",tree);
6298                 printTypeChain(tree->ftype,outfile);
6299                 fprintf(outfile,")\n");
6300                 ast_print(tree->left,outfile,indent+2);
6301                 ast_print(tree->right,outfile,indent+2);
6302                 return ;
6303
6304
6305                 /*------------------------------------------------------------------*/
6306                 /*----------------------------*/
6307                 /*    unary '+' operator      */
6308                 /*----------------------------*/
6309         case '+':
6310                 /* if unary plus */
6311                 if (!tree->right) {
6312                         fprintf(outfile,"UPLUS (%p) type (",tree);
6313                         printTypeChain(tree->ftype,outfile);
6314                         fprintf(outfile,")\n");
6315                         ast_print(tree->left,outfile,indent+2);
6316                 } else {
6317                         /*------------------------------------------------------------------*/
6318                         /*----------------------------*/
6319                         /*      addition              */
6320                         /*----------------------------*/
6321                         fprintf(outfile,"ADD (%p) type (",tree);
6322                         printTypeChain(tree->ftype,outfile);
6323                         fprintf(outfile,")\n");
6324                         ast_print(tree->left,outfile,indent+2);
6325                         ast_print(tree->right,outfile,indent+2);
6326                 }
6327                 return;
6328                 /*------------------------------------------------------------------*/
6329                 /*----------------------------*/
6330                 /*      unary '-'             */
6331                 /*----------------------------*/
6332         case '-':                       /* can be unary   */
6333                 if (!tree->right) {
6334                         fprintf(outfile,"UMINUS (%p) type (",tree);
6335                         printTypeChain(tree->ftype,outfile);
6336                         fprintf(outfile,")\n");
6337                         ast_print(tree->left,outfile,indent+2);
6338                 } else {
6339                         /*------------------------------------------------------------------*/
6340                         /*----------------------------*/
6341                         /*      subtraction           */
6342                         /*----------------------------*/
6343                         fprintf(outfile,"SUB (%p) type (",tree);
6344                         printTypeChain(tree->ftype,outfile);
6345                         fprintf(outfile,")\n");
6346                         ast_print(tree->left,outfile,indent+2);
6347                         ast_print(tree->right,outfile,indent+2);
6348                 }
6349                 return;
6350                 /*------------------------------------------------------------------*/
6351                 /*----------------------------*/
6352                 /*    complement              */
6353                 /*----------------------------*/
6354         case '~':
6355                 fprintf(outfile,"COMPL (%p) type (",tree);
6356                 printTypeChain(tree->ftype,outfile);
6357                 fprintf(outfile,")\n");
6358                 ast_print(tree->left,outfile,indent+2);
6359                 return ;
6360                 /*------------------------------------------------------------------*/
6361                 /*----------------------------*/
6362                 /*           not              */
6363                 /*----------------------------*/
6364         case '!':
6365                 fprintf(outfile,"NOT (%p) type (",tree);
6366                 printTypeChain(tree->ftype,outfile);
6367                 fprintf(outfile,")\n");
6368                 ast_print(tree->left,outfile,indent+2);
6369                 return ;
6370                 /*------------------------------------------------------------------*/
6371                 /*----------------------------*/
6372                 /*           shift            */
6373                 /*----------------------------*/
6374         case RRC:
6375                 fprintf(outfile,"RRC (%p) type (",tree);
6376                 printTypeChain(tree->ftype,outfile);
6377                 fprintf(outfile,")\n");
6378                 ast_print(tree->left,outfile,indent+2);
6379                 return ;
6380
6381         case RLC:
6382                 fprintf(outfile,"RLC (%p) type (",tree);
6383                 printTypeChain(tree->ftype,outfile);
6384                 fprintf(outfile,")\n");
6385                 ast_print(tree->left,outfile,indent+2);
6386                 return ;
6387         case SWAP:
6388                 fprintf(outfile,"SWAP (%p) type (",tree);
6389                 printTypeChain(tree->ftype,outfile);
6390                 fprintf(outfile,")\n");
6391                 ast_print(tree->left,outfile,indent+2);
6392                 return ;
6393         case GETHBIT:
6394                 fprintf(outfile,"GETHBIT (%p) type (",tree);
6395                 printTypeChain(tree->ftype,outfile);
6396                 fprintf(outfile,")\n");
6397                 ast_print(tree->left,outfile,indent+2);
6398                 return ;
6399         case GETABIT:
6400                 fprintf(outfile,"GETABIT (%p) type (",tree);
6401                 printTypeChain(tree->ftype,outfile);
6402                 fprintf(outfile,")\n");
6403                 ast_print(tree->left,outfile,indent+2);
6404                 ast_print(tree->right,outfile,indent+2);
6405                 return ;
6406         case GETBYTE:
6407                 fprintf(outfile,"GETBYTE (%p) type (",tree);
6408                 printTypeChain(tree->ftype,outfile);
6409                 fprintf(outfile,")\n");
6410                 ast_print(tree->left,outfile,indent+2);
6411                 ast_print(tree->right,outfile,indent+2);
6412                 return ;
6413         case GETWORD:
6414                 fprintf(outfile,"GETWORD (%p) type (",tree);
6415                 printTypeChain(tree->ftype,outfile);
6416                 fprintf(outfile,")\n");
6417                 ast_print(tree->left,outfile,indent+2);
6418                 ast_print(tree->right,outfile,indent+2);
6419                 return ;
6420         case LEFT_OP:
6421                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6422                 printTypeChain(tree->ftype,outfile);
6423                 fprintf(outfile,")\n");
6424                 ast_print(tree->left,outfile,indent+2);
6425                 ast_print(tree->right,outfile,indent+2);
6426                 return ;
6427         case RIGHT_OP:
6428                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6429                 printTypeChain(tree->ftype,outfile);
6430                 fprintf(outfile,")\n");
6431                 ast_print(tree->left,outfile,indent+2);
6432                 ast_print(tree->right,outfile,indent+2);
6433                 return ;
6434                 /*------------------------------------------------------------------*/
6435                 /*----------------------------*/
6436                 /*         casting            */
6437                 /*----------------------------*/
6438         case CAST:                      /* change the type   */
6439                 fprintf(outfile,"CAST (%p) from type (",tree);
6440                 printTypeChain(tree->right->ftype,outfile);
6441                 fprintf(outfile,") to type (");
6442                 printTypeChain(tree->ftype,outfile);
6443                 fprintf(outfile,")\n");
6444                 ast_print(tree->right,outfile,indent+2);
6445                 return ;
6446
6447         case AND_OP:
6448                 fprintf(outfile,"ANDAND (%p) type (",tree);
6449                 printTypeChain(tree->ftype,outfile);
6450                 fprintf(outfile,")\n");
6451                 ast_print(tree->left,outfile,indent+2);
6452                 ast_print(tree->right,outfile,indent+2);
6453                 return ;
6454         case OR_OP:
6455                 fprintf(outfile,"OROR (%p) type (",tree);
6456                 printTypeChain(tree->ftype,outfile);
6457                 fprintf(outfile,")\n");
6458                 ast_print(tree->left,outfile,indent+2);
6459                 ast_print(tree->right,outfile,indent+2);
6460                 return ;
6461
6462                 /*------------------------------------------------------------------*/
6463                 /*----------------------------*/
6464                 /*     comparison operators   */
6465                 /*----------------------------*/
6466         case '>':
6467                 fprintf(outfile,"GT(>) (%p) type (",tree);
6468                 printTypeChain(tree->ftype,outfile);
6469                 fprintf(outfile,")\n");
6470                 ast_print(tree->left,outfile,indent+2);
6471                 ast_print(tree->right,outfile,indent+2);
6472                 return ;
6473         case '<':
6474                 fprintf(outfile,"LT(<) (%p) type (",tree);
6475                 printTypeChain(tree->ftype,outfile);
6476                 fprintf(outfile,")\n");
6477                 ast_print(tree->left,outfile,indent+2);
6478                 ast_print(tree->right,outfile,indent+2);
6479                 return ;
6480         case LE_OP:
6481                 fprintf(outfile,"LE(<=) (%p) type (",tree);
6482                 printTypeChain(tree->ftype,outfile);
6483                 fprintf(outfile,")\n");
6484                 ast_print(tree->left,outfile,indent+2);
6485                 ast_print(tree->right,outfile,indent+2);
6486                 return ;
6487         case GE_OP:
6488                 fprintf(outfile,"GE(>=) (%p) type (",tree);
6489                 printTypeChain(tree->ftype,outfile);
6490                 fprintf(outfile,")\n");
6491                 ast_print(tree->left,outfile,indent+2);
6492                 ast_print(tree->right,outfile,indent+2);
6493                 return ;
6494         case EQ_OP:
6495                 fprintf(outfile,"EQ(==) (%p) type (",tree);
6496                 printTypeChain(tree->ftype,outfile);
6497                 fprintf(outfile,")\n");
6498                 ast_print(tree->left,outfile,indent+2);
6499                 ast_print(tree->right,outfile,indent+2);
6500                 return ;
6501         case NE_OP:
6502                 fprintf(outfile,"NE(!=) (%p) type (",tree);
6503                 printTypeChain(tree->ftype,outfile);
6504                 fprintf(outfile,")\n");
6505                 ast_print(tree->left,outfile,indent+2);
6506                 ast_print(tree->right,outfile,indent+2);
6507                 /*------------------------------------------------------------------*/
6508                 /*----------------------------*/
6509                 /*             sizeof         */
6510                 /*----------------------------*/
6511         case SIZEOF:            /* evaluate wihout code generation */
6512                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6513                 return ;
6514
6515                 /*------------------------------------------------------------------*/
6516                 /*----------------------------*/
6517                 /* conditional operator  '?'  */
6518                 /*----------------------------*/
6519         case '?':
6520                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6521                 printTypeChain(tree->ftype,outfile);
6522                 fprintf(outfile,")\n");
6523                 ast_print(tree->left,outfile,indent+2);
6524                 ast_print(tree->right,outfile,indent+2);
6525                 return;
6526
6527         case ':':
6528                 fprintf(outfile,"COLON(:) (%p) type (",tree);
6529                 printTypeChain(tree->ftype,outfile);
6530                 fprintf(outfile,")\n");
6531                 ast_print(tree->left,outfile,indent+2);
6532                 ast_print(tree->right,outfile,indent+2);
6533                 return ;
6534
6535                 /*------------------------------------------------------------------*/
6536                 /*----------------------------*/
6537                 /*    assignment operators    */
6538                 /*----------------------------*/
6539         case MUL_ASSIGN:
6540                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6541                 printTypeChain(tree->ftype,outfile);
6542                 fprintf(outfile,")\n");
6543                 ast_print(tree->left,outfile,indent+2);
6544                 ast_print(tree->right,outfile,indent+2);
6545                 return;
6546         case DIV_ASSIGN:
6547                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6548                 printTypeChain(tree->ftype,outfile);
6549                 fprintf(outfile,")\n");
6550                 ast_print(tree->left,outfile,indent+2);
6551                 ast_print(tree->right,outfile,indent+2);
6552                 return;
6553         case AND_ASSIGN:
6554                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6555                 printTypeChain(tree->ftype,outfile);
6556                 fprintf(outfile,")\n");
6557                 ast_print(tree->left,outfile,indent+2);
6558                 ast_print(tree->right,outfile,indent+2);
6559                 return;
6560         case OR_ASSIGN:
6561                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6562                 printTypeChain(tree->ftype,outfile);
6563                 fprintf(outfile,")\n");
6564                 ast_print(tree->left,outfile,indent+2);
6565                 ast_print(tree->right,outfile,indent+2);
6566                 return;
6567         case XOR_ASSIGN:
6568                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6569                 printTypeChain(tree->ftype,outfile);
6570                 fprintf(outfile,")\n");
6571                 ast_print(tree->left,outfile,indent+2);
6572                 ast_print(tree->right,outfile,indent+2);
6573                 return;
6574         case RIGHT_ASSIGN:
6575                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6576                 printTypeChain(tree->ftype,outfile);
6577                 fprintf(outfile,")\n");
6578                 ast_print(tree->left,outfile,indent+2);
6579                 ast_print(tree->right,outfile,indent+2);
6580                 return;
6581         case LEFT_ASSIGN:
6582                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6583                 printTypeChain(tree->ftype,outfile);
6584                 fprintf(outfile,")\n");
6585                 ast_print(tree->left,outfile,indent+2);
6586                 ast_print(tree->right,outfile,indent+2);
6587                 return;
6588                 /*------------------------------------------------------------------*/
6589                 /*----------------------------*/
6590                 /*    -= operator             */
6591                 /*----------------------------*/
6592         case SUB_ASSIGN:
6593                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6594                 printTypeChain(tree->ftype,outfile);
6595                 fprintf(outfile,")\n");
6596                 ast_print(tree->left,outfile,indent+2);
6597                 ast_print(tree->right,outfile,indent+2);
6598                 return;
6599                 /*------------------------------------------------------------------*/
6600                 /*----------------------------*/
6601                 /*          += operator       */
6602                 /*----------------------------*/
6603         case ADD_ASSIGN:
6604                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6605                 printTypeChain(tree->ftype,outfile);
6606                 fprintf(outfile,")\n");
6607                 ast_print(tree->left,outfile,indent+2);
6608                 ast_print(tree->right,outfile,indent+2);
6609                 return;
6610                 /*------------------------------------------------------------------*/
6611                 /*----------------------------*/
6612                 /*      straight assignemnt   */
6613                 /*----------------------------*/
6614         case '=':
6615                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6616                 printTypeChain(tree->ftype,outfile);
6617                 fprintf(outfile,")\n");
6618                 ast_print(tree->left,outfile,indent+2);
6619                 ast_print(tree->right,outfile,indent+2);
6620                 return;
6621                 /*------------------------------------------------------------------*/
6622                 /*----------------------------*/
6623                 /*      comma operator        */
6624                 /*----------------------------*/
6625         case ',':
6626                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6627                 printTypeChain(tree->ftype,outfile);
6628                 fprintf(outfile,")\n");
6629                 ast_print(tree->left,outfile,indent+2);
6630                 ast_print(tree->right,outfile,indent+2);
6631                 return;
6632                 /*------------------------------------------------------------------*/
6633                 /*----------------------------*/
6634                 /*       function call        */
6635                 /*----------------------------*/
6636         case CALL:
6637         case PCALL:
6638                 fprintf(outfile,"CALL (%p) type (",tree);
6639                 printTypeChain(tree->ftype,outfile);
6640                 fprintf(outfile,")\n");
6641                 ast_print(tree->left,outfile,indent+2);
6642                 ast_print(tree->right,outfile,indent+2);
6643                 return;
6644         case PARAM:
6645                 fprintf(outfile,"PARMS\n");
6646                 ast_print(tree->left,outfile,indent+2);
6647                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6648                         ast_print(tree->right,outfile,indent+2);
6649                 }
6650                 return ;
6651                 /*------------------------------------------------------------------*/
6652                 /*----------------------------*/
6653                 /*     return statement       */
6654                 /*----------------------------*/
6655         case RETURN:
6656                 fprintf(outfile,"RETURN (%p) type (",tree);
6657                 if (tree->right) {
6658                     printTypeChain(tree->right->ftype,outfile);
6659                 }
6660                 fprintf(outfile,")\n");
6661                 ast_print(tree->right,outfile,indent+2);
6662                 return ;
6663                 /*------------------------------------------------------------------*/
6664                 /*----------------------------*/
6665                 /*     label statement        */
6666                 /*----------------------------*/
6667         case LABEL :
6668                 fprintf(outfile,"LABEL (%p)\n",tree);
6669                 ast_print(tree->left,outfile,indent+2);
6670                 ast_print(tree->right,outfile,indent);
6671                 return;
6672                 /*------------------------------------------------------------------*/
6673                 /*----------------------------*/
6674                 /*     switch statement       */
6675                 /*----------------------------*/
6676         case SWITCH:
6677                 {
6678                         value *val;
6679                         fprintf(outfile,"SWITCH (%p) ",tree);
6680                         ast_print(tree->left,outfile,0);
6681                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6682                                 INDENT(indent+2,outfile);
6683                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6684                                         (int) floatFromVal(val),
6685                                         tree->values.switchVals.swNum,
6686                                         (int) floatFromVal(val));
6687                         }
6688                         ast_print(tree->right,outfile,indent);
6689                 }
6690                 return ;
6691                 /*------------------------------------------------------------------*/
6692                 /*----------------------------*/
6693                 /* ifx Statement              */
6694                 /*----------------------------*/
6695         case IFX:
6696                 fprintf(outfile,"IF (%p) \n",tree);
6697                 ast_print(tree->left,outfile,indent+2);
6698                 if (tree->trueLabel) {
6699                         INDENT(indent+2,outfile);
6700                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6701                 }
6702                 if (tree->falseLabel) {
6703                         INDENT(indent+2,outfile);
6704                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6705                 }
6706                 ast_print(tree->right,outfile,indent+2);
6707                 return ;
6708                 /*----------------------------*/
6709                 /* goto Statement              */
6710                 /*----------------------------*/
6711         case GOTO:
6712                 fprintf(outfile,"GOTO (%p) \n",tree);
6713                 ast_print(tree->left,outfile,indent+2);
6714                 fprintf(outfile,"\n");
6715                 return ;
6716                 /*------------------------------------------------------------------*/
6717                 /*----------------------------*/
6718                 /* for Statement              */
6719                 /*----------------------------*/
6720         case FOR:
6721                 fprintf(outfile,"FOR (%p) \n",tree);
6722                 if (AST_FOR( tree, initExpr)) {
6723                         INDENT(indent+2,outfile);
6724                         fprintf(outfile,"INIT EXPR ");
6725                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6726                 }
6727                 if (AST_FOR( tree, condExpr)) {
6728                         INDENT(indent+2,outfile);
6729                         fprintf(outfile,"COND EXPR ");
6730                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6731                 }
6732                 if (AST_FOR( tree, loopExpr)) {
6733                         INDENT(indent+2,outfile);
6734                         fprintf(outfile,"LOOP EXPR ");
6735                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6736                 }
6737                 fprintf(outfile,"FOR LOOP BODY \n");
6738                 ast_print(tree->left,outfile,indent+2);
6739                 return ;
6740         case CRITICAL:
6741                 fprintf(outfile,"CRITICAL (%p) \n",tree);
6742                 ast_print(tree->left,outfile,indent+2);
6743         default:
6744             return ;
6745         }
6746 }
6747
6748 void PA(ast *t)
6749 {
6750         ast_print(t,stdout,0);
6751 }
6752
6753
6754
6755 /*-----------------------------------------------------------------*/
6756 /* astErrors : returns non-zero if errors present in tree          */
6757 /*-----------------------------------------------------------------*/
6758 int astErrors(ast *t)
6759 {
6760   int errors=0;
6761
6762   if (t)
6763     {
6764       if (t->isError)
6765         errors++;
6766
6767       if (t->type == EX_VALUE
6768           && t->opval.val->sym
6769           && t->opval.val->sym->undefined)
6770         errors++;
6771
6772       errors += astErrors(t->left);
6773       errors += astErrors(t->right);
6774     }
6775
6776   return errors;
6777 }