6 static int nid = 1; /* identifies trees & nodes in debugging output */
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) {
25 Tree texpr(Tree (*f)(int), int tok, int a) {
34 static Tree root1(Tree p) {
37 if (p->type == voidtype)
39 switch (generic(p->op)) {
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]);
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]);
50 q->kids[1] = root1(q->kids[1]);
52 if (q->kids[0] == 0 && q->kids[1] == 0)
53 p = root1(p->kids[0]);
57 if ((p->kids[1] = root1(p->kids[1])) == 0)
58 p = root1(p->kids[0]);
62 warning("expression with no effect elided\n");
63 return root1(p->kids[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 */
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:
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;
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);
90 case CVI: case CVF: case CVU: case CVP:
91 case NEG: case BCOM: case FIELD:
93 warning("expression with no effect elided\n");
94 return root1(p->kids[0]);
95 case ADDRL: case ADDRG: case ADDRF: case CNST:
99 warning("expression with no effect elided\n");
101 case ARG: case ASGN: case CALL: case JUMP: case LABEL:
113 char *opname(int op) {
114 static char *opnames[] = {
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)) : "");
176 while (ids[i].node != p)
179 ids[nid++].printed = 0;
183 /* printed - return pointer to ids[id].printed */
184 int *printed(int id) {
186 return &ids[id].printed;
191 /* printtree - print tree p on fd */
192 void printtree(Tree p, int fd) {
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;
201 static char blanks[] = " ";
203 if (p == 0 || *printed(i = nodeid(p)))
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);
208 for (i = 0; i < NELEMS(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));
217 fprint(f, " %s", p->u.sym->name);
219 fprint(f, " node=%p", p->node);
221 for (i = 0; i < NELEMS(p->kids); i++)
222 printtree1(p->kids[i], fd, lev + 1);