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