Beispiel #1
0
static Node *
comparecomplex(Flattenctx *s, Node *n, Op op)
{
	Type *ty;
	Node *l, *r, *e;

	/* special case: unions with nullary constructors can be compared easily. */
	ty = tybase(exprtype(n->expr.args[0]));
	if (ty->type == Tyunion && isenum(ty)) {
		l = mkexpr(n->loc, Outag, rval(s, n->expr.args[0]), NULL);
		r = mkexpr(n->loc, Outag, rval(s, n->expr.args[1]), NULL);
		l->expr.type = mktype(n->loc, Tyuint32);
		r->expr.type = mktype(n->loc, Tyuint32);
		if (op == Oeq)
			e = mkexpr(n->loc, Oueq, l, r, NULL);
		else if (op == One)
			e = mkexpr(n->loc, Oune, l, r, NULL);
		else
			fatal(n, "unsupported operator %s for enum union", opstr[op]);
		e->expr.type = mktype(n->loc, Tybool);
		return e;
	}
	fatal(n, "cannot compare values of type %s for equality\n",
	    tystr(exprtype(n->expr.args[0])));
	return NULL;
}
Beispiel #2
0
/* dbxout - output .stabs entry for type ty */
static void dbxout(Type ty) {
	ty = unqual(ty);
	if (!ty->x.printed) {
		int col = 0;
		print(".stabs \""), col += 8;
		if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty)))
			print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name);
		print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2;
		emittype(ty, 0, col);
		print("\",%d,0,0,0\n", N_LSYM);
	}
}
Beispiel #3
0
Type assign(Type xty, Tree e) {
	Type yty = unqual(e->type);

	xty = unqual(xty);
	if (isenum(xty))
		xty = xty->type;
	if (xty->size == 0 || yty->size == 0)
		return NULL;
	if ( isarith(xty) && isarith(yty)
	||  isstruct(xty) && xty == yty)
		return xty;
	if (isptr(xty) && isnullptr(e))
		return xty;
	if ((isvoidptr(xty) && isptr(yty)
	  || isptr(xty)     && isvoidptr(yty))
	&& (  (isconst(xty->type)    || !isconst(yty->type))
	   && (isvolatile(xty->type) || !isvolatile(yty->type))))
		return xty;

	if ((isptr(xty) && isptr(yty)
	    && eqtype(unqual(xty->type), unqual(yty->type), 1))
	&&  (  (isconst(xty->type)    || !isconst(yty->type))
	    && (isvolatile(xty->type) || !isvolatile(yty->type))))
		return xty;
	if (isptr(xty) && isptr(yty)
	&& (  (isconst(xty->type)    || !isconst(yty->type))
	   && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
		Type lty = unqual(xty->type), rty = unqual(yty->type);
		if (isenum(lty) && rty == inttype
		||  isenum(rty) && lty == inttype) {
			if (Aflag >= 1)
				warning("assignment between `%t' and `%t' is compiler-dependent\n",
					xty, yty);
			return xty;
		}
	}
	return NULL;
}
Beispiel #4
0
Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
	Tree p;

	if (args)
		f = tree(RIGHT, f->type, args, f);
	if (isstruct(ty))
		assert(t3),
		p = tree(RIGHT, ty,
			tree(CALL+B, ty, f, addrof(idtree(t3))),
			idtree(t3));
	else {
		Type rty = ty;
		if (isenum(ty))
			rty = unqual(ty)->type;
		if (!isfloat(rty))
			rty = promote(rty);
		p = tree(mkop(CALL, rty), rty, f, NULL);
		if (isptr(ty) || p->type->size > ty->size)
			p = cast(p, ty);
	}
	return p;
}
Beispiel #5
0
Tree call(Tree f, Type fty, Coordinate src) {
	int n = 0;
	Tree args = NULL, r = NULL, e;
	Type *proto, rty = unqual(freturn(fty));
	Symbol t3 = NULL;

	if (fty->u.f.oldstyle)
		proto = NULL;
	else
		proto = fty->u.f.proto;
	if (hascall(f))
		r = f;
	if (isstruct(rty))
		{
			t3 = temporary(AUTO, unqual(rty));
			if (rty->size == 0)
				error("illegal use of incomplete type `%t'\n", rty);
		}
	if (t != ')')
		for (;;) {
			Tree q = pointer(expr1(0));
			if (proto && *proto && *proto != voidtype)
				{
					Type aty;
					q = value(q);
					aty = assign(*proto, q);
					if (aty)
						q = cast(q, aty);
					else
						error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),

							q->type, *proto);
					if ((isint(q->type) || isenum(q->type))
					&& q->type->size != inttype->size)
						q = cast(q, promote(q->type));
					++proto;
				}
			else
				{
					if (!fty->u.f.oldstyle && *proto == NULL)
						error("too many arguments to %s\n", funcname(f));
					q = value(q);
					if (isarray(q->type) || q->type->size == 0)
						error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);

					else
						q = cast(q, promote(q->type));
				}
			if (!IR->wants_argb && isstruct(q->type))
				if (iscallb(q))
					q = addrof(q);
				else {
					Symbol t1 = temporary(AUTO, unqual(q->type));
					q = asgn(t1, q);
					q = tree(RIGHT, ptr(t1->type),
						root(q), lvalue(idtree(t1)));
				}
			if (q->type->size == 0)
				q->type = inttype;
			if (hascall(q))
				r = r ? tree(RIGHT, voidtype, r, q) : q;
			args = tree(mkop(ARG, q->type), q->type, q, args);
			n++;
			if (Aflag >= 2 && n == 32)
				warning("more than 31 arguments in a call to %s\n",
					funcname(f));
			if (t != ',')
				break;
			t = gettok();
		}
	expect(')');
	if (proto && *proto && *proto != voidtype)
		error("insufficient number of arguments to %s\n",
			funcname(f));
	if (r)
		args = tree(RIGHT, voidtype, r, args);
	e = calltree(f, rty, args, t3);
	if (events.calls)
		apply(events.calls, &src, &e);
	return e;
}
Beispiel #6
0
static struct vector *decls(declfun_p * dcl)
{
    struct vector *v = vec_new();
    node_t *basety;
    int sclass, fspec;
    int level = SCOPE;
    int follow[] = {STATIC, INT, CONST, IF, '}', 0};

    basety = specifiers(&sclass, &fspec);
    if (token->id == ID || token->id == '*' || token->id == '(') {
        struct token *id = NULL;
        node_t *ty = NULL;
        int params = 0;        // for functioness

        // declarator
        if (level == GLOBAL)
            declarator(&ty, &id, &params);
        else
            declarator(&ty, &id, NULL);
        attach_type(&ty, basety);

        if (level == GLOBAL && params) {
            if (first_funcdef(ty)) {
                vec_push(v, funcdef(id, ty, sclass, fspec));
                return v;
            } else {
                exit_params();
            }
        }

        for (;;) {
            if (id) {
                int kind;
                if (dcl == globaldecl)
                    kind = GLOBAL;
                else if (dcl == paramdecl)
                    kind = PARAM;
                else
                    kind = LOCAL;
                node_t *decl = make_decl(id, ty, sclass, fspec, dcl);
                if (token->id == '=')
                    decl_initializer(decl, sclass, kind);
                ensure_decl(decl, sclass, kind);
                vec_push(v, decl);
            }

            if (token->id != ',')
                break;

            expect(',');
            id = NULL;
            ty = NULL;
            // declarator
            declarator(&ty, &id, NULL);
            attach_type(&ty, basety);
        }
    } else if (isenum(basety) || isstruct(basety) || isunion(basety)) {
        // struct/union/enum
        int node_id;
        node_t *decl;
        if (isstruct(basety))
            node_id = STRUCT_DECL;
        else if (isunion(basety))
            node_id = UNION_DECL;
        else
            node_id = ENUM_DECL;

        decl = ast_decl(node_id);
        DECL_SYM(decl) = TYPE_TSYM(basety);
        vec_push(v, decl);
    } else {
        error("invalid token '%s' in declaration", token->name);
    }
    match(';', follow);

    return v;
}