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