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);