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