int
isfunct(Node *n)
{
Type *t, *t1;
Funct *f;
Node *l;
Sym *s;
int o;
o = n->op;
if(n->left == Z)
goto no;
t = n->left->type;
if(t == T)
goto no;
f = t->funct;
switch(o) {
case OAS: // put cast on rhs
case OASI:
case OASADD:
case OASAND:
case OASASHL:
case OASASHR:
case OASDIV:
case OASLDIV:
case OASLMOD:
case OASLMUL:
case OASLSHR:
case OASMOD:
case OASMUL:
case OASOR:
case OASSUB:
case OASXOR:
if(n->right == Z)
goto no;
t1 = n->right->type;
if(t1 == T)
goto no;
if(t1->funct == f)
break;
/*
* the answer is yes,
* now we rewrite the node
* and give diagnostics
*/
switch(o) {
default:
diag(n, "isfunct op missing %O\n", o);
goto bad;
case OADD: // T f(T, T)
case OAND:
case OASHL:
case OASHR:
case ODIV:
case OLDIV:
case OLMOD:
case OLMUL:
case OLSHR:
case OMOD:
case OMUL:
case OOR:
case OSUB:
case OXOR:
case OEQ: // int f(T, T)
case OGE:
case OGT:
case OHI:
case OHS:
case OLE:
case OLO:
case OLS:
case OLT:
case ONE:
if(n->right == Z)
goto bad;
t1 = n->right->type;
if(t1 == T)
goto bad;
if(t1->funct != f)
goto bad;
n->right = new(OLIST, n->left, n->right);
break;
case OAS: // structure copies done by the compiler
case OASI:
goto no;
case OASADD: // T f(T*, T)
case OASAND:
case OASASHL:
case OASASHR:
case OASDIV:
case OASLDIV:
case OASLMOD:
case OASLMUL:
case OASLSHR:
case OASMOD:
case OASMUL:
case OASOR:
case OASSUB:
case OASXOR:
if(n->right == Z)
goto bad;
t1 = n->right->type;
if(t1 == T)
goto bad;
if(t1->funct != f)
goto bad;
n->right = new(OLIST, new(OADDR, n->left, Z), n->right);
break;
case OPOS: // T f(T)
case ONEG:
case ONOT:
case OCOM:
n->right = n->left;
break;