/* tracefinis - complete & generate the trace call to print */ static void tracefinis(Symbol printer) { Tree *ap; Symbol p; *fp = 0; p = mkstr(string(fmt)); for (ap = &args; *ap; ap = &(*ap)->kids[1]) ; *ap = tree(ARG+P, charptype, pointer(idtree(p->u.c.loc)), 0); walk(calltree(pointer(idtree(printer)), freturn(printer->type), args, NULL), 0, 0); args = 0; fp = fmtend = 0; }
Tree vcall(Symbol func, Type ty, ...) { va_list ap; Tree args = NULL, e, f = pointer(idtree(func)), r = NULL; assert(isfunc(func->type)); if (ty == NULL) ty = freturn(func->type); va_start(ap, ty); while ((e = va_arg(ap, Tree)) != NULL) { if (hascall(e)) r = r == NULL ? e : tree(RIGHT, voidtype, r, e); args = tree(mkop(ARG, e->type), e->type, e, args); } va_end(ap); if (r != NULL) args = tree(RIGHT, voidtype, r, args); return calltree(f, ty, args, NULL); }
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; }