* as/hc08/lkaomf51.c (OutputName),
[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 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_TARGET_ULONG) 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_TARGET_ULONG) 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_TARGET_ULONG) 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                                         || TARGET_IS_PIC16) )
3871           {
3872             switch (SPEC_SCLS (sym->etype))
3873               {
3874               case S_CODE:
3875                 gptype = GPTYPE_CODE;
3876                 break;
3877               case S_XDATA:
3878                 gptype = GPTYPE_FAR;
3879                 break;
3880               case S_DATA:
3881               case S_IDATA:
3882                 gptype = GPTYPE_NEAR;
3883                 break;
3884               case S_PDATA:
3885                 gptype = GPTYPE_XSTACK;
3886                 break;
3887               default:
3888                 gptype = 0;
3889
3890                 if(TARGET_IS_PIC16 && (SPEC_SCLS(sym->etype) == S_FIXED))
3891                     gptype = GPTYPE_NEAR;
3892               }
3893             addr |= gptype << (8*(GPTRSIZE - 1));
3894           }
3895
3896         tree->type = EX_VALUE;
3897         tree->opval.val =
3898           valCastLiteral (LTYPE (tree), addr);
3899         TTYPE (tree) = tree->opval.val->type;
3900         TETYPE (tree) = getSpec (TTYPE (tree));
3901         tree->left = NULL;
3902         tree->right = NULL;
3903         tree->values.literalFromCast = 1;
3904         return tree;
3905       }
3906
3907       /* handle offsetof macro:            */
3908       /* #define offsetof(TYPE, MEMBER) \  */
3909       /* ((unsigned) &((TYPE *)0)->MEMBER) */
3910       if (IS_ADDRESS_OF_OP(tree->right)
3911           && IS_AST_OP (tree->right->left)
3912           && tree->right->left->opval.op == PTR_OP
3913           && IS_AST_OP (tree->right->left->left)
3914           && tree->right->left->left->opval.op == CAST
3915           && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
3916
3917         symbol *element = getStructElement (
3918           SPEC_STRUCT (LETYPE(tree->right->left)),
3919           AST_SYMBOL(tree->right->left->right)
3920         );
3921
3922         if (element) {
3923           tree->type = EX_VALUE;
3924           tree->opval.val = valCastLiteral (
3925             LTYPE (tree),
3926             element->offset
3927             + floatFromVal (valFromType (RTYPE (tree->right->left->left)))
3928           );
3929
3930           TTYPE (tree) = tree->opval.val->type;
3931           TETYPE (tree) = getSpec (TTYPE (tree));
3932           tree->left = NULL;
3933           tree->right = NULL;
3934           return tree;
3935         }
3936       }
3937
3938       /* if the right is a literal replace the tree */
3939       if (IS_LITERAL (RETYPE (tree))) {
3940         #if 0
3941         if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
3942           /* rewrite      (type *)litaddr
3943              as           &temp
3944              and define   type at litaddr temp
3945              (but only if type's storage class is not generic)
3946           */
3947           ast *newTree = newNode ('&', NULL, NULL);
3948           symbol *sym;
3949
3950           TTYPE (newTree) = LTYPE (tree);
3951           TETYPE (newTree) = getSpec(LTYPE (tree));
3952
3953           /* define a global symbol at the casted address*/
3954           sym = newSymbol(genSymName (0), 0);
3955           sym->type = LTYPE (tree)->next;
3956           if (!sym->type)
3957             sym->type = newLink (V_VOID);
3958           sym->etype = getSpec(sym->type);
3959           SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
3960           sym->lineDef = tree->lineno;
3961           sym->cdef = 1;
3962           sym->isref = 1;
3963           SPEC_STAT (sym->etype) = 1;
3964           SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RTYPE (tree)));
3965           SPEC_ABSA(sym->etype) = 1;
3966           addSym (SymbolTab, sym, sym->name, 0, 0, 0);
3967           allocGlobal (sym);
3968
3969           newTree->left = newAst_VALUE(symbolVal(sym));
3970           newTree->left->lineno = tree->lineno;
3971           LTYPE (newTree) = sym->type;
3972           LETYPE (newTree) = sym->etype;
3973           LLVAL (newTree) = 1;
3974           LRVAL (newTree) = 0;
3975           TLVAL (newTree) = 1;
3976           return newTree;
3977         }
3978         #endif
3979         if (!IS_PTR (LTYPE (tree))) {
3980           tree->type = EX_VALUE;
3981           tree->opval.val =
3982           valCastLiteral (LTYPE (tree),
3983                           floatFromVal (valFromType (RTYPE (tree))));
3984           TTYPE (tree) = tree->opval.val->type;
3985           tree->left = NULL;
3986           tree->right = NULL;
3987           tree->values.literalFromCast = 1;
3988           TETYPE (tree) = getSpec (TTYPE (tree));
3989           return tree;
3990         }
3991       }
3992       TTYPE (tree) = LTYPE (tree);
3993       LRVAL (tree) = 1;
3994
3995 #endif
3996       TETYPE (tree) = getSpec (TTYPE (tree));
3997
3998       return tree;
3999
4000       /*------------------------------------------------------------------*/
4001       /*----------------------------*/
4002       /*       logical &&, ||       */
4003       /*----------------------------*/
4004     case AND_OP:
4005     case OR_OP:
4006       /* each must be arithmetic type or be a pointer */
4007       if (!IS_PTR (LTYPE (tree)) &&
4008           !IS_ARRAY (LTYPE (tree)) &&
4009           !IS_INTEGRAL (LTYPE (tree)))
4010         {
4011           werror (E_COMPARE_OP);
4012           goto errorTreeReturn;
4013         }
4014
4015       if (!IS_PTR (RTYPE (tree)) &&
4016           !IS_ARRAY (RTYPE (tree)) &&
4017           !IS_INTEGRAL (RTYPE (tree)))
4018         {
4019           werror (E_COMPARE_OP);
4020           goto errorTreeReturn;
4021         }
4022       /* if they are both literal then */
4023       /* rewrite the tree */
4024       if (IS_LITERAL (RTYPE (tree)) &&
4025           IS_LITERAL (LTYPE (tree)))
4026         {
4027           tree->type = EX_VALUE;
4028           tree->opval.val = valLogicAndOr (valFromType (LTYPE (tree)),
4029                                            valFromType (RTYPE (tree)),
4030                                            tree->opval.op);
4031           tree->right = tree->left = NULL;
4032           TETYPE (tree) = getSpec (TTYPE (tree) =
4033                                    tree->opval.val->type);
4034           return tree;
4035         }
4036       LRVAL (tree) = RRVAL (tree) = 1;
4037       TTYPE (tree) = TETYPE (tree) = (resultTypeProp == RESULT_TYPE_BIT) ? newBoolLink() :newCharLink();
4038       return tree;
4039
4040       /*------------------------------------------------------------------*/
4041       /*----------------------------*/
4042       /*     comparison operators   */
4043       /*----------------------------*/
4044     case '>':
4045     case '<':
4046     case LE_OP:
4047     case GE_OP:
4048     case EQ_OP:
4049     case NE_OP:
4050       {
4051         ast *lt = optimizeCompare (tree);
4052
4053         if (tree != lt)
4054           return lt;
4055       }
4056
4057       /* if they are pointers they must be castable */
4058       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4059         {
4060           if (tree->opval.op==EQ_OP &&
4061               !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
4062             // we cannot cast a gptr to a !gptr: switch the leaves
4063             struct ast *s=tree->left;
4064             tree->left=tree->right;
4065             tree->right=s;
4066           }
4067           if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4068             {
4069               werror (E_COMPARE_OP);
4070               fprintf (stderr, "comparing type ");
4071               printTypeChain (LTYPE (tree), stderr);
4072               fprintf (stderr, "to type ");
4073               printTypeChain (RTYPE (tree), stderr);
4074               fprintf (stderr, "\n");
4075               goto errorTreeReturn;
4076             }
4077         }
4078       /* else they should be promotable to one another */
4079       else
4080         {
4081           if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) ||
4082                 (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree)))))
4083
4084             if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4085               {
4086                 werror (E_COMPARE_OP);
4087                 fprintf (stderr, "comparing type ");
4088                 printTypeChain (LTYPE (tree), stderr);
4089                 fprintf (stderr, "to type ");
4090                 printTypeChain (RTYPE (tree), stderr);
4091                 fprintf (stderr, "\n");
4092                 goto errorTreeReturn;
4093               }
4094         }
4095
4096       {
4097         CCR_RESULT ccr_result = CCR_OK;
4098
4099         /* if left is integral and right is literal
4100            then check constant range */
4101         if (IS_INTEGRAL(LTYPE(tree)) && IS_LITERAL(RTYPE(tree)))
4102           ccr_result = checkConstantRange (LTYPE (tree), RTYPE (tree),
4103                                            tree->opval.op, FALSE);
4104         if (ccr_result == CCR_OK &&
4105             IS_INTEGRAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree)))
4106           ccr_result = checkConstantRange (RTYPE (tree), LTYPE (tree),
4107                                            tree->opval.op, TRUE);
4108         switch (ccr_result)
4109             {
4110               case CCR_ALWAYS_TRUE:
4111               case CCR_ALWAYS_FALSE:
4112                 if (!options.lessPedantic)
4113                   werror (W_COMP_RANGE,
4114                           ccr_result == CCR_ALWAYS_TRUE ? "true" : "false");
4115                 return decorateType (newAst_VALUE (constVal (
4116                                    ccr_result == CCR_ALWAYS_TRUE ? "1" : "0")),
4117                                                    resultType);
4118               case CCR_OK:
4119               default:
4120                 break;
4121             }
4122       }
4123
4124       /* if (unsigned value) > 0 then '(unsigned value) ? 1 : 0' */
4125       if (tree->opval.op == '>' &&
4126           SPEC_USIGN(LETYPE(tree)) &&
4127           IS_LITERAL(RTYPE(tree))  &&
4128           ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0)
4129         {
4130           if (resultType == RESULT_TYPE_IFX)
4131             {
4132               /* the parent is an ifx: */
4133               /* if (unsigned value) */
4134               return tree->left;
4135             }
4136
4137           /* (unsigned value) ? 1 : 0 */
4138           tree->opval.op = '?';
4139           tree->right = newNode (':',
4140                                   newAst_VALUE (constVal ("1")),
4141                                   tree->right); /* val 0 */
4142           tree->right->lineno = tree->lineno;
4143           tree->right->left->lineno = tree->lineno;
4144           tree->decorated = 0;
4145           return decorateType (tree, resultType);
4146         }
4147
4148       /* 'ifx (op == 0)' -> 'ifx (!(op))' */
4149       if (IS_LITERAL(RTYPE(tree))  &&
4150           floatFromVal (valFromType (RETYPE (tree))) == 0 &&
4151           tree->opval.op == EQ_OP &&
4152           resultType == RESULT_TYPE_IFX)
4153         {
4154           tree->opval.op = '!';
4155           tree->right = NULL;
4156           tree->decorated = 0;
4157           return decorateType (tree, resultType);
4158         }
4159
4160       /* if they are both literal then */
4161       /* rewrite the tree */
4162       if (IS_LITERAL (RTYPE (tree)) &&
4163           IS_LITERAL (LTYPE (tree)))
4164         {
4165           tree->type = EX_VALUE;
4166           tree->opval.val = valCompare (valFromType (LETYPE (tree)),
4167                                         valFromType (RETYPE (tree)),
4168                                         tree->opval.op);
4169           tree->right = tree->left = NULL;
4170           TETYPE (tree) = getSpec (TTYPE (tree) =
4171                                    tree->opval.val->type);
4172           return tree;
4173         }
4174
4175       /* if one is 'signed char ' and the other one is 'unsigned char' */
4176       /* it's necessary to promote to int */
4177       if (IS_CHAR (RTYPE (tree)) && IS_CHAR (LTYPE (tree)) &&
4178           (IS_UNSIGNED (RTYPE (tree)) != IS_UNSIGNED (LTYPE (tree))))
4179         {
4180           /* Literals are 'optimized' to 'unsigned char'. Try to figure out,
4181              if it's possible to use a 'signed char' */
4182
4183               /* is left a 'unsigned char'? */
4184           if (IS_LITERAL (RTYPE (tree)) && IS_UNSIGNED (RTYPE (tree)) &&
4185               /* the value range of a 'unsigned char' is 0...255;
4186                  if the actual value is < 128 it can be changed to signed */
4187               (int) floatFromVal (valFromType (RETYPE (tree))) < 128)
4188             {
4189               /* now we've got 2 'signed char'! */
4190               SPEC_USIGN (RETYPE (tree)) = 0;
4191             }
4192                    /* same test for the left operand: */
4193           else if (IS_LITERAL (LTYPE (tree)) && IS_UNSIGNED (LTYPE (tree)) &&
4194               (int) floatFromVal (valFromType (LETYPE (tree))) < 128)
4195             {
4196               SPEC_USIGN (LETYPE (tree)) = 0;
4197             }
4198           else
4199             {
4200               werror (W_CMP_SU_CHAR);
4201               tree->left  = addCast (tree->left , RESULT_TYPE_INT, TRUE);
4202               tree->right = addCast (tree->right, RESULT_TYPE_INT, TRUE);
4203             }
4204         }
4205
4206       LRVAL (tree) = RRVAL (tree) = 1;
4207       TTYPE (tree) = TETYPE (tree) = newBoolLink ();
4208
4209       /* condition transformations */
4210       {
4211         unsigned transformedOp = 0;
4212
4213         switch (tree->opval.op)
4214           {
4215             case '<':             /* transform (a < b)  to !(a >= b)  */
4216               if (port->lt_nge)
4217                 transformedOp = GE_OP;
4218               break;
4219             case '>':             /* transform (a > b)  to !(a <= b)  */
4220               if (port->gt_nle)
4221                 transformedOp = LE_OP;
4222               break;
4223             case LE_OP:           /* transform (a <= b) to !(a > b)   */
4224               if (port->le_ngt)
4225                 transformedOp = '>';
4226               break;
4227             case GE_OP:           /* transform (a >= b) to !(a < b)   */
4228               if (port->ge_nlt)
4229                 transformedOp = '<';
4230               break;
4231             case NE_OP:           /* transform (a != b) to !(a == b)   */
4232               if (port->ne_neq)
4233                 transformedOp = EQ_OP;
4234               break;
4235             case EQ_OP:           /* transform (a == b) to !(a != b)   */
4236               if (port->eq_nne)
4237                 transformedOp = NE_OP;
4238               break;
4239             default:
4240               break;
4241           }
4242         if (transformedOp)
4243           {
4244             tree->opval.op = transformedOp;
4245             tree->decorated = 0;
4246             tree = newNode ('!', tree, NULL);
4247             tree->lineno = tree->left->lineno;
4248             return decorateType (tree, resultType);
4249           }
4250       }
4251
4252       return tree;
4253
4254       /*------------------------------------------------------------------*/
4255       /*----------------------------*/
4256       /*             sizeof         */
4257       /*----------------------------*/
4258     case SIZEOF:                /* evaluate wihout code generation */
4259       /* change the type to a integer */
4260       {
4261         int size = getSize (tree->right->ftype);
4262         SNPRINTF(buffer, sizeof(buffer), "%d", size);
4263         if (!size && !IS_VOID(tree->right->ftype))
4264           werrorfl (tree->filename, tree->lineno, E_SIZEOF_INCOMPLETE_TYPE);
4265       }
4266       tree->type = EX_VALUE;
4267       tree->opval.val = constVal (buffer);
4268       tree->right = tree->left = NULL;
4269       TETYPE (tree) = getSpec (TTYPE (tree) =
4270                                tree->opval.val->type);
4271       return tree;
4272
4273       /*------------------------------------------------------------------*/
4274       /*----------------------------*/
4275       /*             typeof         */
4276       /*----------------------------*/
4277     case TYPEOF:
4278         /* return typeof enum value */
4279         tree->type = EX_VALUE;
4280         {
4281             int typeofv = 0;
4282             if (IS_SPEC(tree->right->ftype)) {
4283                 switch (SPEC_NOUN(tree->right->ftype)) {
4284                 case V_INT:
4285                     if (SPEC_LONG(tree->right->ftype)) typeofv = TYPEOF_LONG;
4286                     else typeofv = TYPEOF_INT;
4287                     break;
4288                 case V_FLOAT:
4289                     typeofv = TYPEOF_FLOAT;
4290                     break;
4291                 case V_FIXED16X16:
4292                     typeofv = TYPEOF_FIXED16X16;
4293                     break;
4294                 case V_CHAR:
4295                     typeofv = TYPEOF_CHAR;
4296                     break;
4297                 case V_VOID:
4298                     typeofv = TYPEOF_VOID;
4299                     break;
4300                 case V_STRUCT:
4301                     typeofv = TYPEOF_STRUCT;
4302                     break;
4303                 case V_BITFIELD:
4304                     typeofv = TYPEOF_BITFIELD;
4305                     break;
4306                 case V_BIT:
4307                     typeofv = TYPEOF_BIT;
4308                     break;
4309                 case V_SBIT:
4310                     typeofv = TYPEOF_SBIT;
4311                     break;
4312                 default:
4313                     break;
4314                 }
4315             } else {
4316                 switch (DCL_TYPE(tree->right->ftype)) {
4317                 case POINTER:
4318                     typeofv = TYPEOF_POINTER;
4319                     break;
4320                 case FPOINTER:
4321                     typeofv = TYPEOF_FPOINTER;
4322                     break;
4323                 case CPOINTER:
4324                     typeofv = TYPEOF_CPOINTER;
4325                     break;
4326                 case GPOINTER:
4327                     typeofv = TYPEOF_GPOINTER;
4328                     break;
4329                 case PPOINTER:
4330                     typeofv = TYPEOF_PPOINTER;
4331                     break;
4332                 case IPOINTER:
4333                     typeofv = TYPEOF_IPOINTER;
4334                     break;
4335                 case ARRAY:
4336                     typeofv = TYPEOF_ARRAY;
4337                     break;
4338                 case FUNCTION:
4339                     typeofv = TYPEOF_FUNCTION;
4340                     break;
4341                 default:
4342                     break;
4343                 }
4344             }
4345             SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
4346             tree->opval.val = constVal (buffer);
4347             tree->right = tree->left = NULL;
4348             TETYPE (tree) = getSpec (TTYPE (tree) =
4349                                      tree->opval.val->type);
4350         }
4351         return tree;
4352       /*------------------------------------------------------------------*/
4353       /*----------------------------*/
4354       /* conditional operator  '?'  */
4355       /*----------------------------*/
4356     case '?':
4357       /* the type is value of the colon operator (on the right) */
4358       assert (IS_COLON_OP (tree->right));
4359       /* if already known then replace the tree : optimizer will do it
4360          but faster to do it here */
4361       if (IS_LITERAL (LTYPE (tree)))
4362         {
4363           if (((int) floatFromVal (valFromType (LETYPE (tree)))) != 0)
4364             return decorateType (tree->right->left, resultTypeProp);
4365           else
4366             return decorateType (tree->right->right, resultTypeProp);
4367         }
4368       else
4369         {
4370           tree->right = decorateType (tree->right, resultTypeProp);
4371           TTYPE (tree) = RTYPE (tree);
4372           TETYPE (tree) = getSpec (TTYPE (tree));
4373         }
4374       return tree;
4375
4376     case ':':
4377       /* if they don't match we have a problem */
4378       if ((compareType (LTYPE (tree), RTYPE (tree)) == 0) &&
4379           (compareType (RTYPE (tree), LTYPE (tree)) == 0))
4380         {
4381           werror (E_TYPE_MISMATCH, "conditional operator", " ");
4382           goto errorTreeReturn;
4383         }
4384
4385       TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
4386                                   resultType, tree->opval.op);
4387       TETYPE (tree) = getSpec (TTYPE (tree));
4388       return tree;
4389
4390
4391 #if 0 // assignment operators are converted by the parser
4392       /*------------------------------------------------------------------*/
4393       /*----------------------------*/
4394       /*    assignment operators    */
4395       /*----------------------------*/
4396     case MUL_ASSIGN:
4397     case DIV_ASSIGN:
4398       /* for these it must be both must be integral */
4399       if (!IS_ARITHMETIC (LTYPE (tree)) ||
4400           !IS_ARITHMETIC (RTYPE (tree)))
4401         {
4402           werror (E_OPS_INTEGRAL);
4403           goto errorTreeReturn;
4404         }
4405       RRVAL (tree) = 1;
4406       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4407
4408       if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
4409         werror (E_CODE_WRITE, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4410
4411       if (LRVAL (tree))
4412         {
4413           werror (E_LVALUE_REQUIRED, tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
4414           goto errorTreeReturn;
4415         }
4416       LLVAL (tree) = 1;
4417
4418       return tree;
4419
4420     case AND_ASSIGN:
4421     case OR_ASSIGN:
4422     case XOR_ASSIGN:
4423     case RIGHT_ASSIGN:
4424     case LEFT_ASSIGN:
4425       /* for these it must be both must be integral */
4426       if (!IS_INTEGRAL (LTYPE (tree)) ||
4427           !IS_INTEGRAL (RTYPE (tree)))
4428         {
4429           werror (E_OPS_INTEGRAL);
4430           goto errorTreeReturn;
4431         }
4432       RRVAL (tree) = 1;
4433       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
4434
4435       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4436         werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
4437
4438       if (LRVAL (tree))
4439         {
4440           werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<=");
4441           goto errorTreeReturn;
4442         }
4443       LLVAL (tree) = 1;
4444
4445       return tree;
4446
4447       /*------------------------------------------------------------------*/
4448       /*----------------------------*/
4449       /*    -= operator             */
4450       /*----------------------------*/
4451     case SUB_ASSIGN:
4452       if (!(IS_PTR (LTYPE (tree)) ||
4453             IS_ARITHMETIC (LTYPE (tree))))
4454         {
4455           werror (E_PLUS_INVALID, "-=");
4456           goto errorTreeReturn;
4457         }
4458
4459       if (!(IS_PTR (RTYPE (tree)) ||
4460             IS_ARITHMETIC (RTYPE (tree))))
4461         {
4462           werror (E_PLUS_INVALID, "-=");
4463           goto errorTreeReturn;
4464         }
4465       RRVAL (tree) = 1;
4466       TETYPE (tree) = getSpec (TTYPE (tree) =
4467                                computeType (LTYPE (tree),
4468                                             RTYPE (tree),
4469                                             RESULT_TYPE_NOPROM,
4470                                             tree->opval.op));
4471
4472       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4473         werror (E_CODE_WRITE, "-=");
4474
4475       if (LRVAL (tree))
4476         {
4477           werror (E_LVALUE_REQUIRED, "-=");
4478           goto errorTreeReturn;
4479         }
4480       LLVAL (tree) = 1;
4481
4482       return tree;
4483
4484       /*------------------------------------------------------------------*/
4485       /*----------------------------*/
4486       /*          += operator       */
4487       /*----------------------------*/
4488     case ADD_ASSIGN:
4489       /* this is not a unary operation */
4490       /* if both pointers then problem */
4491       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
4492         {
4493           werror (E_PTR_PLUS_PTR);
4494           goto errorTreeReturn;
4495         }
4496
4497       if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree)))
4498         {
4499           werror (E_PLUS_INVALID, "+=");
4500           goto errorTreeReturn;
4501         }
4502
4503       if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree)))
4504         {
4505           werror (E_PLUS_INVALID, "+=");
4506           goto errorTreeReturn;
4507         }
4508       RRVAL (tree) = 1;
4509       TETYPE (tree) = getSpec (TTYPE (tree) =
4510                                computeType (LTYPE (tree),
4511                                             RTYPE (tree),
4512                                             RESULT_TYPE_NOPROM,
4513                                             tree->opval.op));
4514
4515       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
4516         werror (E_CODE_WRITE, "+=");
4517
4518       if (LRVAL (tree))
4519         {
4520           werror (E_LVALUE_REQUIRED, "+=");
4521           goto errorTreeReturn;
4522         }
4523
4524       tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right), RESULT_TYPE_NONE);
4525       tree->opval.op = '=';
4526
4527       return tree;
4528 #endif
4529
4530       /*------------------------------------------------------------------*/
4531       /*----------------------------*/
4532       /*      straight assignemnt   */
4533       /*----------------------------*/
4534     case '=':
4535       /* cannot be an aggregate */
4536       if (IS_AGGREGATE (LTYPE (tree)))
4537         {
4538           werror (E_AGGR_ASSIGN);
4539           goto errorTreeReturn;
4540         }
4541
4542       /* they should either match or be castable */
4543       if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
4544         {
4545           werror (E_TYPE_MISMATCH, "assignment", " ");
4546           printFromToType(RTYPE(tree),LTYPE(tree));
4547         }
4548
4549       /* if the left side of the tree is of type void
4550          then report error */
4551       if (IS_VOID (LTYPE (tree)))
4552         {
4553           werror (E_CAST_ZERO);
4554           printFromToType(RTYPE(tree), LTYPE(tree));
4555         }
4556
4557       TETYPE (tree) = getSpec (TTYPE (tree) =
4558                                LTYPE (tree));
4559       RRVAL (tree) = 1;
4560       LLVAL (tree) = 1;
4561       if (!tree->initMode ) {
4562         if (IS_CONSTANT(LTYPE(tree)))
4563           werror (E_CODE_WRITE, "=");
4564       }
4565       if (LRVAL (tree))
4566         {
4567           werror (E_LVALUE_REQUIRED, "=");
4568           goto errorTreeReturn;
4569         }
4570
4571       return tree;
4572
4573       /*------------------------------------------------------------------*/
4574       /*----------------------------*/
4575       /*      comma operator        */
4576       /*----------------------------*/
4577     case ',':
4578       TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
4579       return tree;
4580
4581       /*------------------------------------------------------------------*/
4582       /*----------------------------*/
4583       /*       function call        */
4584       /*----------------------------*/
4585     case CALL:
4586
4587       /* undo any explicit pointer derefernce; PCALL will handle it instead */
4588       if (IS_FUNC (LTYPE (tree)) && tree->left->type == EX_OP)
4589         {
4590           if (tree->left->opval.op == '*' && !tree->left->right)
4591             tree->left = tree->left->left;
4592         }
4593
4594       /* require a function or pointer to function */
4595       if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
4596         {
4597           werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
4598           goto errorTreeReturn;
4599         }
4600
4601       /* if there are parms, make sure that
4602          parms are decorate / process / reverse only once */
4603       if (!tree->right ||
4604           !tree->right->decorated)
4605         {
4606           sym_link *functype;
4607           parmNumber = 1;
4608
4609           if (IS_FUNCPTR (LTYPE (tree)))
4610             {
4611               functype = LTYPE (tree)->next;
4612               processFuncPtrArgs (functype);
4613             }
4614           else
4615             functype = LTYPE (tree);
4616
4617           if (processParms (tree->left, FUNC_ARGS(functype),
4618                             &tree->right, &parmNumber, TRUE))
4619             {
4620               goto errorTreeReturn;
4621             }
4622
4623           if ((options.stackAuto || IFFUNC_ISREENT (functype)) &&
4624              !IFFUNC_ISBUILTIN(functype))
4625             {
4626               reverseParms (tree->right);
4627             }
4628
4629            TTYPE (tree) = functype->next;
4630            TETYPE (tree) = getSpec (TTYPE (tree));
4631         }
4632       return tree;
4633
4634       /*------------------------------------------------------------------*/
4635       /*----------------------------*/
4636       /*     return statement       */
4637       /*----------------------------*/
4638     case RETURN:
4639       if (!tree->right)
4640         goto voidcheck;
4641
4642       if (compareType (currFunc->type->next, RTYPE (tree)) == 0)
4643         {
4644           werrorfl (tree->filename, tree->lineno, W_RETURN_MISMATCH);
4645           printFromToType (RTYPE(tree), currFunc->type->next);
4646           goto errorTreeReturn;
4647         }
4648
4649       if (IS_VOID (currFunc->type->next)
4650           && tree->right &&
4651           !IS_VOID (RTYPE (tree)))
4652         {
4653           werrorfl (tree->filename, tree->lineno, E_FUNC_VOID);
4654           goto errorTreeReturn;
4655         }
4656
4657       /* if there is going to be a casting required then add it */
4658       if (compareType (currFunc->type->next, RTYPE (tree)) < 0)
4659         {
4660           tree->right =
4661             decorateType (newNode (CAST,
4662                           newAst_LINK (copyLinkChain (currFunc->type->next)),
4663                                         tree->right),
4664                           RESULT_TYPE_NONE);
4665         }
4666
4667       RRVAL (tree) = 1;
4668       return tree;
4669
4670     voidcheck:
4671
4672       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
4673         {
4674           werror (W_VOID_FUNC, currFunc->name);
4675           goto errorTreeReturn;
4676         }
4677
4678       TTYPE (tree) = TETYPE (tree) = NULL;
4679       return tree;
4680
4681       /*------------------------------------------------------------------*/
4682       /*----------------------------*/
4683       /*     switch statement       */
4684       /*----------------------------*/
4685     case SWITCH:
4686       /* the switch value must be an integer */
4687       if (!IS_INTEGRAL (LTYPE (tree)))
4688         {
4689           werrorfl (tree->filename, tree->lineno, E_SWITCH_NON_INTEGER);
4690           goto errorTreeReturn;
4691         }
4692       LRVAL (tree) = 1;
4693       TTYPE (tree) = TETYPE (tree) = NULL;
4694       return tree;
4695
4696       /*------------------------------------------------------------------*/
4697       /*----------------------------*/
4698       /* ifx Statement              */
4699       /*----------------------------*/
4700     case IFX:
4701       tree->left = backPatchLabels (tree->left,
4702                                     tree->trueLabel,
4703                                     tree->falseLabel);
4704       TTYPE (tree) = TETYPE (tree) = NULL;
4705       return tree;
4706
4707       /*------------------------------------------------------------------*/
4708       /*----------------------------*/
4709       /* for Statement              */
4710       /*----------------------------*/
4711     case FOR:
4712
4713       AST_FOR (tree, initExpr) = decorateType (
4714                   resolveSymbols (AST_FOR (tree, initExpr)), RESULT_TYPE_NONE);
4715       AST_FOR (tree, condExpr) = decorateType (
4716                   resolveSymbols (AST_FOR (tree, condExpr)), RESULT_TYPE_NONE);
4717       AST_FOR (tree, loopExpr) = decorateType (
4718                   resolveSymbols (AST_FOR (tree, loopExpr)), RESULT_TYPE_NONE);
4719
4720       /* if the for loop is reversible then
4721          reverse it otherwise do what we normally
4722          do */
4723       {
4724         symbol *sym;
4725         ast *init, *end;
4726
4727         if (isLoopReversible (tree, &sym, &init, &end))
4728           return reverseLoop (tree, sym, init, end);
4729         else
4730           return decorateType (createFor (AST_FOR (tree, trueLabel),
4731                                           AST_FOR (tree, continueLabel),
4732                                           AST_FOR (tree, falseLabel),
4733                                           AST_FOR (tree, condLabel),
4734                                           AST_FOR (tree, initExpr),
4735                                           AST_FOR (tree, condExpr),
4736                                           AST_FOR (tree, loopExpr),
4737                                           tree->left), RESULT_TYPE_NONE);
4738       }
4739     case PARAM:
4740       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
4741               "node PARAM shouldn't be processed here");
4742               /* but in processParams() */
4743       return tree;
4744     default:
4745       TTYPE (tree) = TETYPE (tree) = NULL;
4746       return tree;
4747     }
4748
4749   /* some error found this tree will be killed */
4750 errorTreeReturn:
4751   TTYPE (tree) = TETYPE (tree) = newCharLink ();
4752   tree->opval.op = NULLOP;
4753   tree->isError = 1;
4754
4755   return tree;
4756 }
4757
4758 /*-----------------------------------------------------------------*/
4759 /* sizeofOp - processes size of operation                          */
4760 /*-----------------------------------------------------------------*/
4761 value *
4762 sizeofOp (sym_link * type)
4763 {
4764   char buff[10];
4765   int size;
4766
4767   /* make sure the type is complete and sane */
4768   checkTypeSanity(type, "(sizeof)");
4769
4770   /* get the size and convert it to character  */
4771   SNPRINTF (buff, sizeof(buff), "%d", size = getSize (type));
4772   if (!size && !IS_VOID(type))
4773     werror (E_SIZEOF_INCOMPLETE_TYPE);
4774
4775   /* now convert into value  */
4776   return constVal (buff);
4777 }
4778
4779
4780 #define IS_AND(ex) (ex->type == EX_OP && ex->opval.op == AND_OP )
4781 #define IS_OR(ex)  (ex->type == EX_OP && ex->opval.op == OR_OP )
4782 #define IS_NOT(ex) (ex->type == EX_OP && ex->opval.op == '!' )
4783 #define IS_ANDORNOT(ex) (IS_AND(ex) || IS_OR(ex) || IS_NOT(ex))
4784 #define IS_IFX(ex) (ex->type == EX_OP && ex->opval.op == IFX )
4785 #define IS_LT(ex)  (ex->type == EX_OP && ex->opval.op == '<' )
4786 #define IS_GT(ex)  (ex->type == EX_OP && ex->opval.op == '>')
4787
4788 /*-----------------------------------------------------------------*/
4789 /* backPatchLabels - change and or not operators to flow control    */
4790 /*-----------------------------------------------------------------*/
4791 static ast *
4792 backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
4793 {
4794
4795   if (!tree)
4796     return NULL;
4797
4798   /* while-loops insert a label between the IFX and the condition,
4799      therefore look behind the label too */
4800   if (tree->opval.op == LABEL &&
4801       tree->right &&
4802       IS_ANDORNOT (tree->right))
4803     {
4804       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4805       return tree;
4806     }
4807
4808   if (!(IS_ANDORNOT (tree)))
4809     return tree;
4810
4811   /* if this an and */
4812   if (IS_AND (tree))
4813     {
4814       static int localLbl = 0;
4815       symbol *localLabel;
4816
4817       SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
4818       localLabel = newSymbol (buffer, NestLevel);
4819
4820       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
4821
4822       /* if left is already a IFX then just change the if true label in that */
4823       if (!IS_IFX (tree->left))
4824         tree->left = newIfxNode (tree->left, localLabel, falseLabel);
4825
4826       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4827       /* right is a IFX then just join */
4828       if (IS_IFX (tree->right))
4829         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4830
4831       tree->right = createLabel (localLabel, tree->right);
4832       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4833
4834       return newNode (NULLOP, tree->left, tree->right);
4835     }
4836
4837   /* if this is an or operation */
4838   if (IS_OR (tree))
4839     {
4840       static int localLbl = 0;
4841       symbol *localLabel;
4842
4843       SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
4844       localLabel = newSymbol (buffer, NestLevel);
4845
4846       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
4847
4848       /* if left is already a IFX then just change the if true label in that */
4849       if (!IS_IFX (tree->left))
4850         tree->left = newIfxNode (tree->left, trueLabel, localLabel);
4851
4852       tree->right = backPatchLabels (tree->right, trueLabel, falseLabel);
4853       /* right is a IFX then just join */
4854       if (IS_IFX (tree->right))
4855         return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right));
4856
4857       tree->right = createLabel (localLabel, tree->right);
4858       tree->right = newIfxNode (tree->right, trueLabel, falseLabel);
4859
4860       return newNode (NULLOP, tree->left, tree->right);
4861     }
4862
4863   /* change not */
4864   if (IS_NOT (tree))
4865     {
4866       /* call with exchanged labels */
4867       tree->left = backPatchLabels (tree->left, falseLabel, trueLabel);
4868
4869       /* if left isn't already a IFX */
4870       if (!IS_IFX (tree->left))
4871         {
4872           tree->left = newNode (IFX, tree->left, NULL);
4873           tree->left->trueLabel = falseLabel;
4874           tree->left->falseLabel = trueLabel;
4875         }
4876       return tree->left;
4877      }
4878
4879   if (IS_IFX (tree))
4880     {
4881       tree->trueLabel = trueLabel;
4882       tree->falseLabel = falseLabel;
4883     }
4884
4885   return tree;
4886 }
4887
4888
4889 /*-----------------------------------------------------------------*/
4890 /* createBlock - create expression tree for block                  */
4891 /*-----------------------------------------------------------------*/
4892 ast *
4893 createBlock (symbol * decl, ast * body)
4894 {
4895   ast *ex;
4896
4897   /* if the block has nothing */
4898   if (!body && !decl)
4899     return NULL;
4900
4901   ex = newNode (BLOCK, NULL, body);
4902   ex->values.sym = decl;
4903
4904   ex->level++;
4905   ex->lineno = 0;
4906   return ex;
4907 }
4908
4909 /*-----------------------------------------------------------------*/
4910 /* createLabel - creates the expression tree for labels            */
4911 /*-----------------------------------------------------------------*/
4912 ast *
4913 createLabel (symbol * label, ast * stmnt)
4914 {
4915   symbol *csym;
4916   char name[SDCC_NAME_MAX + 1];
4917   ast *rValue;
4918
4919   /* must create fresh symbol if the symbol name  */
4920   /* exists in the symbol table, since there can  */
4921   /* be a variable with the same name as the labl */
4922   if ((csym = findSym (SymbolTab, NULL, label->name)) &&
4923       (csym->level == label->level))
4924     label = newSymbol (label->name, label->level);
4925
4926   /* change the name before putting it in add _ */
4927   SNPRINTF(name, sizeof(name), "%s", label->name);
4928
4929   /* put the label in the LabelSymbol table    */
4930   /* but first check if a label of the same    */
4931   /* name exists                               */
4932   if ((csym = findSym (LabelTab, NULL, name)))
4933     werror (E_DUPLICATE_LABEL, label->name);
4934   else
4935     addSym (LabelTab, label, name, label->level, 0, 0);
4936
4937   label->isitmp = 1;
4938   label->islbl = 1;
4939   label->key = labelKey++;
4940   rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt);
4941   rValue->lineno = 0;
4942
4943   return rValue;
4944 }
4945
4946 /*-----------------------------------------------------------------*/
4947 /* createCase - generates the parsetree for a case statement       */
4948 /*-----------------------------------------------------------------*/
4949 ast *
4950 createCase (ast * swStat, ast * caseVal, ast * stmnt)
4951 {
4952   char caseLbl[SDCC_NAME_MAX + 1];
4953   ast *rexpr;
4954   value *val;
4955
4956   /* if the switch statement does not exist */
4957   /* then case is out of context            */
4958   if (!swStat)
4959     {
4960       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONTEXT);
4961       return NULL;
4962     }
4963
4964   caseVal = decorateType (resolveSymbols (caseVal), RESULT_TYPE_NONE);
4965   /* if not a constant then error  */
4966   if (!IS_LITERAL (caseVal->ftype))
4967     {
4968       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_CONSTANT);
4969       return NULL;
4970     }
4971
4972   /* if not a integer than error */
4973   if (!IS_INTEGRAL (caseVal->ftype))
4974     {
4975       werrorfl (caseVal->filename, caseVal->lineno, E_CASE_NON_INTEGER);
4976       return NULL;
4977     }
4978
4979   /* find the end of the switch values chain   */
4980   if (!(val = swStat->values.switchVals.swVals))
4981     swStat->values.switchVals.swVals = caseVal->opval.val;
4982   else
4983     {
4984       /* also order the cases according to value */
4985       value *pval = NULL;
4986       int cVal = (int) floatFromVal (caseVal->opval.val);
4987       while (val && (int) floatFromVal (val) < cVal)
4988         {
4989           pval = val;
4990           val = val->next;
4991         }
4992
4993       /* if we reached the end then */
4994       if (!val)
4995         {
4996           pval->next = caseVal->opval.val;
4997         }
4998       else if ((int) floatFromVal (val) == cVal)
4999         {
5000           werrorfl (caseVal->filename, caseVal->lineno, E_DUPLICATE_LABEL,
5001                     "case");
5002           return NULL;
5003         }
5004       else
5005         {
5006           /* we found a value greater than */
5007           /* the current value we must add this */
5008           /* before the value */
5009           caseVal->opval.val->next = val;
5010
5011           /* if this was the first in chain */
5012           if (swStat->values.switchVals.swVals == val)
5013             swStat->values.switchVals.swVals =
5014               caseVal->opval.val;
5015           else
5016             pval->next = caseVal->opval.val;
5017         }
5018
5019     }
5020
5021   /* create the case label   */
5022   SNPRINTF(caseLbl, sizeof(caseLbl),
5023            "_case_%d_%d",
5024            swStat->values.switchVals.swNum,
5025            (int) floatFromVal (caseVal->opval.val));
5026
5027   rexpr = createLabel (newSymbol (caseLbl, 0), stmnt);
5028   rexpr->lineno = 0;
5029   return rexpr;
5030 }
5031
5032 /*-----------------------------------------------------------------*/
5033 /* createDefault - creates the parse tree for the default statement */
5034 /*-----------------------------------------------------------------*/
5035 ast *
5036 createDefault (ast * swStat, ast * defaultVal, ast * stmnt)
5037 {
5038   char defLbl[SDCC_NAME_MAX + 1];
5039
5040   /* if the switch statement does not exist */
5041   /* then case is out of context            */
5042   if (!swStat)
5043     {
5044       werrorfl (defaultVal->filename, defaultVal->lineno, E_CASE_CONTEXT);
5045       return NULL;
5046     }
5047
5048   if (swStat->values.switchVals.swDefault)
5049     {
5050       werrorfl (defaultVal->filename, defaultVal->lineno, E_DUPLICATE_LABEL,
5051                 "default");
5052       return NULL;
5053     }
5054
5055   /* turn on the default flag   */
5056   swStat->values.switchVals.swDefault = 1;
5057
5058   /* create the label  */
5059   SNPRINTF (defLbl, sizeof(defLbl),
5060             "_default_%d", swStat->values.switchVals.swNum);
5061   return createLabel (newSymbol (defLbl, 0), stmnt);
5062 }
5063
5064 /*-----------------------------------------------------------------*/
5065 /* createIf - creates the parsetree for the if statement           */
5066 /*-----------------------------------------------------------------*/
5067 ast *
5068 createIf (ast * condAst, ast * ifBody, ast * elseBody)
5069 {
5070   static int Lblnum = 0;
5071   ast *ifTree;
5072   symbol *ifTrue, *ifFalse, *ifEnd;
5073
5074   /* if neither exists */
5075   if (!elseBody && !ifBody) {
5076     // if there are no side effects (i++, j() etc)
5077     if (!hasSEFcalls(condAst)) {
5078       return condAst;
5079     }
5080   }
5081
5082   /* create the labels */
5083   SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
5084   ifFalse = newSymbol (buffer, NestLevel);
5085   /* if no else body then end == false */
5086   if (!elseBody)
5087     ifEnd = ifFalse;
5088   else
5089     {
5090       SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
5091       ifEnd = newSymbol (buffer, NestLevel);
5092     }
5093
5094   SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
5095   ifTrue = newSymbol (buffer, NestLevel);
5096
5097   Lblnum++;
5098
5099   /* attach the ifTrue label to the top of it body */
5100   ifBody = createLabel (ifTrue, ifBody);
5101   /* attach a goto end to the ifBody if else is present */
5102   if (elseBody)
5103     {
5104       ifBody = newNode (NULLOP, ifBody,
5105                         newNode (GOTO,
5106                                  newAst_VALUE (symbolVal (ifEnd)),
5107                                  NULL));
5108       /* put the elseLabel on the else body */
5109       elseBody = createLabel (ifFalse, elseBody);
5110       /* out the end at the end of the body */
5111       elseBody = newNode (NULLOP,
5112                           elseBody,
5113                           createLabel (ifEnd, NULL));
5114     }
5115   else
5116     {
5117       ifBody = newNode (NULLOP, ifBody,
5118                         createLabel (ifFalse, NULL));
5119     }
5120   condAst = backPatchLabels (condAst, ifTrue, ifFalse);
5121   if (IS_IFX (condAst))
5122     ifTree = condAst;
5123   else
5124     ifTree = newIfxNode (condAst, ifTrue, ifFalse);
5125
5126   return newNode (NULLOP, ifTree,
5127                   newNode (NULLOP, ifBody, elseBody));
5128
5129 }
5130
5131 /*-----------------------------------------------------------------*/
5132 /* createDo - creates parse tree for do                            */
5133 /*        _dobody_n:                                               */
5134 /*            statements                                           */
5135 /*        _docontinue_n:                                           */
5136 /*            condition_expression +-> trueLabel -> _dobody_n      */
5137 /*                                 |                               */
5138 /*                                 +-> falseLabel-> _dobreak_n     */
5139 /*        _dobreak_n:                                              */
5140 /*-----------------------------------------------------------------*/
5141 ast *
5142 createDo (symbol * trueLabel, symbol * continueLabel,
5143           symbol * falseLabel, ast * condAst, ast * doBody)
5144 {
5145   ast *doTree;
5146
5147
5148   /* if the body does not exist then it is simple */
5149   if (!doBody)
5150     {
5151       condAst = backPatchLabels (condAst, continueLabel, NULL);
5152       doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst)
5153                 : newNode (IFX, createLabel (continueLabel, condAst), NULL));
5154       doTree->trueLabel = continueLabel;
5155       doTree->falseLabel = NULL;
5156       return doTree;
5157     }
5158
5159   /* otherwise we have a body */
5160   condAst = backPatchLabels (condAst, trueLabel, falseLabel);
5161
5162   /* attach the body label to the top */
5163   doBody = createLabel (trueLabel, doBody);
5164   /* attach the continue label to end of body */
5165   doBody = newNode (NULLOP, doBody,
5166                     createLabel (continueLabel, NULL));
5167
5168   /* now put the break label at the end */
5169   if (IS_IFX (condAst))
5170     doTree = condAst;
5171   else
5172     doTree = newIfxNode (condAst, trueLabel, falseLabel);
5173
5174   doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL));
5175
5176   /* putting it together */
5177   return newNode (NULLOP, doBody, doTree);
5178 }
5179
5180 /*-----------------------------------------------------------------*/
5181 /* createFor - creates parse tree for 'for' statement              */
5182 /*        initExpr                                                 */
5183 /*   _forcond_n:                                                   */
5184 /*        condExpr  +-> trueLabel -> _forbody_n                    */
5185 /*                  |                                              */
5186 /*                  +-> falseLabel-> _forbreak_n                   */
5187 /*   _forbody_n:                                                   */
5188 /*        statements                                               */
5189 /*   _forcontinue_n:                                               */
5190 /*        loopExpr                                                 */
5191 /*        goto _forcond_n ;                                        */
5192 /*   _forbreak_n:                                                  */
5193 /*-----------------------------------------------------------------*/
5194 ast *
5195 createFor (symbol * trueLabel, symbol * continueLabel,
5196            symbol * falseLabel, symbol * condLabel,
5197            ast * initExpr, ast * condExpr, ast * loopExpr,
5198            ast * forBody)
5199 {
5200   ast *forTree;
5201
5202   /* if loopexpression not present then we can generate it */
5203   /* the same way as a while */
5204   if (!loopExpr)
5205     return newNode (NULLOP, initExpr,
5206                     createWhile (trueLabel, continueLabel,
5207                                  falseLabel, condExpr, forBody));
5208   /* vanilla for statement */
5209   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5210
5211   if (condExpr && !IS_IFX (condExpr))
5212     condExpr = newIfxNode (condExpr, trueLabel, falseLabel);
5213
5214
5215   /* attach condition label to condition */
5216   condExpr = createLabel (condLabel, condExpr);
5217
5218   /* attach body label to body */
5219   forBody = createLabel (trueLabel, forBody);
5220
5221   /* attach continue to forLoop expression & attach */
5222   /* goto the forcond @ and of loopExpression       */
5223   loopExpr = createLabel (continueLabel,
5224                           newNode (NULLOP,
5225                                    loopExpr,
5226                                    newNode (GOTO,
5227                                        newAst_VALUE (symbolVal (condLabel)),
5228                                             NULL)));
5229   /* now start putting them together */
5230   forTree = newNode (NULLOP, initExpr, condExpr);
5231   forTree = newNode (NULLOP, forTree, forBody);
5232   forTree = newNode (NULLOP, forTree, loopExpr);
5233   /* finally add the break label */
5234   forTree = newNode (NULLOP, forTree,
5235                      createLabel (falseLabel, NULL));
5236   return forTree;
5237 }
5238
5239 /*-----------------------------------------------------------------*/
5240 /* createWhile - creates parse tree for while statement            */
5241 /*               the while statement will be created as follows    */
5242 /*                                                                 */
5243 /*      _while_continue_n:                                         */
5244 /*            condition_expression +-> trueLabel -> _while_boby_n  */
5245 /*                                 |                               */
5246 /*                                 +-> falseLabel -> _while_break_n */
5247 /*      _while_body_n:                                             */
5248 /*            statements                                           */
5249 /*            goto _while_continue_n                               */
5250 /*      _while_break_n:                                            */
5251 /*-----------------------------------------------------------------*/
5252 ast *
5253 createWhile (symbol * trueLabel, symbol * continueLabel,
5254              symbol * falseLabel, ast * condExpr, ast * whileBody)
5255 {
5256   ast *whileTree;
5257
5258   /* put the continue label */
5259   condExpr = backPatchLabels (condExpr, trueLabel, falseLabel);
5260   condExpr = createLabel (continueLabel, condExpr);
5261   condExpr->lineno = 0;
5262
5263   /* put the body label in front of the body */
5264   whileBody = createLabel (trueLabel, whileBody);
5265   whileBody->lineno = 0;
5266   /* put a jump to continue at the end of the body */
5267   /* and put break label at the end of the body */
5268   whileBody = newNode (NULLOP,
5269                        whileBody,
5270                        newNode (GOTO,
5271                                 newAst_VALUE (symbolVal (continueLabel)),
5272                                 createLabel (falseLabel, NULL)));
5273
5274   /* put it all together */
5275   if (IS_IFX (condExpr))
5276     whileTree = condExpr;
5277   else
5278     {
5279       whileTree = newNode (IFX, condExpr, NULL);
5280       /* put the true & false labels in place */
5281       whileTree->trueLabel = trueLabel;
5282       whileTree->falseLabel = falseLabel;
5283     }
5284
5285   return newNode (NULLOP, whileTree, whileBody);
5286 }
5287
5288 /*-----------------------------------------------------------------*/
5289 /* isShiftRightLitVal _BitAndLitVal - helper function              */
5290 /*-----------------------------------------------------------------*/
5291 static ast *
5292 isShiftRightLitVal_BitAndLitVal (ast * tree)
5293 {
5294   /* if this is not a bit and */
5295   if (!IS_BITAND (tree))
5296     return NULL;
5297
5298   /* will look for tree of the form
5299      ( expr >> litval2) & litval1 */
5300   if (!IS_AST_LIT_VALUE (tree->right))
5301     return NULL;
5302
5303   if (!IS_RIGHT_OP (tree->left))
5304     return NULL;
5305
5306   if (!IS_AST_LIT_VALUE (tree->left->right))
5307     return NULL;
5308
5309   return tree->left->left;
5310 }
5311
5312 /*-----------------------------------------------------------------*/
5313 /* isBitAndPowOf2 - helper function                                */
5314 /*-----------------------------------------------------------------*/
5315 static int
5316 isBitAndPow2 (ast * tree)
5317 {
5318   /* if this is not a bit and */
5319   if (!IS_BITAND (tree))
5320     return -1;
5321
5322   /* will look for tree of the form
5323      ( expr & (1 << litval) */
5324   if (!IS_AST_LIT_VALUE (tree->right))
5325     return -1;
5326
5327   return powof2 ((TYPE_TARGET_ULONG)AST_LIT_VALUE (tree->right));
5328 }
5329
5330 /*-----------------------------------------------------------------*/
5331 /* optimizeGetHbit - get highest order bit of the expression       */
5332 /*-----------------------------------------------------------------*/
5333 ast *
5334 optimizeGetHbit (ast * tree, RESULT_TYPE resultType)
5335 {
5336   int i, j;
5337   ast * expr;
5338
5339   expr = isShiftRightLitVal_BitAndLitVal(tree);
5340   if (expr)
5341     {
5342       if ((AST_LIT_VALUE (tree->right) != 1) ||
5343           ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
5344           (j = (getSize (TTYPE (expr)) * 8 - 1))))
5345         expr = NULL;
5346     }
5347   if (!expr && (resultType == RESULT_TYPE_BIT))
5348     {
5349       expr = tree->left;
5350       if (isBitAndPow2 (tree) != (signed)getSize (TTYPE (expr)) * 8 - 1)
5351         expr = NULL;
5352     }
5353   if (!expr)
5354     return tree;
5355
5356   /* make sure the port supports GETHBIT */
5357   if (port->hasExtBitOp
5358       && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (expr))))
5359     return tree;
5360
5361   return decorateType (newNode (GETHBIT, expr, NULL), RESULT_TYPE_NONE);
5362 }
5363
5364 /*-----------------------------------------------------------------*/
5365 /* optimizeGetAbit - get a single bit of the expression            */
5366 /*-----------------------------------------------------------------*/
5367 ast *
5368 optimizeGetAbit (ast * tree, RESULT_TYPE resultType)
5369 {
5370   ast * expr;
5371   ast * count = NULL;
5372
5373   expr = isShiftRightLitVal_BitAndLitVal(tree);
5374   if (expr)
5375     {
5376   if (AST_LIT_VALUE (tree->right) != 1)
5377         expr = NULL;
5378       count = tree->left->right;
5379     }
5380   if (!expr && (resultType == RESULT_TYPE_BIT))
5381     {
5382       int p2 = isBitAndPow2 (tree);
5383       if (p2 >= 0)
5384         {
5385           expr = tree->left;
5386           count = newAst_VALUE (valueFromLit (p2));
5387         }
5388     }
5389   if (!expr)
5390     return tree;
5391
5392   /* make sure the port supports GETABIT */
5393   if (port->hasExtBitOp
5394       && !port->hasExtBitOp(GETABIT, getSize (TTYPE (expr))))
5395     return tree;
5396
5397   return decorateType (newNode (GETABIT, expr, count), RESULT_TYPE_NONE);
5398
5399 }
5400
5401 /*-----------------------------------------------------------------*/
5402 /* optimizeGetByte - get a byte of the expression                  */
5403 /*-----------------------------------------------------------------*/
5404 ast *
5405 optimizeGetByte (ast * tree, RESULT_TYPE resultType)
5406 {
5407   unsigned int i = 0;
5408   ast * expr;
5409   ast * count = NULL;
5410
5411   expr = isShiftRightLitVal_BitAndLitVal(tree);
5412   if (expr)
5413     {
5414       i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5415       count = tree->left->right;
5416       if (AST_LIT_VALUE (tree->right) != 0xFF)
5417         expr = NULL;
5418     }
5419   if (!expr && resultType == RESULT_TYPE_CHAR)
5420     {
5421       /* if this is a right shift over a multiple of 8 */
5422       if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5423         {
5424           i = (unsigned int) AST_LIT_VALUE (tree->right);
5425           count = tree->right;
5426             expr = tree->left;
5427         }
5428     }
5429   if (!expr || (i == 0) || (i % 8) || (i >= getSize (TTYPE (expr)) * 8))
5430     return tree;
5431
5432   /* make sure the port supports GETBYTE */
5433   if (port->hasExtBitOp
5434       && !port->hasExtBitOp(GETBYTE, getSize (TTYPE (expr))))
5435     return tree;
5436
5437   return decorateType (newNode (GETBYTE, expr, count), RESULT_TYPE_NONE);
5438 }
5439
5440 /*-----------------------------------------------------------------*/
5441 /* optimizeGetWord - get two bytes of the expression               */
5442 /*-----------------------------------------------------------------*/
5443 ast *
5444 optimizeGetWord (ast * tree, RESULT_TYPE resultType)
5445 {
5446   unsigned int i = 0;
5447   ast * expr;
5448   ast * count = NULL;
5449
5450   expr = isShiftRightLitVal_BitAndLitVal(tree);
5451   if (expr)
5452     {
5453       i = (unsigned int) AST_LIT_VALUE (tree->left->right);
5454       count = tree->left->right;
5455       if (AST_LIT_VALUE (tree->right) != 0xFFFF)
5456         expr = NULL;
5457     }
5458   if (!expr && resultType == RESULT_TYPE_INT)
5459     {
5460       /* if this is a right shift over a multiple of 8 */
5461       if (IS_RIGHT_OP (tree) && IS_AST_LIT_VALUE (tree->right))
5462         {
5463           i = (unsigned int) AST_LIT_VALUE (tree->right);
5464           count = tree->right;
5465             expr = tree->left;
5466         }
5467     }
5468   if (!expr || (i == 0) || (i % 8) || (i >= (getSize (TTYPE (expr))-1) * 8))
5469     return tree;
5470
5471   /* make sure the port supports GETWORD */
5472   if (port->hasExtBitOp
5473       && !port->hasExtBitOp(GETWORD, getSize (TTYPE (expr))))
5474     return tree;
5475
5476   return decorateType (newNode (GETWORD, expr, count), RESULT_TYPE_NONE);
5477 }
5478
5479 /*-----------------------------------------------------------------*/
5480 /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry     */
5481 /*-----------------------------------------------------------------*/
5482 ast *
5483 optimizeRRCRLC (ast * root)
5484 {
5485   /* will look for trees of the form
5486      (?expr << 1) | (?expr >> 7) or
5487      (?expr >> 7) | (?expr << 1) will make that
5488      into a RLC : operation ..
5489      Will also look for
5490      (?expr >> 1) | (?expr << 7) or
5491      (?expr << 7) | (?expr >> 1) will make that
5492      into a RRC operation
5493      note : by 7 I mean (number of bits required to hold the
5494      variable -1 ) */
5495   /* if the root operation is not a | operation then not */
5496   if (!IS_BITOR (root))
5497     return root;
5498
5499   /* I have to think of a better way to match patterns this sucks */
5500   /* that aside let's start looking for the first case : I use a
5501      negative check a lot to improve the efficiency */
5502   /* (?expr << 1) | (?expr >> 7) */
5503   if (IS_LEFT_OP (root->left) &&
5504       IS_RIGHT_OP (root->right))
5505     {
5506
5507       if (!SPEC_USIGN (TETYPE (root->left->left)))
5508         return root;
5509
5510       if (!IS_AST_LIT_VALUE (root->left->right) ||
5511           !IS_AST_LIT_VALUE (root->right->right))
5512         goto tryNext0;
5513
5514       /* make sure it is the same expression */
5515       if (!isAstEqual (root->left->left,
5516                        root->right->left))
5517         goto tryNext0;
5518
5519       if (AST_LIT_VALUE (root->left->right) != 1)
5520         goto tryNext0;
5521
5522       if (AST_LIT_VALUE (root->right->right) !=
5523           (getSize (TTYPE (root->left->left)) * 8 - 1))
5524         goto tryNext0;
5525
5526       /* make sure the port supports RLC */
5527       if (port->hasExtBitOp
5528           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5529         return root;
5530
5531       /* whew got the first case : create the AST */
5532       return newNode (RLC, root->left->left, NULL);
5533     }
5534
5535 tryNext0:
5536   /* check for second case */
5537   /* (?expr >> 7) | (?expr << 1) */
5538   if (IS_LEFT_OP (root->right) &&
5539       IS_RIGHT_OP (root->left))
5540     {
5541
5542       if (!SPEC_USIGN (TETYPE (root->left->left)))
5543         return root;
5544
5545       if (!IS_AST_LIT_VALUE (root->left->right) ||
5546           !IS_AST_LIT_VALUE (root->right->right))
5547         goto tryNext1;
5548
5549       /* make sure it is the same symbol */
5550       if (!isAstEqual (root->left->left,
5551                        root->right->left))
5552         goto tryNext1;
5553
5554       if (AST_LIT_VALUE (root->right->right) != 1)
5555         goto tryNext1;
5556
5557       if (AST_LIT_VALUE (root->left->right) !=
5558           (getSize (TTYPE (root->left->left)) * 8 - 1))
5559         goto tryNext1;
5560
5561       /* make sure the port supports RLC */
5562       if (port->hasExtBitOp
5563           && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
5564         return root;
5565
5566       /* whew got the first case : create the AST */
5567       return newNode (RLC, root->left->left, NULL);
5568
5569     }
5570
5571 tryNext1:
5572   /* third case for RRC */
5573   /*  (?symbol >> 1) | (?symbol << 7) */
5574   if (IS_LEFT_OP (root->right) &&
5575       IS_RIGHT_OP (root->left))
5576     {
5577
5578       if (!SPEC_USIGN (TETYPE (root->left->left)))
5579         return root;
5580
5581       if (!IS_AST_LIT_VALUE (root->left->right) ||
5582           !IS_AST_LIT_VALUE (root->right->right))
5583         goto tryNext2;
5584
5585       /* make sure it is the same symbol */
5586       if (!isAstEqual (root->left->left,
5587                        root->right->left))
5588         goto tryNext2;
5589
5590       if (AST_LIT_VALUE (root->left->right) != 1)
5591         goto tryNext2;
5592
5593       if (AST_LIT_VALUE (root->right->right) !=
5594           (getSize (TTYPE (root->left->left)) * 8 - 1))
5595         goto tryNext2;
5596
5597       /* make sure the port supports RRC */
5598       if (port->hasExtBitOp
5599           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5600         return root;
5601
5602       /* whew got the first case : create the AST */
5603       return newNode (RRC, root->left->left, NULL);
5604
5605     }
5606 tryNext2:
5607   /* fourth and last case for now */
5608   /* (?symbol << 7) | (?symbol >> 1) */
5609   if (IS_RIGHT_OP (root->right) &&
5610       IS_LEFT_OP (root->left))
5611     {
5612
5613       if (!SPEC_USIGN (TETYPE (root->left->left)))
5614         return root;
5615
5616       if (!IS_AST_LIT_VALUE (root->left->right) ||
5617           !IS_AST_LIT_VALUE (root->right->right))
5618         return root;
5619
5620       /* make sure it is the same symbol */
5621       if (!isAstEqual (root->left->left,
5622                        root->right->left))
5623         return root;
5624
5625       if (AST_LIT_VALUE (root->right->right) != 1)
5626         return root;
5627
5628       if (AST_LIT_VALUE (root->left->right) !=
5629           (getSize (TTYPE (root->left->left)) * 8 - 1))
5630         return root;
5631
5632       /* make sure the port supports RRC */
5633       if (port->hasExtBitOp
5634           && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
5635         return root;
5636
5637       /* whew got the first case : create the AST */
5638       return newNode (RRC, root->left->left, NULL);
5639
5640     }
5641
5642   /* not found return root */
5643   return root;
5644 }
5645
5646 /*-----------------------------------------------------------------*/
5647 /* optimizeSWAP :- optimize for nibble/byte/word swaps             */
5648 /*-----------------------------------------------------------------*/
5649 ast *
5650 optimizeSWAP (ast * root)
5651 {
5652   /* will look for trees of the form
5653      (?expr << 4) | (?expr >> 4) or
5654      (?expr >> 4) | (?expr << 4) will make that
5655      into a SWAP : operation ..
5656      note : by 4 I mean (number of bits required to hold the
5657      variable /2 ) */
5658   /* if the root operation is not a | operation then not */
5659   if (!IS_BITOR (root))
5660     return root;
5661
5662   /* (?expr << 4) | (?expr >> 4) */
5663   if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
5664       || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
5665     {
5666
5667       if (!SPEC_USIGN (TETYPE (root->left->left)))
5668         return root;
5669
5670       if (!IS_AST_LIT_VALUE (root->left->right) ||
5671           !IS_AST_LIT_VALUE (root->right->right))
5672         return root;
5673
5674       /* make sure it is the same expression */
5675       if (!isAstEqual (root->left->left,
5676                        root->right->left))
5677         return root;
5678
5679       if (AST_LIT_VALUE (root->left->right) !=
5680           (getSize (TTYPE (root->left->left)) * 4))
5681         return root;
5682
5683       if (AST_LIT_VALUE (root->right->right) !=
5684           (getSize (TTYPE (root->left->left)) * 4))
5685         return root;
5686
5687       /* make sure the port supports SWAP */
5688       if (port->hasExtBitOp
5689           && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
5690         return root;
5691
5692       /* found it : create the AST */
5693       return newNode (SWAP, root->left->left, NULL);
5694     }
5695
5696
5697   /* not found return root */
5698   return root;
5699 }
5700
5701 /*-----------------------------------------------------------------*/
5702 /* optimizeCompare - optimizes compares for bit variables          */
5703 /*-----------------------------------------------------------------*/
5704 static ast *
5705 optimizeCompare (ast * root)
5706 {
5707   ast *optExpr = NULL;
5708   value *vleft;
5709   value *vright;
5710   unsigned int litValue;
5711
5712   /* if nothing then return nothing */
5713   if (!root)
5714     return NULL;
5715
5716   /* if not a compare op then do leaves */
5717   if (!IS_COMPARE_OP (root))
5718     {
5719       root->left = optimizeCompare (root->left);
5720       root->right = optimizeCompare (root->right);
5721       return root;
5722     }
5723
5724   /* if left & right are the same then depending
5725      of the operation do */
5726   if (isAstEqual (root->left, root->right))
5727     {
5728       switch (root->opval.op)
5729         {
5730         case '>':
5731         case '<':
5732         case NE_OP:
5733           optExpr = newAst_VALUE (constVal ("0"));
5734           break;
5735         case GE_OP:
5736         case LE_OP:
5737         case EQ_OP:
5738           optExpr = newAst_VALUE (constVal ("1"));
5739           break;
5740         }
5741
5742       return decorateType (optExpr, RESULT_TYPE_NONE);
5743     }
5744
5745   vleft = (root->left->type == EX_VALUE ?
5746            root->left->opval.val : NULL);
5747
5748   vright = (root->right->type == EX_VALUE ?
5749             root->right->opval.val : NULL);
5750
5751   /* if left is a BITVAR in BITSPACE */
5752   /* and right is a LITERAL then opt- */
5753   /* imize else do nothing       */
5754   if (vleft && vright &&
5755       IS_BITVAR (vleft->etype) &&
5756       IN_BITSPACE (SPEC_OCLS (vleft->etype)) &&
5757       IS_LITERAL (vright->etype))
5758     {
5759
5760       /* if right side > 1 then comparison may never succeed */
5761       if ((litValue = (int) floatFromVal (vright)) > 1)
5762         {
5763           werror (W_BAD_COMPARE);
5764           goto noOptimize;
5765         }
5766
5767       if (litValue)
5768         {
5769           switch (root->opval.op)
5770             {
5771             case '>':           /* bit value greater than 1 cannot be */
5772               werror (W_BAD_COMPARE);
5773               goto noOptimize;
5774               break;
5775
5776             case '<':           /* bit value < 1 means 0 */
5777             case NE_OP:
5778               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5779               break;
5780
5781             case LE_OP: /* bit value <= 1 means no check */
5782               optExpr = newAst_VALUE (vright);
5783               break;
5784
5785             case GE_OP: /* bit value >= 1 means only check for = */
5786             case EQ_OP:
5787               optExpr = newAst_VALUE (vleft);
5788               break;
5789             }
5790         }
5791       else
5792         {                       /* literal is zero */
5793           switch (root->opval.op)
5794             {
5795             case '<':           /* bit value < 0 cannot be */
5796               werror (W_BAD_COMPARE);
5797               goto noOptimize;
5798               break;
5799
5800             case '>':           /* bit value > 0 means 1 */
5801             case NE_OP:
5802               optExpr = newAst_VALUE (vleft);
5803               break;
5804
5805             case LE_OP: /* bit value <= 0 means no check */
5806             case GE_OP: /* bit value >= 0 means no check */
5807               werror (W_BAD_COMPARE);
5808               goto noOptimize;
5809               break;
5810
5811             case EQ_OP: /* bit == 0 means ! of bit */
5812               optExpr = newNode ('!', newAst_VALUE (vleft), NULL);
5813               break;
5814             }
5815         }
5816       return decorateType (resolveSymbols (optExpr), RESULT_TYPE_NONE);
5817     }                           /* end-of-if of BITVAR */
5818
5819 noOptimize:
5820   return root;
5821 }
5822 /*-----------------------------------------------------------------*/
5823 /* addSymToBlock : adds the symbol to the first block we find      */
5824 /*-----------------------------------------------------------------*/
5825 void
5826 addSymToBlock (symbol * sym, ast * tree)
5827 {
5828   /* reached end of tree or a leaf */
5829   if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree))
5830     return;
5831
5832   /* found a block */
5833   if (IS_AST_OP (tree) &&
5834       tree->opval.op == BLOCK)
5835     {
5836
5837       symbol *lsym = copySymbol (sym);
5838
5839       lsym->next = AST_VALUES (tree, sym);
5840       AST_VALUES (tree, sym) = lsym;
5841       return;
5842     }
5843
5844   addSymToBlock (sym, tree->left);
5845   addSymToBlock (sym, tree->right);
5846 }
5847
5848 /*-----------------------------------------------------------------*/
5849 /* processRegParms - do processing for register parameters         */
5850 /*-----------------------------------------------------------------*/
5851 static void
5852 processRegParms (value * args, ast * body)
5853 {
5854   while (args)
5855     {
5856       if (IS_REGPARM (args->etype))
5857         addSymToBlock (args->sym, body);
5858       args = args->next;
5859     }
5860 }
5861
5862 /*-----------------------------------------------------------------*/
5863 /* resetParmKey - resets the operandkeys for the symbols           */
5864 /*-----------------------------------------------------------------*/
5865 DEFSETFUNC (resetParmKey)
5866 {
5867   symbol *sym = item;
5868
5869   sym->key = 0;
5870   sym->defs = NULL;
5871   sym->uses = NULL;
5872   sym->remat = 0;
5873   return 1;
5874 }
5875
5876 /*-----------------------------------------------------------------*/
5877 /* createFunction - This is the key node that calls the iCode for  */
5878 /*                  generating the code for a function. Note code  */
5879 /*                  is generated function by function, later when  */
5880 /*                  add inter-procedural analysis this will change */
5881 /*-----------------------------------------------------------------*/
5882 ast *
5883 createFunction (symbol * name, ast * body)
5884 {
5885   ast *ex;
5886   symbol *csym;
5887   int stack = 0;
5888   sym_link *fetype;
5889   iCode *piCode = NULL;
5890
5891   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
5892     fprintf (stderr, "SDCCast.c:createFunction(%s)\n", name->name);
5893
5894   /* if check function return 0 then some problem */
5895   if (checkFunction (name, NULL) == 0)
5896     return NULL;
5897
5898   /* create a dummy block if none exists */
5899   if (!body)
5900     body = newNode (BLOCK, NULL, NULL);
5901
5902   noLineno++;
5903
5904   /* check if the function name already in the symbol table */
5905   if ((csym = findSym (SymbolTab, NULL, name->name)))
5906     {
5907       name = csym;
5908       /* special case for compiler defined functions
5909          we need to add the name to the publics list : this
5910          actually means we are now compiling the compiler
5911          support routine */
5912       if (name->cdef)
5913         {
5914           addSet (&publics, name);
5915         }
5916     }
5917   else
5918     {
5919       addSymChain (&name);
5920       allocVariables (name);
5921     }
5922   name->lastLine = mylineno;
5923   currFunc = name;
5924
5925   /* set the stack pointer */
5926   stackPtr  = -port->stack.direction * port->stack.call_overhead;
5927   xstackPtr = 0;
5928
5929   if (IFFUNC_ISISR (name->type))
5930     stackPtr -= port->stack.direction * port->stack.isr_overhead;
5931
5932   if (IFFUNC_ISREENT (name->type) || options.stackAuto)
5933     {
5934       if (options.useXstack)
5935         xstackPtr -= port->stack.direction * port->stack.reent_overhead;
5936       else
5937         stackPtr  -= port->stack.direction * port->stack.reent_overhead;
5938     }
5939
5940   fetype = getSpec (name->type);        /* get the specifier for the function */
5941   /* if this is a reentrant function then */
5942   if (IFFUNC_ISREENT (name->type))
5943     reentrant++;
5944
5945   allocParms (FUNC_ARGS(name->type));   /* allocate the parameters */
5946
5947   /* do processing for parameters that are passed in registers */
5948   processRegParms (FUNC_ARGS(name->type), body);
5949
5950   /* set the stack pointer */
5951   stackPtr = 0;
5952   xstackPtr = -1;
5953
5954   gatherImplicitVariables (body, NULL);  /* move implicit variables into blocks */
5955
5956   /* allocate & autoinit the block variables */
5957   processBlockVars (body, &stack, ALLOCATE);
5958
5959   /* name needs to be mangled */
5960   SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
5961
5962   body = resolveSymbols (body); /* resolve the symbols */
5963   body = decorateType (body, RESULT_TYPE_NONE); /* propagateType & do semantic checks */
5964
5965   /* save the stack information */
5966   if (options.useXstack)
5967     name->xstack = SPEC_STAK (fetype) = stack;
5968   else
5969     name->stack = SPEC_STAK (fetype) = stack;
5970
5971   ex = newAst_VALUE (symbolVal (name)); /* create name */
5972   ex = newNode (FUNCTION, ex, body);
5973   ex->values.args = FUNC_ARGS(name->type);
5974   ex->decorated=1;
5975   if (options.dump_tree) PA(ex);
5976   if (fatalError)
5977     {
5978       werror (E_FUNC_NO_CODE, name->name);
5979       goto skipall;
5980     }
5981
5982   /* create the node & generate intermediate code */
5983   GcurMemmap = code;
5984   codeOutFile = code->oFile;
5985   piCode = iCodeFromAst (ex);
5986
5987   if (fatalError)
5988     {
5989       werror (E_FUNC_NO_CODE, name->name);
5990       goto skipall;
5991     }
5992
5993   eBBlockFromiCode (piCode);
5994
5995   /* if there are any statics then do them */
5996   if (staticAutos)
5997     {
5998       GcurMemmap = statsg;
5999       codeOutFile = statsg->oFile;
6000       eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos), RESULT_TYPE_NONE)));
6001       staticAutos = NULL;
6002     }
6003
6004 skipall:
6005
6006   /* dealloc the block variables */
6007   processBlockVars (body, &stack, DEALLOCATE);
6008   outputDebugStackSymbols();
6009   /* deallocate paramaters */
6010   deallocParms (FUNC_ARGS(name->type));
6011
6012   if (IFFUNC_ISREENT (name->type))
6013     reentrant--;
6014
6015   /* we are done freeup memory & cleanup */
6016   noLineno--;
6017   if (port->reset_labelKey) labelKey = 1;
6018   name->key = 0;
6019   FUNC_HASBODY(name->type) = 1;
6020   addSet (&operKeyReset, name);
6021   applyToSet (operKeyReset, resetParmKey);
6022
6023   if (options.debug)
6024     cdbStructBlock(1);
6025
6026   cleanUpLevel (LabelTab, 0);
6027   cleanUpBlock (StructTab, 1);
6028   cleanUpBlock (TypedefTab, 1);
6029
6030   xstack->syms = NULL;
6031   istack->syms = NULL;
6032   return NULL;
6033 }
6034
6035
6036 #define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
6037 /*-----------------------------------------------------------------*/
6038 /* ast_print : prints the ast (for debugging purposes)             */
6039 /*-----------------------------------------------------------------*/
6040
6041 void ast_print (ast * tree, FILE *outfile, int indent)
6042 {
6043
6044         if (!tree) return ;
6045
6046         /* can print only decorated trees */
6047         if (!tree->decorated) return;
6048
6049         /* if any child is an error | this one is an error do nothing */
6050         if (tree->isError ||
6051             (tree->left && tree->left->isError) ||
6052             (tree->right && tree->right->isError)) {
6053                 fprintf(outfile,"ERROR_NODE(%p)\n",tree);
6054         }
6055
6056
6057         /* print the line          */
6058         /* if not block & function */
6059         if (tree->type == EX_OP &&
6060             (tree->opval.op != FUNCTION &&
6061              tree->opval.op != BLOCK &&
6062              tree->opval.op != NULLOP)) {
6063         }
6064
6065         if (tree->opval.op == FUNCTION) {
6066                 int arg=0;
6067                 value *args=FUNC_ARGS(tree->left->opval.val->type);
6068                 fprintf(outfile,"FUNCTION (%s=%p) type (",
6069                         tree->left->opval.val->name, tree);
6070                 printTypeChain (tree->left->opval.val->type->next,outfile);
6071                 fprintf(outfile,") args (");
6072                 do {
6073                   if (arg) {
6074                     fprintf (outfile, ", ");
6075                   }
6076                   printTypeChain (args ? args->type : NULL, outfile);
6077                   arg++;
6078                   args= args ? args->next : NULL;
6079                 } while (args);
6080                 fprintf(outfile,")\n");
6081                 ast_print(tree->left,outfile,indent);
6082                 ast_print(tree->right,outfile,indent);
6083                 return ;
6084         }
6085         if (tree->opval.op == BLOCK) {
6086                 symbol *decls = tree->values.sym;
6087                 INDENT(indent,outfile);
6088                 fprintf(outfile,"{\n");
6089                 while (decls) {
6090                         INDENT(indent+2,outfile);
6091                         fprintf(outfile,"DECLARE SYMBOL (%s=%p) type (",
6092                                 decls->name, decls);
6093                         printTypeChain(decls->type,outfile);
6094                         fprintf(outfile,")\n");
6095
6096                         decls = decls->next;
6097                 }
6098                 ast_print(tree->right,outfile,indent+2);
6099                 INDENT(indent,outfile);
6100                 fprintf(outfile,"}\n");
6101                 return;
6102         }
6103         if (tree->opval.op == NULLOP) {
6104                 ast_print(tree->left,outfile,indent);
6105                 ast_print(tree->right,outfile,indent);
6106                 return ;
6107         }
6108         INDENT(indent,outfile);
6109
6110         /*------------------------------------------------------------------*/
6111         /*----------------------------*/
6112         /*   leaf has been reached    */
6113         /*----------------------------*/
6114         /* if this is of type value */
6115         /* just get the type        */
6116         if (tree->type == EX_VALUE) {
6117
6118                 if (IS_LITERAL (tree->opval.val->etype)) {
6119                         fprintf(outfile,"CONSTANT (%p) value = ", tree);
6120                         if (SPEC_USIGN (tree->opval.val->etype))
6121                                 fprintf(outfile,"%u", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val));
6122                         else
6123                                 fprintf(outfile,"%d", (TYPE_TARGET_LONG) floatFromVal(tree->opval.val));
6124                         fprintf(outfile,", 0x%x, %f", (TYPE_TARGET_ULONG) floatFromVal(tree->opval.val),
6125                                                       floatFromVal(tree->opval.val));
6126                 } else if (tree->opval.val->sym) {
6127                         /* if the undefined flag is set then give error message */
6128                         if (tree->opval.val->sym->undefined) {
6129                                 fprintf(outfile,"UNDEFINED SYMBOL ");
6130                         } else {
6131                                 fprintf(outfile,"SYMBOL ");
6132                         }
6133                         fprintf(outfile,"(%s=%p @ %p)",
6134                                 tree->opval.val->sym->name, tree, tree->opval.val->sym);
6135                 }
6136                 if (tree->ftype) {
6137                         fprintf(outfile," type (");
6138                         printTypeChain(tree->ftype,outfile);
6139                         fprintf(outfile,")\n");
6140                 } else {
6141                         fprintf(outfile,"\n");
6142                 }
6143                 return ;
6144         }
6145
6146         /* if type link for the case of cast */
6147         if (tree->type == EX_LINK) {
6148                 fprintf(outfile,"TYPENODE (%p) type = (",tree);
6149                 printTypeChain(tree->opval.lnk,outfile);
6150                 fprintf(outfile,")\n");
6151                 return ;
6152         }
6153
6154
6155         /* depending on type of operator do */
6156
6157         switch (tree->opval.op) {
6158                 /*------------------------------------------------------------------*/
6159                 /*----------------------------*/
6160                 /*        array node          */
6161                 /*----------------------------*/
6162         case '[':
6163                 fprintf(outfile,"ARRAY_OP (%p) type (",tree);
6164                 printTypeChain(tree->ftype,outfile);
6165                 fprintf(outfile,")\n");
6166                 ast_print(tree->left,outfile,indent+2);
6167                 ast_print(tree->right,outfile,indent+2);
6168                 return;
6169
6170                 /*------------------------------------------------------------------*/
6171                 /*----------------------------*/
6172                 /*      struct/union          */
6173                 /*----------------------------*/
6174         case '.':
6175                 fprintf(outfile,"STRUCT_ACCESS (%p) type (",tree);
6176                 printTypeChain(tree->ftype,outfile);
6177                 fprintf(outfile,")\n");
6178                 ast_print(tree->left,outfile,indent+2);
6179                 ast_print(tree->right,outfile,indent+2);
6180                 return ;
6181
6182                 /*------------------------------------------------------------------*/
6183                 /*----------------------------*/
6184                 /*    struct/union pointer    */
6185                 /*----------------------------*/
6186         case PTR_OP:
6187                 fprintf(outfile,"PTR_ACCESS (%p) type (",tree);
6188                 printTypeChain(tree->ftype,outfile);
6189                 fprintf(outfile,")\n");
6190                 ast_print(tree->left,outfile,indent+2);
6191                 ast_print(tree->right,outfile,indent+2);
6192                 return ;
6193
6194                 /*------------------------------------------------------------------*/
6195                 /*----------------------------*/
6196                 /*  ++/-- operation           */
6197                 /*----------------------------*/
6198         case INC_OP:
6199                 if (tree->left)
6200                   fprintf(outfile,"post-");
6201                 else
6202                   fprintf(outfile,"pre-");
6203                 fprintf(outfile,"INC_OP (%p) type (",tree);
6204                 printTypeChain(tree->ftype,outfile);
6205                 fprintf(outfile,")\n");
6206                 ast_print(tree->left,outfile,indent+2); /* postincrement case */
6207                 ast_print(tree->right,outfile,indent+2); /* preincrement case */
6208                 return ;
6209
6210         case DEC_OP:
6211                 if (tree->left)
6212                   fprintf(outfile,"post-");
6213                 else
6214                   fprintf(outfile,"pre-");
6215                 fprintf(outfile,"DEC_OP (%p) type (",tree);
6216                 printTypeChain(tree->ftype,outfile);
6217                 fprintf(outfile,")\n");
6218                 ast_print(tree->left,outfile,indent+2); /* postdecrement case */
6219                 ast_print(tree->right,outfile,indent+2); /* predecrement case */
6220                 return ;
6221
6222                 /*------------------------------------------------------------------*/
6223                 /*----------------------------*/
6224                 /*  bitwise and               */
6225                 /*----------------------------*/
6226         case '&':
6227                 if (tree->right) {
6228                         fprintf(outfile,"& (%p) type (",tree);
6229                         printTypeChain(tree->ftype,outfile);
6230                         fprintf(outfile,")\n");
6231                         ast_print(tree->left,outfile,indent+2);
6232                         ast_print(tree->right,outfile,indent+2);
6233                 } else {
6234                         fprintf(outfile,"ADDRESS_OF (%p) type (",tree);
6235                         printTypeChain(tree->ftype,outfile);
6236                         fprintf(outfile,")\n");
6237                         ast_print(tree->left,outfile,indent+2);
6238                         ast_print(tree->right,outfile,indent+2);
6239                 }
6240                 return ;
6241                 /*----------------------------*/
6242                 /*  bitwise or                */
6243                 /*----------------------------*/
6244         case '|':
6245                 fprintf(outfile,"OR (%p) type (",tree);
6246                 printTypeChain(tree->ftype,outfile);
6247                 fprintf(outfile,")\n");
6248                 ast_print(tree->left,outfile,indent+2);
6249                 ast_print(tree->right,outfile,indent+2);
6250                 return ;
6251                 /*------------------------------------------------------------------*/
6252                 /*----------------------------*/
6253                 /*  bitwise xor               */
6254                 /*----------------------------*/
6255         case '^':
6256                 fprintf(outfile,"XOR (%p) type (",tree);
6257                 printTypeChain(tree->ftype,outfile);
6258                 fprintf(outfile,")\n");
6259                 ast_print(tree->left,outfile,indent+2);
6260                 ast_print(tree->right,outfile,indent+2);
6261                 return ;
6262
6263                 /*------------------------------------------------------------------*/
6264                 /*----------------------------*/
6265                 /*  division                  */
6266                 /*----------------------------*/
6267         case '/':
6268                 fprintf(outfile,"DIV (%p) type (",tree);
6269                 printTypeChain(tree->ftype,outfile);
6270                 fprintf(outfile,")\n");
6271                 ast_print(tree->left,outfile,indent+2);
6272                 ast_print(tree->right,outfile,indent+2);
6273                 return ;
6274                 /*------------------------------------------------------------------*/
6275                 /*----------------------------*/
6276                 /*            modulus         */
6277                 /*----------------------------*/
6278         case '%':
6279                 fprintf(outfile,"MOD (%p) type (",tree);
6280                 printTypeChain(tree->ftype,outfile);
6281                 fprintf(outfile,")\n");
6282                 ast_print(tree->left,outfile,indent+2);
6283                 ast_print(tree->right,outfile,indent+2);
6284                 return ;
6285
6286                 /*------------------------------------------------------------------*/
6287                 /*----------------------------*/
6288                 /*  address dereference       */
6289                 /*----------------------------*/
6290         case '*':                       /* can be unary  : if right is null then unary operation */
6291                 if (!tree->right) {
6292                         fprintf(outfile,"DEREF (%p) type (",tree);
6293                         printTypeChain(tree->ftype,outfile);
6294                         fprintf(outfile,")\n");
6295                         ast_print(tree->left,outfile,indent+2);
6296                         return ;
6297                 }
6298                 /*------------------------------------------------------------------*/
6299                 /*----------------------------*/
6300                 /*      multiplication        */
6301                 /*----------------------------*/
6302                 fprintf(outfile,"MULT (%p) type (",tree);
6303                 printTypeChain(tree->ftype,outfile);
6304                 fprintf(outfile,")\n");
6305                 ast_print(tree->left,outfile,indent+2);
6306                 ast_print(tree->right,outfile,indent+2);
6307                 return ;
6308
6309
6310                 /*------------------------------------------------------------------*/
6311                 /*----------------------------*/
6312                 /*    unary '+' operator      */
6313                 /*----------------------------*/
6314         case '+':
6315                 /* if unary plus */
6316                 if (!tree->right) {
6317                         fprintf(outfile,"UPLUS (%p) type (",tree);
6318                         printTypeChain(tree->ftype,outfile);
6319                         fprintf(outfile,")\n");
6320                         ast_print(tree->left,outfile,indent+2);
6321                 } else {
6322                         /*------------------------------------------------------------------*/
6323                         /*----------------------------*/
6324                         /*      addition              */
6325                         /*----------------------------*/
6326                         fprintf(outfile,"ADD (%p) type (",tree);
6327                         printTypeChain(tree->ftype,outfile);
6328                         fprintf(outfile,")\n");
6329                         ast_print(tree->left,outfile,indent+2);
6330                         ast_print(tree->right,outfile,indent+2);
6331                 }
6332                 return;
6333                 /*------------------------------------------------------------------*/
6334                 /*----------------------------*/
6335                 /*      unary '-'             */
6336                 /*----------------------------*/
6337         case '-':                       /* can be unary   */
6338                 if (!tree->right) {
6339                         fprintf(outfile,"UMINUS (%p) type (",tree);
6340                         printTypeChain(tree->ftype,outfile);
6341                         fprintf(outfile,")\n");
6342                         ast_print(tree->left,outfile,indent+2);
6343                 } else {
6344                         /*------------------------------------------------------------------*/
6345                         /*----------------------------*/
6346                         /*      subtraction           */
6347                         /*----------------------------*/
6348                         fprintf(outfile,"SUB (%p) type (",tree);
6349                         printTypeChain(tree->ftype,outfile);
6350                         fprintf(outfile,")\n");
6351                         ast_print(tree->left,outfile,indent+2);
6352                         ast_print(tree->right,outfile,indent+2);
6353                 }
6354                 return;
6355                 /*------------------------------------------------------------------*/
6356                 /*----------------------------*/
6357                 /*    complement              */
6358                 /*----------------------------*/
6359         case '~':
6360                 fprintf(outfile,"COMPL (%p) type (",tree);
6361                 printTypeChain(tree->ftype,outfile);
6362                 fprintf(outfile,")\n");
6363                 ast_print(tree->left,outfile,indent+2);
6364                 return ;
6365                 /*------------------------------------------------------------------*/
6366                 /*----------------------------*/
6367                 /*           not              */
6368                 /*----------------------------*/
6369         case '!':
6370                 fprintf(outfile,"NOT (%p) type (",tree);
6371                 printTypeChain(tree->ftype,outfile);
6372                 fprintf(outfile,")\n");
6373                 ast_print(tree->left,outfile,indent+2);
6374                 return ;
6375                 /*------------------------------------------------------------------*/
6376                 /*----------------------------*/
6377                 /*           shift            */
6378                 /*----------------------------*/
6379         case RRC:
6380                 fprintf(outfile,"RRC (%p) type (",tree);
6381                 printTypeChain(tree->ftype,outfile);
6382                 fprintf(outfile,")\n");
6383                 ast_print(tree->left,outfile,indent+2);
6384                 return ;
6385
6386         case RLC:
6387                 fprintf(outfile,"RLC (%p) type (",tree);
6388                 printTypeChain(tree->ftype,outfile);
6389                 fprintf(outfile,")\n");
6390                 ast_print(tree->left,outfile,indent+2);
6391                 return ;
6392         case SWAP:
6393                 fprintf(outfile,"SWAP (%p) type (",tree);
6394                 printTypeChain(tree->ftype,outfile);
6395                 fprintf(outfile,")\n");
6396                 ast_print(tree->left,outfile,indent+2);
6397                 return ;
6398         case GETHBIT:
6399                 fprintf(outfile,"GETHBIT (%p) type (",tree);
6400                 printTypeChain(tree->ftype,outfile);
6401                 fprintf(outfile,")\n");
6402                 ast_print(tree->left,outfile,indent+2);
6403                 return ;
6404         case GETABIT:
6405                 fprintf(outfile,"GETABIT (%p) type (",tree);
6406                 printTypeChain(tree->ftype,outfile);
6407                 fprintf(outfile,")\n");
6408                 ast_print(tree->left,outfile,indent+2);
6409                 ast_print(tree->right,outfile,indent+2);
6410                 return ;
6411         case GETBYTE:
6412                 fprintf(outfile,"GETBYTE (%p) type (",tree);
6413                 printTypeChain(tree->ftype,outfile);
6414                 fprintf(outfile,")\n");
6415                 ast_print(tree->left,outfile,indent+2);
6416                 ast_print(tree->right,outfile,indent+2);
6417                 return ;
6418         case GETWORD:
6419                 fprintf(outfile,"GETWORD (%p) type (",tree);
6420                 printTypeChain(tree->ftype,outfile);
6421                 fprintf(outfile,")\n");
6422                 ast_print(tree->left,outfile,indent+2);
6423                 ast_print(tree->right,outfile,indent+2);
6424                 return ;
6425         case LEFT_OP:
6426                 fprintf(outfile,"LEFT_SHIFT (%p) type (",tree);
6427                 printTypeChain(tree->ftype,outfile);
6428                 fprintf(outfile,")\n");
6429                 ast_print(tree->left,outfile,indent+2);
6430                 ast_print(tree->right,outfile,indent+2);
6431                 return ;
6432         case RIGHT_OP:
6433                 fprintf(outfile,"RIGHT_SHIFT (%p) type (",tree);
6434                 printTypeChain(tree->ftype,outfile);
6435                 fprintf(outfile,")\n");
6436                 ast_print(tree->left,outfile,indent+2);
6437                 ast_print(tree->right,outfile,indent+2);
6438                 return ;
6439                 /*------------------------------------------------------------------*/
6440                 /*----------------------------*/
6441                 /*         casting            */
6442                 /*----------------------------*/
6443         case CAST:                      /* change the type   */
6444                 fprintf(outfile,"CAST (%p) from type (",tree);
6445                 printTypeChain(tree->right->ftype,outfile);
6446                 fprintf(outfile,") to type (");
6447                 printTypeChain(tree->ftype,outfile);
6448                 fprintf(outfile,")\n");
6449                 ast_print(tree->right,outfile,indent+2);
6450                 return ;
6451
6452         case AND_OP:
6453                 fprintf(outfile,"ANDAND (%p) type (",tree);
6454                 printTypeChain(tree->ftype,outfile);
6455                 fprintf(outfile,")\n");
6456                 ast_print(tree->left,outfile,indent+2);
6457                 ast_print(tree->right,outfile,indent+2);
6458                 return ;
6459         case OR_OP:
6460                 fprintf(outfile,"OROR (%p) type (",tree);
6461                 printTypeChain(tree->ftype,outfile);
6462                 fprintf(outfile,")\n");
6463                 ast_print(tree->left,outfile,indent+2);
6464                 ast_print(tree->right,outfile,indent+2);
6465                 return ;
6466
6467                 /*------------------------------------------------------------------*/
6468                 /*----------------------------*/
6469                 /*     comparison operators   */
6470                 /*----------------------------*/
6471         case '>':
6472                 fprintf(outfile,"GT(>) (%p) type (",tree);
6473                 printTypeChain(tree->ftype,outfile);
6474                 fprintf(outfile,")\n");
6475                 ast_print(tree->left,outfile,indent+2);
6476                 ast_print(tree->right,outfile,indent+2);
6477                 return ;
6478         case '<':
6479                 fprintf(outfile,"LT(<) (%p) type (",tree);
6480                 printTypeChain(tree->ftype,outfile);
6481                 fprintf(outfile,")\n");
6482                 ast_print(tree->left,outfile,indent+2);
6483                 ast_print(tree->right,outfile,indent+2);
6484                 return ;
6485         case LE_OP:
6486                 fprintf(outfile,"LE(<=) (%p) type (",tree);
6487                 printTypeChain(tree->ftype,outfile);
6488                 fprintf(outfile,")\n");
6489                 ast_print(tree->left,outfile,indent+2);
6490                 ast_print(tree->right,outfile,indent+2);
6491                 return ;
6492         case GE_OP:
6493                 fprintf(outfile,"GE(>=) (%p) type (",tree);
6494                 printTypeChain(tree->ftype,outfile);
6495                 fprintf(outfile,")\n");
6496                 ast_print(tree->left,outfile,indent+2);
6497                 ast_print(tree->right,outfile,indent+2);
6498                 return ;
6499         case EQ_OP:
6500                 fprintf(outfile,"EQ(==) (%p) type (",tree);
6501                 printTypeChain(tree->ftype,outfile);
6502                 fprintf(outfile,")\n");
6503                 ast_print(tree->left,outfile,indent+2);
6504                 ast_print(tree->right,outfile,indent+2);
6505                 return ;
6506         case NE_OP:
6507                 fprintf(outfile,"NE(!=) (%p) type (",tree);
6508                 printTypeChain(tree->ftype,outfile);
6509                 fprintf(outfile,")\n");
6510                 ast_print(tree->left,outfile,indent+2);
6511                 ast_print(tree->right,outfile,indent+2);
6512                 /*------------------------------------------------------------------*/
6513                 /*----------------------------*/
6514                 /*             sizeof         */
6515                 /*----------------------------*/
6516         case SIZEOF:            /* evaluate wihout code generation */
6517                 fprintf(outfile,"SIZEOF %d\n",(getSize (tree->right->ftype)));
6518                 return ;
6519
6520                 /*------------------------------------------------------------------*/
6521                 /*----------------------------*/
6522                 /* conditional operator  '?'  */
6523                 /*----------------------------*/
6524         case '?':
6525                 fprintf(outfile,"QUEST(?) (%p) type (",tree);
6526                 printTypeChain(tree->ftype,outfile);
6527                 fprintf(outfile,")\n");
6528                 ast_print(tree->left,outfile,indent+2);
6529                 ast_print(tree->right,outfile,indent+2);
6530                 return;
6531
6532         case ':':
6533                 fprintf(outfile,"COLON(:) (%p) type (",tree);
6534                 printTypeChain(tree->ftype,outfile);
6535                 fprintf(outfile,")\n");
6536                 ast_print(tree->left,outfile,indent+2);
6537                 ast_print(tree->right,outfile,indent+2);
6538                 return ;
6539
6540                 /*------------------------------------------------------------------*/
6541                 /*----------------------------*/
6542                 /*    assignment operators    */
6543                 /*----------------------------*/
6544         case MUL_ASSIGN:
6545                 fprintf(outfile,"MULASS(*=) (%p) type (",tree);
6546                 printTypeChain(tree->ftype,outfile);
6547                 fprintf(outfile,")\n");
6548                 ast_print(tree->left,outfile,indent+2);
6549                 ast_print(tree->right,outfile,indent+2);
6550                 return;
6551         case DIV_ASSIGN:
6552                 fprintf(outfile,"DIVASS(/=) (%p) type (",tree);
6553                 printTypeChain(tree->ftype,outfile);
6554                 fprintf(outfile,")\n");
6555                 ast_print(tree->left,outfile,indent+2);
6556                 ast_print(tree->right,outfile,indent+2);
6557                 return;
6558         case AND_ASSIGN:
6559                 fprintf(outfile,"ANDASS(&=) (%p) type (",tree);
6560                 printTypeChain(tree->ftype,outfile);
6561                 fprintf(outfile,")\n");
6562                 ast_print(tree->left,outfile,indent+2);
6563                 ast_print(tree->right,outfile,indent+2);
6564                 return;
6565         case OR_ASSIGN:
6566                 fprintf(outfile,"ORASS(|=) (%p) type (",tree);
6567                 printTypeChain(tree->ftype,outfile);
6568                 fprintf(outfile,")\n");
6569                 ast_print(tree->left,outfile,indent+2);
6570                 ast_print(tree->right,outfile,indent+2);
6571                 return;
6572         case XOR_ASSIGN:
6573                 fprintf(outfile,"XORASS(^=) (%p) type (",tree);
6574                 printTypeChain(tree->ftype,outfile);
6575                 fprintf(outfile,")\n");
6576                 ast_print(tree->left,outfile,indent+2);
6577                 ast_print(tree->right,outfile,indent+2);
6578                 return;
6579         case RIGHT_ASSIGN:
6580                 fprintf(outfile,"RSHFTASS(>>=) (%p) type (",tree);
6581                 printTypeChain(tree->ftype,outfile);
6582                 fprintf(outfile,")\n");
6583                 ast_print(tree->left,outfile,indent+2);
6584                 ast_print(tree->right,outfile,indent+2);
6585                 return;
6586         case LEFT_ASSIGN:
6587                 fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
6588                 printTypeChain(tree->ftype,outfile);
6589                 fprintf(outfile,")\n");
6590                 ast_print(tree->left,outfile,indent+2);
6591                 ast_print(tree->right,outfile,indent+2);
6592                 return;
6593                 /*------------------------------------------------------------------*/
6594                 /*----------------------------*/
6595                 /*    -= operator             */
6596                 /*----------------------------*/
6597         case SUB_ASSIGN:
6598                 fprintf(outfile,"SUBASS(-=) (%p) type (",tree);
6599                 printTypeChain(tree->ftype,outfile);
6600                 fprintf(outfile,")\n");
6601                 ast_print(tree->left,outfile,indent+2);
6602                 ast_print(tree->right,outfile,indent+2);
6603                 return;
6604                 /*------------------------------------------------------------------*/
6605                 /*----------------------------*/
6606                 /*          += operator       */
6607                 /*----------------------------*/
6608         case ADD_ASSIGN:
6609                 fprintf(outfile,"ADDASS(+=) (%p) type (",tree);
6610                 printTypeChain(tree->ftype,outfile);
6611                 fprintf(outfile,")\n");
6612                 ast_print(tree->left,outfile,indent+2);
6613                 ast_print(tree->right,outfile,indent+2);
6614                 return;
6615                 /*------------------------------------------------------------------*/
6616                 /*----------------------------*/
6617                 /*      straight assignemnt   */
6618                 /*----------------------------*/
6619         case '=':
6620                 fprintf(outfile,"ASSIGN(=) (%p) type (",tree);
6621                 printTypeChain(tree->ftype,outfile);
6622                 fprintf(outfile,")\n");
6623                 ast_print(tree->left,outfile,indent+2);
6624                 ast_print(tree->right,outfile,indent+2);
6625                 return;
6626                 /*------------------------------------------------------------------*/
6627                 /*----------------------------*/
6628                 /*      comma operator        */
6629                 /*----------------------------*/
6630         case ',':
6631                 fprintf(outfile,"COMMA(,) (%p) type (",tree);
6632                 printTypeChain(tree->ftype,outfile);
6633                 fprintf(outfile,")\n");
6634                 ast_print(tree->left,outfile,indent+2);
6635                 ast_print(tree->right,outfile,indent+2);
6636                 return;
6637                 /*------------------------------------------------------------------*/
6638                 /*----------------------------*/
6639                 /*       function call        */
6640                 /*----------------------------*/
6641         case CALL:
6642         case PCALL:
6643                 fprintf(outfile,"CALL (%p) type (",tree);
6644                 printTypeChain(tree->ftype,outfile);
6645                 fprintf(outfile,")\n");
6646                 ast_print(tree->left,outfile,indent+2);
6647                 ast_print(tree->right,outfile,indent+2);
6648                 return;
6649         case PARAM:
6650                 fprintf(outfile,"PARMS\n");
6651                 ast_print(tree->left,outfile,indent+2);
6652                 if (tree->right /*&& !IS_AST_PARAM(tree->right)*/) {
6653                         ast_print(tree->right,outfile,indent+2);
6654                 }
6655                 return ;
6656                 /*------------------------------------------------------------------*/
6657                 /*----------------------------*/
6658                 /*     return statement       */
6659                 /*----------------------------*/
6660         case RETURN:
6661                 fprintf(outfile,"RETURN (%p) type (",tree);
6662                 if (tree->right) {
6663                     printTypeChain(tree->right->ftype,outfile);
6664                 }
6665                 fprintf(outfile,")\n");
6666                 ast_print(tree->right,outfile,indent+2);
6667                 return ;
6668                 /*------------------------------------------------------------------*/
6669                 /*----------------------------*/
6670                 /*     label statement        */
6671                 /*----------------------------*/
6672         case LABEL :
6673                 fprintf(outfile,"LABEL (%p)\n",tree);
6674                 ast_print(tree->left,outfile,indent+2);
6675                 ast_print(tree->right,outfile,indent);
6676                 return;
6677                 /*------------------------------------------------------------------*/
6678                 /*----------------------------*/
6679                 /*     switch statement       */
6680                 /*----------------------------*/
6681         case SWITCH:
6682                 {
6683                         value *val;
6684                         fprintf(outfile,"SWITCH (%p) ",tree);
6685                         ast_print(tree->left,outfile,0);
6686                         for (val = tree->values.switchVals.swVals; val ; val = val->next) {
6687                                 INDENT(indent+2,outfile);
6688                                 fprintf(outfile,"CASE 0x%x GOTO _case_%d_%d\n",
6689                                         (int) floatFromVal(val),
6690                                         tree->values.switchVals.swNum,
6691                                         (int) floatFromVal(val));
6692                         }
6693                         ast_print(tree->right,outfile,indent);
6694                 }
6695                 return ;
6696                 /*------------------------------------------------------------------*/
6697                 /*----------------------------*/
6698                 /* ifx Statement              */
6699                 /*----------------------------*/
6700         case IFX:
6701                 fprintf(outfile,"IF (%p) \n",tree);
6702                 ast_print(tree->left,outfile,indent+2);
6703                 if (tree->trueLabel) {
6704                         INDENT(indent+2,outfile);
6705                         fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
6706                 }
6707                 if (tree->falseLabel) {
6708                         INDENT(indent+2,outfile);
6709                         fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
6710                 }
6711                 ast_print(tree->right,outfile,indent+2);
6712                 return ;
6713                 /*----------------------------*/
6714                 /* goto Statement              */
6715                 /*----------------------------*/
6716         case GOTO:
6717                 fprintf(outfile,"GOTO (%p) \n",tree);
6718                 ast_print(tree->left,outfile,indent+2);
6719                 fprintf(outfile,"\n");
6720                 return ;
6721                 /*------------------------------------------------------------------*/
6722                 /*----------------------------*/
6723                 /* for Statement              */
6724                 /*----------------------------*/
6725         case FOR:
6726                 fprintf(outfile,"FOR (%p) \n",tree);
6727                 if (AST_FOR( tree, initExpr)) {
6728                         INDENT(indent+2,outfile);
6729                         fprintf(outfile,"INIT EXPR ");
6730                         ast_print(AST_FOR(tree, initExpr),outfile,indent+2);
6731                 }
6732                 if (AST_FOR( tree, condExpr)) {
6733                         INDENT(indent+2,outfile);
6734                         fprintf(outfile,"COND EXPR ");
6735                         ast_print(AST_FOR(tree, condExpr),outfile,indent+2);
6736                 }
6737                 if (AST_FOR( tree, loopExpr)) {
6738                         INDENT(indent+2,outfile);
6739                         fprintf(outfile,"LOOP EXPR ");
6740                         ast_print(AST_FOR(tree, loopExpr),outfile,indent+2);
6741                 }
6742                 fprintf(outfile,"FOR LOOP BODY \n");
6743                 ast_print(tree->left,outfile,indent+2);
6744                 return ;
6745         case CRITICAL:
6746                 fprintf(outfile,"CRITICAL (%p) \n",tree);
6747                 ast_print(tree->left,outfile,indent+2);
6748         default:
6749             return ;
6750         }
6751 }
6752
6753 void PA(ast *t)
6754 {
6755         ast_print(t,stdout,0);
6756 }
6757
6758
6759
6760 /*-----------------------------------------------------------------*/
6761 /* astErrors : returns non-zero if errors present in tree          */
6762 /*-----------------------------------------------------------------*/
6763 int astErrors(ast *t)
6764 {
6765   int errors=0;
6766
6767   if (t)
6768     {
6769       if (t->isError)
6770         errors++;
6771
6772       if (t->type == EX_VALUE
6773           && t->opval.val->sym
6774           && t->opval.val->sym->undefined)
6775         errors++;
6776
6777       errors += astErrors(t->left);
6778       errors += astErrors(t->right);
6779     }
6780
6781   return errors;
6782 }