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