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