* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc / src / .svn / text-base / tree.c.svn-base
blobd2b6a9173d33f15ee1899025bbd09ae309ad1cf5
1 #include "c.h"
4 int where = STMT;
5 static int warn;
6 static int nid = 1;             /* identifies trees & nodes in debugging output */
7 static struct nodeid {
8         int printed;
9         Tree node;
10 } ids[500];                     /* if ids[i].node == p, then p's id is i */
12 static void printtree1(Tree, int, int);
14 Tree tree(int op, Type type, Tree left, Tree right) {
15         Tree p;
17         NEW0(p, where);
18         p->op = op;
19         p->type = type;
20         p->kids[0] = left;
21         p->kids[1] = right;
22         return p;
25 Tree texpr(Tree (*f)(int), int tok, int a) {
26         int save = where;
27         Tree p;
29         where = a;
30         p = (*f)(tok);
31         where = save;
32         return p;
34 static Tree root1(Tree p) {
35         if (p == NULL)
36                 return p;
37         if (p->type == voidtype)
38                 warn++;
39         switch (generic(p->op)) {
40         case COND: {
41                 Tree q = p->kids[1];
42                 assert(q && q->op == RIGHT);
43                 if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN)
44                         q->kids[0] = root1(q->kids[0]->kids[1]);
45                 else
46                         q->kids[0] = root1(q->kids[0]);
47                 if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN)
48                         q->kids[1] = root1(q->kids[1]->kids[1]);
49                 else
50                         q->kids[1] = root1(q->kids[1]);
51                 p->u.sym = 0;
52                 if (q->kids[0] == 0 && q->kids[1] == 0)
53                         p = root1(p->kids[0]);
54                 }
55                 break;
56         case AND: case OR:
57                 if ((p->kids[1] = root1(p->kids[1])) == 0)
58                         p = root1(p->kids[0]);
59                 break;
60         case NOT:
61                 if (warn++ == 0)
62                         warning("expression with no effect elided\n");
63                 return root1(p->kids[0]);
64         case RIGHT:
65                 if (p->kids[1] == 0)
66                         return root1(p->kids[0]);
67                 if (p->kids[0] && p->kids[0]->op == CALL+B
68                 &&  p->kids[1] && p->kids[1]->op == INDIR+B)
69                         /* avoid premature release of the CALL+B temporary */
70                         return p->kids[0];
71                 if (p->kids[0] && p->kids[0]->op == RIGHT
72                 &&  p->kids[1] == p->kids[0]->kids[0])
73                         /* de-construct e++ construction */
74                         return p->kids[0]->kids[1];
75                 p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1]));
76                 return p->kids[0] || p->kids[1] ? p : (Tree)0;
77         case EQ:  case NE:  case GT:   case GE:  case LE:  case LT: 
78         case ADD: case SUB: case MUL:  case DIV: case MOD:
79         case LSH: case RSH: case BAND: case BOR: case BXOR:
80                 if (warn++ == 0)
81                         warning("expression with no effect elided\n");
82                 p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1]));
83                 return p->kids[0] || p->kids[1] ? p : (Tree)0;
84         case INDIR:
85                 if (p->type->size == 0 && unqual(p->type) != voidtype)
86                         warning("reference to `%t' elided\n", p->type);
87                 if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
88                         warning("reference to `volatile %t' elided\n", p->type);
89                 /* fall thru */
90         case CVI: case CVF: case CVU: case CVP:
91         case NEG: case BCOM: case FIELD:
92                 if (warn++ == 0)
93                         warning("expression with no effect elided\n");
94                 return root1(p->kids[0]);
95         case ADDRL: case ADDRG: case ADDRF: case CNST:
96                 if (needconst)
97                         return p;
98                 if (warn++ == 0)
99                         warning("expression with no effect elided\n");
100                 return NULL;
101         case ARG: case ASGN: case CALL: case JUMP: case LABEL:
102                 break;
103         default: assert(0);
104         }
105         return p;
108 Tree root(Tree p) {
109         warn = 0;
110         return root1(p);
113 char *opname(int op) {
114         static char *opnames[] = {
115         "",
116         "CNST",
117         "ARG",
118         "ASGN",
119         "INDIR",
120         "CVC",
121         "CVD",
122         "CVF",
123         "CVI",
124         "CVP",
125         "CVS",
126         "CVU",
127         "NEG",
128         "CALL",
129         "*LOAD*",
130         "RET",
131         "ADDRG",
132         "ADDRF",
133         "ADDRL",
134         "ADD",
135         "SUB",
136         "LSH",
137         "MOD",
138         "RSH",
139         "BAND",
140         "BCOM",
141         "BOR",
142         "BXOR",
143         "DIV",
144         "MUL",
145         "EQ",
146         "GE",
147         "GT",
148         "LE",
149         "LT",
150         "NE",
151         "JUMP",
152         "LABEL",
153         "AND",
154         "NOT",
155         "OR",
156         "COND",
157         "RIGHT",
158         "FIELD"
159         }, *suffixes[] = {
160                 "0", "F", "D", "C", "S", "I", "U", "P", "V", "B",
161                 "10","11","12","13","14","15"
162         };
164         if (generic(op) >= AND && generic(op) <= FIELD && opsize(op) == 0)
165                 return opnames[opindex(op)];
166         return stringf("%s%s%s",
167                 opindex(op) > 0 && opindex(op) < NELEMS(opnames) ?
168                         opnames[opindex(op)] : stringd(opindex(op)),
169                 suffixes[optype(op)], opsize(op) > 0 ? stringd(opsize(op)) : "");
172 int nodeid(Tree p) {
173         int i = 1;
175         ids[nid].node = p;
176         while (ids[i].node != p)
177                 i++;
178         if (i == nid)
179                 ids[nid++].printed = 0;
180         return i;
183 /* printed - return pointer to ids[id].printed */
184 int *printed(int id) {
185         if (id)
186                 return &ids[id].printed;
187         nid = 1;
188         return 0;
191 /* printtree - print tree p on fd */
192 void printtree(Tree p, int fd) {
193         (void)printed(0);
194         printtree1(p, fd, 1);
197 /* printtree1 - recursively print tree p */
198 static void printtree1(Tree p, int fd, int lev) {
199         FILE *f = fd == 1 ? stdout : stderr;
200         int i;
201         static char blanks[] = "                                                   ";
203         if (p == 0 || *printed(i = nodeid(p)))
204                 return;
205         fprint(f, "#%d%S%S", i, blanks, i < 10 ? 2 : i < 100 ? 1 : 0, blanks, lev);
206         fprint(f, "%s %t", opname(p->op), p->type);
207         *printed(i) = 1;
208         for (i = 0; i < NELEMS(p->kids); i++)
209                 if (p->kids[i])
210                         fprint(f, " #%d", nodeid(p->kids[i]));
211         if (p->op == FIELD && p->u.field)
212                 fprint(f, " %s %d..%d", p->u.field->name,
213                         fieldsize(p->u.field) + fieldright(p->u.field), fieldright(p->u.field));
214         else if (generic(p->op) == CNST)
215                 fprint(f, " %s", vtoa(p->type, p->u.v));
216         else if (p->u.sym)
217                 fprint(f, " %s", p->u.sym->name);
218         if (p->node)
219                 fprint(f, " node=%p", p->node);
220         fprint(f, "\n");
221         for (i = 0; i < NELEMS(p->kids); i++)
222                 printtree1(p->kids[i], fd, lev + 1);