* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc / src / tree.c
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]);
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);
105 return p;
108 Tree root(Tree p) {
109 warn = 0;
110 return root1(p);
113 char *opname(int op) {
114 static char *opnames[] = {
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"
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);