示例#1
0
/* subtree - construct tree for l - r */
static Tree subtree(int op, Tree l, Tree r) {
	long n;
	Type ty = inttype;

	if (isarith(l->type) && isarith(r->type)) {
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);		
	} else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
		ty = unqual(l->type);
		n = unqual(ty->type)->size;
		if (n == 0)
			error("unknown size for type `%t'\n", ty->type);
		r = cast(r, promote(r->type));
		if (n > 1)
			r = multree(MUL, cnsttree(signedptr, n), r);
		if (isunsigned(r->type))
			r = cast(r, unsignedptr);
		else
			r = cast(r, signedptr);
		return simplify(SUB+P, ty, l, r);
	} else if (compatible(l->type, r->type)) {
		ty = unqual(l->type);
		n = unqual(ty->type)->size;
		if (n == 0)
			error("unknown size for type `%t'\n", ty->type);
		l = simplify(SUB+U, unsignedptr,
			cast(l, unsignedptr), cast(r, unsignedptr));
		return simplify(DIV+I, longtype,
			cast(l, longtype), cnsttree(longtype, n));
	} else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}
示例#2
0
Tree asgntree(int op, Tree l, Tree r) {
    Type aty, ty;

    r = pointer(r);
    ty = assign(l->type, r);
    if (ty)
        r = cast(r, ty);
    else {
        typeerror(ASGN, l, r);
        if (r->type == voidtype)
            r = retype(r, inttype);
        ty = r->type;
    }
    if (l->op != FIELD)
        l = lvalue(l);
    aty = l->type;
    if (isptr(aty))
        aty = unqual(aty)->type;
    if (isconst(aty)
            || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) {
        if (isaddrop(l->op)
                && !l->u.sym->computed && !l->u.sym->generated)
            error("assignment to const identifier `%s'\n",
                  l->u.sym->name);
        else
            error("assignment to const location\n");
    }
    if (l->op == FIELD) {
        long n = 8 * l->u.field->type->size - fieldsize(l->u.field);
        if (n > 0 && isunsigned(l->u.field->type))
            r = bittree(BAND, r,
                        cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
        else if (n > 0) {
            if (r->op == CNST + I) {
                n = r->u.v.i;
                if (n & (1 << (fieldsize(l->u.field) - 1)))
                    n |= ~0UL << fieldsize(l->u.field);
                r = cnsttree(r->type, n);
            } else
                r = shtree(RSH,
                           shtree(LSH, r, cnsttree(inttype, n)),
                           cnsttree(inttype, n));
        }
    }
    if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
        return tree(RIGHT, ty,
                    tree(CALL + B, ty, r->kids[0]->kids[0], l),
                    idtree(l->u.sym));
    return tree(mkop(op, ty), ty, l, r);
}
示例#3
0
static Tree addtree(int op, Tree l, Tree r) {
	Type ty = inttype;

	if (isarith(l->type) && isarith(r->type)) {
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);		
	} else if (isptr(l->type) && isint(r->type))
		return addtree(ADD, r, l);
	else if (  isptr(r->type) && isint(l->type)
	&& !isfunc(r->type->type))
		{
			long n;
			ty = unqual(r->type);
			n = unqual(ty->type)->size;
			if (n == 0)
				error("unknown size for type `%t'\n", ty->type);
			l = cast(l, promote(l->type));
			if (n > 1)
				l = multree(MUL, cnsttree(signedptr, n), l);
			if (isunsigned(l->type))
				l = cast(l, unsignedptr);
			else
				l = cast(l, signedptr);
			if (YYcheck && !isaddrop(r->op))		/* omit */
				return nullcall(ty, YYcheck, r, l);	/* omit */
			return simplify(ADD, ty, l, r);
		}

	else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}
示例#4
0
文件: stmt.c 项目: 0culus/ioq3
static void cmp(int op, Symbol p, long n, int lab) {
	Type ty = signedint(p->type);

	listnodes(eqtree(op,
			cast(idtree(p), ty),
			cnsttree(ty, n)),
		lab, 0);
}
示例#5
0
文件: stab.c 项目: bhanug/cdb
/* call_hook - called at function calls.
If *e is a call, call_hook changes the expression to the equivalent of
the C expression

	(tos.ip = i, *e)

where i is the stopping point index for the execution point of the
expression in which the call appears.
*/
static void call_hook(void *cl, Coordinate *cp, Tree *e) {
	assert(*e);
	*e = tree(RIGHT, (*e)->type,
		asgntree(ASGN,
			field(lvalue(idtree(tos)), string("ip")),
			cnsttree(inttype, Seq_length(pickle->spoints))),
		*e);
}
示例#6
0
文件: stab.c 项目: bhanug/cdb
/* point_hook - called at each execution point */
static void point_hook(void *cl, Coordinate *cp, Tree *e) {
	Tree t;
	
	/*
	add breakpoint test to *e:
	(_Nub_bpflags[i] != 0 && _Nub_bp(i), *e)
	*/
	t = tree(AND, voidtype,
		(*optree[NEQ])(NE,
			rvalue((*optree['+'])(ADD,
				pointer(idtree(nub_bpflags)),
				cnsttree(inttype, Seq_length(pickle->spoints)))),
			cnsttree(inttype, 0L)),
		vcall(nub_bp, voidtype, cnsttree(inttype, Seq_length(pickle->spoints)), NULL));
	if (*e)
		*e = tree(RIGHT, (*e)->type, t, *e);
	else
		*e = t;
	Seq_addhi(pickle->spoints,
		  sym_spoint(sym_coordinate(cp->file ? cp->file : string(""), cp->x, cp->y), tail()));
}
示例#7
0
文件: stab.c 项目: bhanug/cdb
/* entry_hook - called an function entry */
static void entry_hook(void *cl, Symbol cfunc) {
	static int nfuncs;
	Type ty;

	/*
	Simulate the declaration of an sframe structure,
	but without the tag.
	*/
	ty = newstruct(STRUCT, "");
#define addfield(name,t) \
	ty->size = roundup(ty->size, t->align);\
	if (ty->align < t->align) ty->align = t->align; \
	newfield(string(name), ty, t)->offset = ty->size; \
	ty->size += t->size
	addfield("up",    voidptype);
	addfield("down",  voidptype);
	addfield("func",  inttype);
	addfield("module",inttype);
	addfield("ip",    inttype);     
#undef addfield
	ty->size = roundup(ty->size, ty->align);
	ty->u.sym->defined = 1;
	ty->u.sym->generated = 1;
	tos = genident(AUTO, ty, LOCAL);
	addlocal(tos);
	tos->defined = 1;
	/*
	 Generated the assignments to the shadow
	 frame fields.
	*/
#define set(name,e) walk(asgntree(ASGN,field(lvalue(idtree(tos)),string(#name)),(e)),0,0)
	set(down,       idtree(nub_tos));
	set(func,       cnsttree(inttype, symboluid(cfunc)));
	set(module,     cnsttree(inttype, uname));
#undef set
	walk(asgn(nub_tos, lvalue(idtree(tos))), 0, 0);
	foreach(identifiers, PARAM, setoffset, tos);
}
示例#8
0
Tree unary(void) {
	Tree p;

	switch (t) {
	case '*':    t = gettok(); p = unary(); p = pointer(p);
						  if (isptr(p->type)
						  && (isfunc(p->type->type) || isarray(p->type->type)))
						  	p = retype(p, p->type->type);
						  else {
						  	if (YYnull)
						  		p = nullcheck(p);
						  	p = rvalue(p);
						  } break;
	case '&':    t = gettok(); p = unary(); if (isarray(p->type) || isfunc(p->type))
						  	p = retype(p, ptr(p->type));
						  else
						  	p = lvalue(p);
						  if (isaddrop(p->op) && p->u.sym->sclass == REGISTER)
						  	error("invalid operand of unary &; `%s' is declared register\n", p->u.sym->name);

						  else if (isaddrop(p->op))
						  	p->u.sym->addressed = 1;
 break;
	case '+':    t = gettok(); p = unary(); p = pointer(p);
						  if (isarith(p->type))
						  	p = cast(p, promote(p->type));
						  else
						  	typeerror(ADD, p, NULL);  break;
	case '-':    t = gettok(); p = unary(); p = pointer(p);
						  if (isarith(p->type)) {
						  	Type ty = promote(p->type);
						  	p = cast(p, ty);
						  	if (isunsigned(ty)) {
						  		warning("unsigned operand of unary -\n");
						  		p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL));
						  	} else
						  		p = simplify(NEG, ty, p, NULL);
						  } else
						  	typeerror(SUB, p, NULL); break;
	case '~':    t = gettok(); p = unary(); p = pointer(p);
						  if (isint(p->type)) {
						  	Type ty = promote(p->type);
						  	p = simplify(BCOM, ty, cast(p, ty), NULL);
						  } else
						  	typeerror(BCOM, p, NULL);  break;
	case '!':    t = gettok(); p = unary(); p = pointer(p);
						  if (isscalar(p->type))
						  	p = simplify(NOT, inttype, cond(p), NULL);
						  else
						  	typeerror(NOT, p, NULL); break;
	case INCR:   t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break;
	case DECR:   t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break;
	case TYPECODE: case SIZEOF: { int op = t;
				      Type ty;
				      p = NULL;
				      t = gettok();
				      if (t == '(') {
				      	t = gettok();
				      	if (istypename(t, tsym)) {
				      		ty = typename();
				      		expect(')');
				      	} else {
				      		p = postfix(expr(')'));
				      		ty = p->type;
				      	}
				      } else {
示例#9
0
文件: stmt.c 项目: 0culus/ioq3
void swcode(Swtch swp, int b[], int lb, int ub) {
	int hilab, lolab, l, u, k = (lb + ub)/2;
	long *v = swp->values;

	if (k > lb && k < ub) {
		lolab = genlabel(1);
		hilab = genlabel(1);
	} else if (k > lb) {
		lolab = genlabel(1);
		hilab = swp->deflab->u.l.label;
	} else if (k < ub) {
		lolab = swp->deflab->u.l.label;
		hilab = genlabel(1);
	} else
		lolab = hilab = swp->deflab->u.l.label;
	l = b[k];
	u = b[k+1] - 1;
	if (u - l + 1 <= 3)
		{
			int i;
			for (i = l; i <= u; i++)
				cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
			if (k > lb && k < ub)
				cmp(GT, swp->sym, v[u], hilab);
			else if (k > lb)
				cmp(GT, swp->sym, v[u], hilab);
			else if (k < ub)
				cmp(LT, swp->sym, v[l], lolab);
			else
				assert(lolab == hilab),
				branch(lolab);
			walk(NULL, 0, 0);
		}
	else {
		Tree e;
		Type ty = signedint(swp->sym->type);
		Symbol table = genident(STATIC,
			array(voidptype, u - l + 1, 0), GLOBAL);
		(*IR->defsymbol)(table);
		if (!isunsigned(swp->sym->type) || v[l] != 0)
			cmp(LT, swp->sym, v[l], lolab);
		cmp(GT, swp->sym, v[u], hilab);
		e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));
		if (e->type->size < unsignedptr->size)
			e = cast(e, unsignedlong);
		walk(tree(JUMP, voidtype,
			rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),
			0, 0);
		code(Switch);
		codelist->u.swtch.table = table;
		codelist->u.swtch.sym = swp->sym;
		codelist->u.swtch.deflab = swp->deflab;
		codelist->u.swtch.size = u - l + 1;
		codelist->u.swtch.values = &v[l];
		codelist->u.swtch.labels = &swp->labels[l];
		if (v[u] - v[l] + 1 >= 10000)
			warning("switch generates a huge table\n");
	}
	if (k > lb) {
		assert(lolab != swp->deflab->u.l.label);
		definelab(lolab);
		swcode(swp, b, lb, k - 1);
	}
	if (k < ub) {
		assert(hilab != swp->deflab->u.l.label);
		definelab(hilab);
		swcode(swp, b, k + 1, ub);
	}
}
示例#10
0
Tree consttree(unsigned n, Type ty) {
	if (isarray(ty))
		ty = atop(ty);
	else assert(isint(ty));
	return cnsttree(ty, (unsigned long)n);
}
示例#11
0
文件: stmt.c 项目: HanumathRao/lcc
void statement(int loop, Swtch swp, int lev) {
	float ref = refinc;

	if (Aflag >= 2 && lev == 15)
		warning("more than 15 levels of nested statements\n");
	switch (t) {
	case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
 break;
	case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
	case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
					break;

	case FOR:      forstmt(genlabel(4), swp, lev + 1);
 break;
	case BREAK:    walk(NULL, 0, 0);
		       definept(NULL);
		       if (swp && swp->lab > loop)
		       	branch(swp->lab + 1);
		       else if (loop)
		       	branch(loop + 2);
		       else
		       	error("illegal break statement\n");
		       t = gettok(); expect(';');
					   break;

	case CONTINUE: walk(NULL, 0, 0);
		       definept(NULL);
		       if (loop)
		       	branch(loop + 1);
		       else
		       	error("illegal continue statement\n");
		       t = gettok(); expect(';');
					      break;

	case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
 break;
	case CASE:     {
		       	int lab = genlabel(1);
		       	if (swp == NULL)
		       		error("illegal case label\n");
		       	definelab(lab);
		       	while (t == CASE) {
		       		static char stop[] = { IF, ID, 0 };
		       		Tree p;
		       		t = gettok();
		       		p = constexpr(0);
		       		if (generic(p->op) == CNST && isint(p->type)) {
		       			if (swp) {
		       				needconst++;
		       				p = cast(p, swp->sym->type);
		       				if (p->type->op == UNSIGNED)
		       					p->u.v.i = extend(p->u.v.u, p->type);
		       				needconst--;
		       				caselabel(swp, p->u.v.i, lab);
		       			}
		       		} else
		       			error("case label must be a constant integer expression\n");

		       		test(':', stop);
		       	}
		       	statement(loop, swp, lev);
		       } break;
	case DEFAULT:  if (swp == NULL)
		       	error("illegal default label\n");
		       else if (swp->deflab)
		       	error("extra default label\n");
		       else {
		       	swp->deflab = findlabel(swp->lab);
		       	definelab(swp->deflab->u.l.label);
		       }
		       t = gettok();
		       expect(':');
		       statement(loop, swp, lev); break;
	case RETURN:   {
		       	Type rty = freturn(cfunc->type);
		       	t = gettok();
		       	definept(NULL);
		       	if (t != ';')
		       		if (rty == voidtype) {
		       			error("extraneous return value\n");
		       			expr(0);
		       			retcode(NULL);
		       		} else
		       			retcode(expr(0));
		       	else {
		       		if (rty != voidtype) {
		       			warning("missing return value\n");
		       			retcode(cnsttree(inttype, 0L));
		       		} else
		       			retcode(NULL);
		       	}
		       	branch(cfunc->u.f.label);
		       } expect(';');
					    break;

	case '{':      compound(loop, swp, lev + 1); break;
	case ';':      definept(NULL); t = gettok(); break;
	case GOTO:     walk(NULL, 0, 0);
		       definept(NULL);
		       t = gettok();
		       if (t == ID) {
		       	Symbol p = lookup(token, stmtlabs);
		       	if (p == NULL) {
				p = install(token, &stmtlabs, 0, FUNC);
				p->scope = LABELS;
				p->u.l.label = genlabel(1);
				p->src = src;
			}
		       	use(p, src);
		       	branch(p->u.l.label);
		       	t = gettok();
		       } else
		       	error("missing label in goto\n"); expect(';');
					  break;

	case ID:       if (getchr() == ':') {
		       	stmtlabel();
		       	statement(loop, swp, lev);
		       	break;
		       }
	default:       definept(NULL);
		       if (kind[t] != ID) {
		       	error("unrecognized statement\n");
		       	t = gettok();
		       } else {
		       	Tree e = expr0(0);
		       	listnodes(e, 0, 0);
		       	if (nodecount == 0 || nodecount > 200)
		       		walk(NULL, 0, 0);
		       	else if (glevel) walk(NULL, 0, 0);
		       	deallocate(STMT);
		       } expect(';');
						break;

	}
	if (kind[t] != IF && kind[t] != ID
	&& t != '}' && t != EOI) {
		static char stop[] = { IF, ID, '}', 0 };
		error("illegal statement termination\n");
		skipto(0, stop);
	}
	refinc = ref;
}