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