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