Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

tree.c (5133B)


      1 #include "c.h"
      2 
      3 
      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 */
     11 
     12 static void printtree1(Tree, int, int);
     13 
     14 Tree tree(int op, Type type, Tree left, Tree right) {
     15 	Tree p;
     16 
     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;
     23 }
     24 
     25 Tree texpr(Tree (*f)(int), int tok, int a) {
     26 	int save = where;
     27 	Tree p;
     28 
     29 	where = a;
     30 	p = (*f)(tok);
     31 	where = save;
     32 	return p;
     33 }
     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;
    106 }
    107 
    108 Tree root(Tree p) {
    109 	warn = 0;
    110 	return root1(p);
    111 }
    112 
    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 	};
    163 
    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)) : "");
    170 }
    171 
    172 int nodeid(Tree p) {
    173 	int i = 1;
    174 
    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;
    181 }
    182 
    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;
    189 }
    190 
    191 /* printtree - print tree p on fd */
    192 void printtree(Tree p, int fd) {
    193 	(void)printed(0);
    194 	printtree1(p, fd, 1);
    195 }
    196 
    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[] = "                                                   ";
    202 
    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);
    223 }