Beispiel #1
0
// CHECK-LABEL: @test1
int test1(int *a, int i) {
// CHECK: store i32* %a, i32** [[A_ADDR:%.+]], align
// CHECK: [[A:%.+]] = load i32*, i32** [[A_ADDR]]
// CHECK: [[CMP:%.+]] = icmp ne i32* [[A]], null
// CHECK: call void @llvm.assume(i1 [[CMP]])

// CHECK: [[CALL:%.+]] = call i32 @isconst()
// CHECK: [[BOOL:%.+]] = icmp ne i32 [[CALL]], 0
// CHECK: call void @llvm.assume(i1 [[BOOL]])

// CHECK: [[CALLPURE:%.+]] = call i32 @ispure()
// CHECK: [[BOOLPURE:%.+]] = icmp ne i32 [[CALLPURE]], 0
// CHECK: call void @llvm.assume(i1 [[BOOLPURE]])
#ifdef _MSC_VER
  __assume(a != 0)
  __assume(isconst());
  __assume(ispure());
#else
  __builtin_assume(a != 0);
  __builtin_assume(isconst());
  __builtin_assume(ispure());
#endif

// Nothing is generated for an assume with side effects...
// CHECK-NOT: load i32*, i32** %i.addr
// CHECK-NOT: call void @llvm.assume
// CHECK-NOT: call i32 @nonconst()
#ifdef _MSC_VER
  __assume(++i != 0)
  __assume(nonconst());
#else
  __builtin_assume(++i != 0);
  __builtin_assume(nonconst());
#endif

  return a[0];
}
Beispiel #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);
}
Beispiel #3
0
static TYPE *enumConst(char *buf, TYPE *tp)
{
    while (isconst(tp) || isvolatile(tp) || isrestrict(tp))
    {
        switch(tp->type)
        {
            case bt_const:
                strcat(buf, tn_const);
                break;
            case bt_volatile:
                strcat(buf, tn_volatile);
                break;
            case bt_restrict:
/*				strcat(buf, tn_restrict); */
                break;
        }
        tp = tp->btp;
    }
    return tp;
}
Beispiel #4
0
ExtArray ExtArray::deriv(value_t dt) const
{
    if (isconst()) return const_array(0.0);
    if (data_size_ == 1) {
        const value_t dx = (last_ - data_.get()[0]) / (2 * dt);
        value_t* x = new value_t[2];
        x[0] = dx;   /* left and right finite differences */
        x[1] = dx;
        return ExtArray(shared_owner(x), 0.0, 2);
    } else {
        const value_t dt2 = 2 * dt;
        value_t* x = new value_t[data_size_ + 1];
        /* left/right finite difference for edges, otherwise central diff */
        x[0] = (data_.get()[1] - data_.get()[0]) / dt;
        for (size_t i = 1; i < data_size_-1; ++i)
            x[i] = (data_.get()[i + 1] - data_.get()[i - 1]) / dt2;
        if (data_size_ >= 3)
            x[data_size_ - 1] = (last_ - data_.get()[data_size_ - 2]) / dt2;
        x[data_size_] = (last_ - data_.get()[data_size_-1]) / dt;
        return ExtArray(shared_owner(x), 0.0, data_size_ + 1);
    }
}
Beispiel #5
0
void EiC_showvalue(AR_t * arg)
{
    int t;

    if(!EiC_interActive || !arg->type)
	return ;

    fputc('\t', stdout);

    t = EiC_gettype(arg->type);

    if(isconst(arg->type) && t != t_pointer) {
	outputval(t, &arg->v);
	fputc('\n', stdout);
	return;
    }
    	
    switch ((t = EiC_gettype(arg->type))) {
      case t_union:  fputs("(Union)",stdout); break;
      case t_struct: showstruct(arg); break;
      case t_char:   case t_uchar:  case t_short:  
      case t_ushort: outputval(t_int, &arg->v.ival); break;
      case t_float:  outputval(t_double, &arg->v.ival); break;
      case t_array:
      case t_pointer:
	if (EiC_gettype(nextType(arg->type)) == t_char)
	    t = STR;
	else
	    t = t_pointer;
      default:
	outputval(t, &arg->v);
	break;
    }
    fputc('\n', stdout);

}
Beispiel #6
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 #7
0
Datei: swt.c Projekt: 8l/go
/*
 * normal (expression) switch.
 * rebulid case statements into if .. goto
 */
static void
exprswitch(Node *sw)
{
	Node *def;
	NodeList *cas;
	Node *a;
	Case *c0, *c, *c1;
	Type *t;
	int arg, ncase;

	casebody(sw, N);

	arg = Snorm;
	if(isconst(sw->ntest, CTBOOL)) {
		arg = Strue;
		if(sw->ntest->val.u.bval == 0)
			arg = Sfalse;
	}
	walkexpr(&sw->ntest, &sw->ninit);
	t = sw->type;
	if(t == T)
		return;

	/*
	 * convert the switch into OIF statements
	 */
	exprname = N;
	cas = nil;
	if(arg != Strue && arg != Sfalse) {
		exprname = temp(sw->ntest->type);
		cas = list1(nod(OAS, exprname, sw->ntest));
		typechecklist(cas, Etop);
	} else {
		exprname = nodbool(arg == Strue);
	}

	c0 = mkcaselist(sw, arg);
	if(c0 != C && c0->type == Tdefault) {
		def = c0->node->right;
		c0 = c0->link;
	} else {
		def = nod(OBREAK, N, N);
	}

loop:
	if(c0 == C) {
		cas = list(cas, def);
		sw->nbody = concat(cas, sw->nbody);
		sw->list = nil;
		walkstmtlist(sw->nbody);
		return;
	}

	// deal with the variables one-at-a-time
	if(!okforcmp[t->etype] || c0->type != Texprconst) {
		a = exprbsw(c0, 1, arg);
		cas = list(cas, a);
		c0 = c0->link;
		goto loop;
	}

	// do binary search on run of constants
	ncase = 1;
	for(c=c0; c->link!=C; c=c->link) {
		if(c->link->type != Texprconst)
			break;
		ncase++;
	}

	// break the chain at the count
	c1 = c->link;
	c->link = C;

	// sort and compile constants
	c0 = csort(c0, exprcmp);
	a = exprbsw(c0, ncase, arg);
	cas = list(cas, a);

	c0 = c1;
	goto loop;

}
Beispiel #8
0
BOOL comparetypes(TYPE *typ1, TYPE *typ2, int exact)
{
    if (typ1->type == bt_any || typ2->type == bt_any)
        return TRUE;
    if (typ1->type == bt_typedef)
        typ1 = basetype(typ1);
    if (typ2->type == bt_typedef)
        typ2 = basetype(typ2);
    if (isref(typ1))
        typ1 = basetype(typ1)->btp;
    if (isref(typ2))
        typ2 = basetype(typ2)->btp;
    if (ispointer(typ1) && ispointer(typ2))
        if (exact)
        {
            int arr = FALSE;
            int first = TRUE;
            while (ispointer(typ1) && ispointer(typ2))
            {
                if (!first && (exact == 1))
                    if (isconst(typ2) && !isconst(typ1) || isvolatile(typ2) && !isvolatile(typ1))
                        return FALSE;
                first = FALSE;
                typ1 = basetype(typ1);
                typ2 = basetype(typ2);
                if (typ1->type != typ2->type)
                    return FALSE;
                if (arr && typ1->array != typ2->array)	
                    return FALSE;
                if (arr && typ1->size != typ2->size)
                    return FALSE;
                arr |= typ1->array | typ2->array;
                typ1 = typ1->btp;
                typ2 = typ2->btp;				
            }
            if ((exact == 1) && (isconst(typ2) && !isconst(typ1) || isvolatile(typ2) && !isvolatile(typ1)))
                return FALSE;
            return comparetypes(typ1, typ2, TRUE);
        }
            
        else
            return TRUE;
    
    typ1 = basetype(typ1);
    typ2 = basetype(typ2);
    if (exact && (isfunction(typ1) || isfuncptr(typ1)) && (isfunction(typ2) || isfuncptr(typ2)))
    {
        HASHREC *hr1;
        HASHREC *hr2;
        typ1 = basetype(typ1);
        typ2 = basetype(typ2);
        if (ispointer(typ1))
            typ1 = basetype(typ1->btp);
        if (ispointer(typ2))
            typ2 = basetype(typ2->btp);
        if (!comparetypes(typ1->btp, typ2->btp, exact))
            return FALSE;
        hr1 = typ1->syms->table[0];
        hr2 = typ2->syms->table[0];
        while (hr1 && hr2)
        {
            SYMBOL *sp1 = (SYMBOL *)hr1->p;
            SYMBOL *sp2 = (SYMBOL *)hr2->p;
            if (!comparetypes(sp1->tp, sp2->tp, exact))
                return FALSE;
            hr1 = hr1->next;
            hr2 = hr2->next;
        }
        if (hr1 || hr2)
            return FALSE;
        return TRUE;
    }
    if (cparams.prm_cplusplus)
    {
        if (typ1->scoped != typ2->scoped)
            return FALSE;
        if (typ1->type == bt_enum)
        {
            if (typ2->type == bt_enum)
                return typ1->sp == typ2->sp;
            else
                return isint(typ2);
        }
        else if (typ2->type == bt_enum)
        {
            return isint(typ1);
        }
        if (typ1->type == typ2->type && typ1->type == bt_memberptr)
        {
            if (typ1->sp != typ2->sp)
            {
                if (classRefCount(typ2->sp, typ1->sp) != 1)
                    return FALSE;
            }
            return comparetypes(typ1->btp, typ2->btp, exact);
        }
    }
    if (typ1->type == typ2->type && (isstructured(typ1) || exact && typ1->type == bt_enum))
        return typ1->sp == typ2->sp;
    if (typ1->type == typ2->type || !exact && isarithmetic(typ2) && isarithmetic(typ1))
        return TRUE;
    if (isfunction(typ1) && isfunction(typ2) && 
        typ1->sp->linkage == typ2->sp->linkage)
        return TRUE;
    else if (!exact && (ispointer(typ1) && (isfuncptr(typ2) || isfunction(typ2) || isint(typ2))
             || ispointer(typ2) && (isfuncptr(typ1) || isfunction(typ1) || isint(typ1))))
            return (TRUE);
    else if (typ1->type == bt_enum && isint(typ2))
    {
        return TRUE;
    }
    else if (typ2->type == bt_enum && isint(typ1))
    {
        return TRUE;
    }
    return FALSE;
}
Beispiel #9
0
/* List a variable */
void list_var(SYMBOL *sp, int i)
{
    int j;
    long val;
    if (!cparams.prm_listfile)
        return ;
    if (sp->dontlist)
        return;
    if (sp->tp->type == bt_aggregate)
    {
        HASHREC *hr = sp->tp->syms->table[0];
        while (hr)
        {
            sp = (SYMBOL *)hr->p;
            list_var(sp, 0);
            hr = hr->next;
        }
        return ;
    }
    for (j = i; j; --j)
        fprintf(listFile, "    ");
    if (sp->storage_class == sc_auto && !sp->regmode)
        val = (long)getautoval(sp->offset);
    else
        val = sp->value.u;
    fprintf(listFile,"Identifier:   %s\n    ", unmangledname(sp->name));
    for (j = i; j; --j)
        fprintf(listFile, "    ");
    if (sp->regmode == 1) {
        fprintf(listFile,"Register: %-3s&     ",lookupRegName((-sp->offset) & 255));
    }
    else if (sp->regmode == 2) {
        fprintf(listFile,"Register: %-3s      ",lookupRegName((-sp->offset) & 255));
    }
    else
        fprintf(listFile,"Offset:   %08lX ", val);
    fprintf(listFile,"Storage: ");
    if (sp->tp->type == bt_ifunc)
        if (sp->isInline && !sp->noinline)
            fprintf(listFile,"%-7s","inline");
        else
            fprintf(listFile,"%-7s","code");
    else if (sp->storage_class == sc_auto)
        if (sp->regmode)
            fprintf(listFile,"%-7s","reg");
        else
            fprintf(listFile,"%-7s","stack");
    else if (sp->storage_class == sc_global || sp->storage_class == sc_static 
             || sp->storage_class == sc_localstatic)
        if (isconst(sp->tp))
            fprintf(listFile,"%-7s","const");
        else if (sp->init)
            fprintf(listFile,"%-7s","data");
        else
            fprintf(listFile,"%-7s","bss");
    else if (sp->storage_class == sc_constant || sp->storage_class == sc_enumconstant)
        fprintf(listFile,"%-7s","constant");
    else
        fprintf(listFile,"%-7s","none");
    put_sc(sp->storage_class);
    put_ty(sp->tp);
    fprintf(listFile, "\n");
    if (sp->tp == 0)
        return ;
    if (isstructured(sp->tp) && sp->storage_class == sc_type)
        list_table(sp->tp->syms, i + 1);
}
Beispiel #10
0
/*
 * emittype - emit ty's type number, emitting its definition if necessary.
 * Returns the output column number after emission; col is the approximate
 * output column before emission and is used to emit continuation lines for long
 * struct, union, and enum types. Continuations are not emitted for other types,
 * even if the definition is long. lev is the depth of calls to emittype.
 */
static int emittype(Type ty, int lev, int col) {
	int tc = ty->x.typeno;

	if (isconst(ty) || isvolatile(ty)) {
		col = emittype(ty->type, lev, col);
		ty->x.typeno = ty->type->x.typeno;
		ty->x.printed = 1;
		return col;
	}
	if (tc == 0) {
		ty->x.typeno = tc = ++ntypes;
/*              fprint(2,"`%t'=%d\n", ty, tc); */
	}
	print("%d", tc), col += 3;
	if (ty->x.printed)
		return col;
	ty->x.printed = 1;
	switch (ty->op) {
	case VOID:	/* void is defined as itself */
		print("=%d", tc), col += 1+3;
		break;
	case INT:
		if (ty == chartype)	/* plain char is a subrange of itself */
			print("=r%d;%d;%d;", tc, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
				col += 2+3+2*2.408*ty->size+2;
		else			/* other signed ints are subranges of int */
			print("=r1;%D;%D;", ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
				col += 4+2*2.408*ty->size+2;
		break;
	case UNSIGNED:
		if (ty == chartype)	/* plain char is a subrange of itself */
			print("=r%d;0;%u;", tc, ty->u.sym->u.limits.max.i),
				col += 2+3+2+2.408*ty->size+1;
		else			/* other signed ints are subranges of int */
			print("=r1;0;%U;", ty->u.sym->u.limits.max.i),
				col += 4+2.408*ty->size+1;
		break;
	case FLOAT:	/* float, double, long double get sizes, not ranges */
		print("=r1;%d;0;", ty->size), col += 4+1+3;
		break;
	case POINTER:
		print("=*"), col += 2;
		col = emittype(ty->type, lev + 1, col);
		break;
	case FUNCTION:
		print("=f"), col += 2;
		col = emittype(ty->type, lev + 1, col);
		break;
	case ARRAY:	/* array includes subscript as an int range */
		if (ty->size && ty->type->size)
			print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1;
		else
			print("=ar1;0;-1;"), col += 10;
		col = emittype(ty->type, lev + 1, col);
		break;
	case STRUCT: case UNION: {
		Field p;
		if (!ty->u.sym->defined) {
			print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name);
			col += 2+1+strlen(ty->u.sym->name)+1;
			break;
		}
		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
			ty->x.printed = 0;
			break;
		}
		print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3;
		for (p = fieldlist(ty); p; p = p->link) {
			if (p->name)
				print("%s:", p->name), col += strlen(p->name)+1;
			else
				print(":"), col += 1;
			col = emittype(p->type, lev + 1, col);
			if (p->lsb)
				print(",%d,%d;", 8*p->offset +
					(IR->little_endian ? fieldright(p) : fieldleft(p)),
					fieldsize(p));
			else
				print(",%d,%d;", 8*p->offset, 8*p->type->size);
			col += 1+3+1+3+1;	/* accounts for ,%d,%d; */
			if (col >= 80 && p->link) {
				print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
				col = 8;
			}
		}
		print(";"), col += 1;
		break;
		}
	case ENUM: {
		Symbol *p;
		if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
			ty->x.printed = 0;
			break;
		}
		print("=e"), col += 2;
		for (p = ty->u.sym->u.idlist; *p; p++) {
			print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3;
			if (col >= 80 && p[1]) {
				print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
				col = 8;
			}
		}
		print(";"), col += 1;
		break;
		}
	default:
		assert(0);
	}
	return col;
}
Beispiel #11
0
static void EiC_showdectype(type_expr * t, int expand, FILE *fp)
{

    struct_t *S;
    int i;
    static int level = 0;

    while (t) {
	if(isconst(t) || isconstp(t))
	    fputs("const ",fp);
	
	switch (EiC_gettype(t)) {
	  case t_var:   fputs("...", fp); break;
	  case t_enum:  fputs("enum ", fp); break;
	  case t_char:  fputs("char ", fp); break;
	  case t_uchar: fputs("unsigned char ", fp); break;
	  case t_short: fputs("short ", fp); break;
	  case t_ushort:fputs("unsigned short ", fp); break;
	  case t_int:   fputs("int ", fp); break;
	  case t_uint:  fputs("unsigned ", fp); break;
	  case t_long:  fputs("long int ", fp); break;
	  case t_ulong: fputs("unsigned long int ", fp); break;
	  case t_llong: fputs("long long ",fp); break;
	  case t_float: fputs("float ", fp); break;
	  case t_double:fputs("double ", fp); break;
	  case t_pointer: 

	    if(isunsafe(t)) 
	      fputs("unsafe ", fp);
	    /*else if(issafe(t)) 
	      fputs("safe ", fp);*/

	    fputs("* ", fp); 
	    break;

	  case t_void:  fputs("void ", fp); break;
	  case t_hidden: fputs("hidden ",fp); break;
	    
	  case t_funcdec: fputs("dec_", fp); showFunc(&t,fp); break;
	  case t_func:   showFunc(&t,fp); break;
	  case t_builtin: fputs("Builtin ",fp); showFunc(&t,fp); break; 

	  case t_array:
	    fprintf(fp,"ARY[%d]",(int) EiC_getInf(t));
	    break;
	  case t_union:
	  case t_struct:
	    S = EiC_getInf(t);
	    if(!S) {
		fputs("Incomplete", fp);
		break;
	    }
	    if (EiC_gettype(t) == t_struct)
		fprintf(fp,"struct: size  %u bytes",S->tsize);
	    else
		fprintf(fp,"union: size  %u bytes",S->tsize);
	    if (expand) {
		level++;
		fputc('\n', fp);
		if (level <= 2) {
		    int j;
		    for (i = 0; i < S->n; i++) {
			for (j = 0; j < level; j++)
			    fputc('\t', fp);
			fputs(S->id[i], fp);
			fputs(" -> ", fp);
			EiC_showdectype(S->type[i], expand,fp);
			fputc('\n', fp);
		    }
		}
		level--;
	    }
	    break;
	  case t_ref: fputs("Reference ",fp);break;
	  case ID: fputs("Identifier ", fp); break;
	  default: fputs("Uknown identifier", fp); return;
	}
	t = nextType(t);
    }
}
Beispiel #12
0
char *mangleType (char *in, TYPE *tp, BOOLEAN first)
{
    char nm[4096];
    int i;
    HASHREC *hr ;
    if(!tp)
    {
        sprintf(in, "%d%s", strlen("initializer-list"), "initializer-list");
        in += strlen(in);
    }
    else if (tp->type == bt_typedef)
    {
       in = mangleType(in, tp->btp, FALSE);
    }
    else if (isstructured(tp) && basetype(tp)->sp->templateLevel)
    {
        {
            if (isconst(tp))
                *in++ = 'x';
            if (isvolatile(tp))
                *in++ = 'y';
            if (islrqual(tp))
                *in++ = 'r';
            if (isrrqual(tp))
                *in++ = 'R';
        }
        in = mangleTemplate(in, basetype(tp)->sp, basetype(tp)->sp->templateParams);
    }
    else
    {
//        if (ispointer(tp) || isref(tp))
//        {
//            if (basetype(tp)->btp)
//            {
//                if (isconst(basetype(tp)->btp))
//                    *in++ = 'x';
//                if (isvolatile(basetype(tp)->btp))
//                    *in++ = 'y';
//            }
//        }
//        if (isfunction(tp))
        {
            if (isconst(tp))
                *in++ = 'x';
            if (isvolatile(tp))
                *in++ = 'y';
            if (islrqual(tp))
                *in++ = 'r';
            if (isrrqual(tp))
                *in++ = 'R';
        }
        tp = basetype(tp);
        switch (tp->type)
        {
        /*
            case bt_templateplaceholder:
                tplPlaceholder(nm, tp->lst.head->name, tp->lst.tail);
                sprintf(buf, "%d%s", strlen(nm), nm);
                buf += strlen(buf);
                break;
        */
            case bt_func:
            case bt_ifunc:
                if (basetype(tp)->sp && basetype(tp)->sp->parentClass && !first)
                {
                    *in++ = 'M';
                    in = getName(in, tp->sp->parentClass);
                    in += strlen(in);
                }
                *in++ = 'q';
                hr = tp->syms->table[0];
                while (hr)
                {
                    SYMBOL *sp = (SYMBOL *)hr->p;
                    if (!sp->thisPtr)
                        in = mangleType(in, sp->tp, TRUE);
                    hr = hr->next ;
                }
                *in++ = '$';
                // return value
                in = mangleType(in, tp->btp, TRUE);
                break;
            case bt_memberptr:
                *in++ = 'M';
                in = getName(in, tp->sp);
                if (isfunction(tp->btp))
                {
                    *in++ = 'q';
                    hr = basetype(tp->btp)->syms->table[0];
                    while (hr)
                    {
                        SYMBOL *sp = (SYMBOL *)hr->p;
                        if (!sp->thisPtr)
                            in = mangleType(in, sp->tp, TRUE);
                        hr = hr->next ;
                    }
                    *in++ = '$';
                    in = mangleType (in, tp->btp->btp, TRUE);
                }
                else
                {
                    *in++ = '$';
                    in = mangleType (in, basetype(tp)->btp, TRUE);
                }
                break;
            case bt_enum:
            case bt_struct:
            case bt_union:
            case bt_class:
                in = getName(in, tp->sp);
                break;
            case bt_bool:
                in = lookupName(in, "bool");
                in += strlen(in);
                break;
            case bt_unsigned_short:
                *in++ = 'u';
            case bt_short:
                *in++ = 's';
                break;
            case bt_unsigned:
                *in++ = 'u';
            case bt_int:
                *in++ = 'i';
                break;
            case bt_char16_t:
                *in++ = 'h';
                break;
            case bt_char32_t:
                *in++ = 'H';
                break;
            case bt_unsigned_long:
                *in++ = 'u';
            case bt_long:
                *in++ = 'l';
                break;
            case bt_unsigned_long_long:
                *in++ = 'u';
            case bt_long_long:
                *in++ = 'L';
                break;
            case bt_unsigned_char:
                *in++ = 'u';
            case bt_char:
                *in++ = 'c';
                break;
            case bt_signed_char:
                *in++ = 'S';
                *in++ = 'c';
                break;
            case bt_wchar_t:
                *in++ = 'C';
                break;
            case bt_float_complex:
                *in++ = 'F';
                break;
            case bt_double_complex:
                *in++ = 'D';
                break;
            case bt_long_double_complex:
                *in++ = 'G';
                break;
            case bt_float:
                *in++ = 'f';
                break;
            case bt_double:
                *in++ = 'd';
                break;
            case bt_long_double:
                *in++ = 'g';
                break;
            case bt_pointer:
                if (tp->nullptrType)
                {
                    in = lookupName(in, "nullptr_t");
                    in += strlen(in);
                }
                else
                {
                    if (first|| !tp->array)
                    {
                        *in++ = 'p';
                    }
                    else
                    {
                        sprintf(in,"A%ld",tp->btp->size ? tp->size / tp->btp->size : 0);
                        in += strlen(in);
                    }
                    in = mangleType(in, tp->btp, FALSE);
                }
                break;
            case bt_far:
                *in++ = 'P';
                in = mangleType(in, tp->btp, FALSE);
                break;
            case bt_lref:
                *in++ = 'r';
                in = mangleType(in, tp->btp, FALSE);
                break;
            case bt_rref:
                *in++ = 'R';
                in = mangleType(in, tp->btp, FALSE);
                break;
            case bt_ellipse:
                *in++ = 'e';
                break;
            case bt_void:
            case bt_any:
                *in++ = 'v';
                break;
            case bt_templateparam:
                in = getName(in, tp->templateParam->p->sym);
                break;
            case bt_templateselector:
            {
                TEMPLATESELECTOR *s = tp->sp->templateSelector;
                char *p;
                s = s->next;
                if (s->isTemplate)
                    p = mangleTemplate(nm, s->sym, s->templateParams);
                else
                    p = getName(nm, s->sym);
				p[0] =0;
				if (strlen(nm) > sizeof(nm))
                    p = mangleTemplate(nm, s->sym, s->templateParams);
                s = s->next ;
                while (s)
                {
                    strcat(nm , "@");
                    strcat(nm , s->name);
                    s= s->next;
                }
                p = nm;
                while (isdigit(*p))
                    p++;
                sprintf(in, "%d%s", strlen(p), p);
                in += strlen(in);
            }
                break;
            case bt_templatedecltype:
                // the index is being used to make names unique so two decltypes won't collide when storing them
                // in a symbol table...
                declTypeIndex = (declTypeIndex + 1) %1000;
                *in++ = 'E';
                sprintf(in, "%03d", declTypeIndex);
                in += 3;
                break;
            case bt_aggregate:
                in = getName(in, tp->sp);
                break;
            default:
                diag("mangleType: unknown type");
                break;
        }
    }
    *in= 0;
    return in;
}
Beispiel #13
0
/*
 * generate:
 *	res = &n;
 */
void
agen(Node *n, Node *res)
{
	Node *nl, *nr;
	Node n1, n2, n3, tmp, n4;
	Prog *p1;
	uint32 w;
	uint64 v;
	Type *t;

	if(debug['g']) {
		dump("\nagen-res", res);
		dump("agen-r", n);
	}
	if(n == N || n->type == T)
		return;

	if(!isptr[res->type->etype])
		fatal("agen: not tptr: %T", res->type);

	while(n->op == OCONVNOP)
		n = n->left;

	if(n->addable) {
		regalloc(&n1, types[tptr], res);
		gins(ALEAQ, n, &n1);
		gmove(&n1, res);
		regfree(&n1);
		goto ret;
	}

	nl = n->left;
	nr = n->right;

	switch(n->op) {
	default:
		fatal("agen: unknown op %N", n);
		break;

	case OCALLMETH:
		cgen_callmeth(n, 0);
		cgen_aret(n, res);
		break;

	case OCALLINTER:
		cgen_callinter(n, res, 0);
		cgen_aret(n, res);
		break;

	case OCALLFUNC:
		cgen_call(n, 0);
		cgen_aret(n, res);
		break;

	case OINDEX:
		w = n->type->width;
		if(nr->addable)
			goto irad;
		if(nl->addable) {
			if(!isconst(nr, CTINT)) {
				regalloc(&n1, nr->type, N);
				cgen(nr, &n1);
			}
			regalloc(&n3, types[tptr], res);
			agen(nl, &n3);
			goto index;
		}
		tempname(&tmp, nr->type);
		cgen(nr, &tmp);
		nr = &tmp;

	irad:
		regalloc(&n3, types[tptr], res);
		agen(nl, &n3);
		if(!isconst(nr, CTINT)) {
			regalloc(&n1, nr->type, N);
			cgen(nr, &n1);
		}
		goto index;

	index:
		// &a is in &n3 (allocated in res)
		// i is in &n1 (if not constant)
		// w is width

		// explicit check for nil if array is large enough
		// that we might derive too big a pointer.
		if(!isslice(nl->type) && nl->type->width >= unmappedzero) {
			regalloc(&n4, types[tptr], &n3);
			gmove(&n3, &n4);
			n4.op = OINDREG;
			n4.type = types[TUINT8];
			n4.xoffset = 0;
			gins(ATESTB, nodintconst(0), &n4);
			regfree(&n4);
		}

		if(w == 0)
			fatal("index is zero width");

		// constant index
		if(isconst(nr, CTINT)) {
			v = mpgetfix(nr->val.u.xval);
			if(isslice(nl->type)) {

				if(!debug['B'] && !n->etype) {
					n1 = n3;
					n1.op = OINDREG;
					n1.type = types[tptr];
					n1.xoffset = Array_nel;
					nodconst(&n2, types[TUINT64], v);
					gins(optoas(OCMP, types[TUINT32]), &n1, &n2);
					p1 = gbranch(optoas(OGT, types[TUINT32]), T);
					ginscall(throwindex, 0);
					patch(p1, pc);
				}

				n1 = n3;
				n1.op = OINDREG;
				n1.type = types[tptr];
				n1.xoffset = Array_array;
				gmove(&n1, &n3);
			} else
			if(!debug['B'] && !n->etype) {
				if(v < 0)
					yyerror("out of bounds on array");
				else
				if(v >= nl->type->bound)
					yyerror("out of bounds on array");
			}

			nodconst(&n2, types[tptr], v*w);
			gins(optoas(OADD, types[tptr]), &n2, &n3);

			gmove(&n3, res);
			regfree(&n3);
			break;
		}

		// type of the index
		t = types[TUINT64];
		if(issigned[n1.type->etype])
			t = types[TINT64];

		regalloc(&n2, t, &n1);			// i
		gmove(&n1, &n2);
		regfree(&n1);

		if(!debug['B'] && !n->etype) {
			// check bounds
			if(isslice(nl->type)) {
				n1 = n3;
				n1.op = OINDREG;
				n1.type = types[tptr];
				n1.xoffset = Array_nel;
			} else
				nodconst(&n1, types[TUINT64], nl->type->bound);
			gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
			p1 = gbranch(optoas(OLT, types[TUINT32]), T);
			ginscall(throwindex, 0);
			patch(p1, pc);
		}

		if(isslice(nl->type)) {
			n1 = n3;
			n1.op = OINDREG;
			n1.type = types[tptr];
			n1.xoffset = Array_array;
			gmove(&n1, &n3);
		}

		if(w == 1 || w == 2 || w == 4 || w == 8) {
			p1 = gins(ALEAQ, &n2, &n3);
			p1->from.scale = w;
			p1->from.index = p1->from.type;
			p1->from.type = p1->to.type + D_INDIR;
		} else {
			nodconst(&n1, t, w);
			gins(optoas(OMUL, t), &n1, &n2);
			gins(optoas(OADD, types[tptr]), &n2, &n3);
			gmove(&n3, res);
		}

		gmove(&n3, res);
		regfree(&n2);
		regfree(&n3);
		break;

	case ONAME:
		// should only get here with names in this func.
		if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
			dump("bad agen", n);
			fatal("agen: bad ONAME funcdepth %d != %d",
				n->funcdepth, funcdepth);
		}

		// should only get here for heap vars or paramref
		if(!(n->class & PHEAP) && n->class != PPARAMREF) {
			dump("bad agen", n);
			fatal("agen: bad ONAME class %#x", n->class);
		}
		cgen(n->heapaddr, res);
		if(n->xoffset != 0) {
			nodconst(&n1, types[TINT64], n->xoffset);
			gins(optoas(OADD, types[tptr]), &n1, res);
		}
		break;

	case OIND:
		cgen(nl, res);
		break;

	case ODOT:
		agen(nl, res);
		if(n->xoffset != 0) {
			nodconst(&n1, types[TINT64], n->xoffset);
			gins(optoas(OADD, types[tptr]), &n1, res);
		}
		break;

	case ODOTPTR:
		cgen(nl, res);
		if(n->xoffset != 0) {
			// explicit check for nil if struct is large enough
			// that we might derive too big a pointer.
			if(nl->type->type->width >= unmappedzero) {
				regalloc(&n1, types[tptr], res);
				gmove(res, &n1);
				n1.op = OINDREG;
				n1.type = types[TUINT8];
				n1.xoffset = 0;
				gins(ATESTB, nodintconst(0), &n1);
				regfree(&n1);
			}
			nodconst(&n1, types[TINT64], n->xoffset);
			gins(optoas(OADD, types[tptr]), &n1, res);
		}
		break;
	}

ret:
	;
}
Beispiel #14
0
Datei: swt.c Projekt: 8l/go
/*
 * type check switch statement
 */
void
typecheckswitch(Node *n)
{
	int top, lno, ptr;
	char *nilonly;
	Type *t, *badtype, *missing, *have;
	NodeList *l, *ll;
	Node *ncase, *nvar;
	Node *def;

	lno = lineno;
	typechecklist(n->ninit, Etop);
	nilonly = nil;

	if(n->ntest != N && n->ntest->op == OTYPESW) {
		// type switch
		top = Etype;
		typecheck(&n->ntest->right, Erv);
		t = n->ntest->right->type;
		if(t != T && t->etype != TINTER)
			yyerror("cannot type switch on non-interface value %lN", n->ntest->right);
	} else {
		// value switch
		top = Erv;
		if(n->ntest) {
			typecheck(&n->ntest, Erv);
			defaultlit(&n->ntest, T);
			t = n->ntest->type;
		} else
			t = types[TBOOL];
		if(t) {
			if(!okforeq[t->etype])
				yyerror("cannot switch on %lN", n->ntest);
			else if(t->etype == TARRAY && !isfixedarray(t))
				nilonly = "slice";
			else if(t->etype == TARRAY && isfixedarray(t) && algtype1(t, nil) == ANOEQ)
				yyerror("cannot switch on %lN", n->ntest);
			else if(t->etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ)
				yyerror("cannot switch on %lN (struct containing %T cannot be compared)", n->ntest, badtype);
			else if(t->etype == TFUNC)
				nilonly = "func";
			else if(t->etype == TMAP)
				nilonly = "map";
		}
	}
	n->type = t;

	def = N;
	for(l=n->list; l; l=l->next) {
		ncase = l->n;
		setlineno(n);
		if(ncase->list == nil) {
			// default
			if(def != N)
				yyerror("multiple defaults in switch (first at %L)", def->lineno);
			else
				def = ncase;
		} else {
			for(ll=ncase->list; ll; ll=ll->next) {
				setlineno(ll->n);
				typecheck(&ll->n, Erv | Etype);
				if(ll->n->type == T || t == T)
					continue;
				setlineno(ncase);
				switch(top) {
				case Erv:	// expression switch
					defaultlit(&ll->n, t);
					if(ll->n->op == OTYPE)
						yyerror("type %T is not an expression", ll->n->type);
					else if(ll->n->type != T && !assignop(ll->n->type, t, nil) && !assignop(t, ll->n->type, nil)) {
						if(n->ntest)
							yyerror("invalid case %N in switch on %N (mismatched types %T and %T)", ll->n, n->ntest, ll->n->type, t);
						else
							yyerror("invalid case %N in switch (mismatched types %T and bool)", ll->n, ll->n->type);
					} else if(nilonly && !isconst(ll->n, CTNIL)) {
						yyerror("invalid case %N in switch (can only compare %s %N to nil)", ll->n, nilonly, n->ntest);
					}
					break;
				case Etype:	// type switch
					if(ll->n->op == OLITERAL && istype(ll->n->type, TNIL)) {
						;
					} else if(ll->n->op != OTYPE && ll->n->type != T) {  // should this be ||?
						yyerror("%lN is not a type", ll->n);
						// reset to original type
						ll->n = n->ntest->right;
					} else if(ll->n->type->etype != TINTER && t->etype == TINTER && !implements(ll->n->type, t, &missing, &have, &ptr)) {
						if(have && !missing->broke && !have->broke)
							yyerror("impossible type switch case: %lN cannot have dynamic type %T"
								" (wrong type for %S method)\n\thave %S%hT\n\twant %S%hT",
								n->ntest->right, ll->n->type, missing->sym, have->sym, have->type,
								missing->sym, missing->type);
						else if(!missing->broke)
							yyerror("impossible type switch case: %lN cannot have dynamic type %T"
								" (missing %S method)", n->ntest->right, ll->n->type, missing->sym);
					}
					break;
				}
			}
		}
		if(top == Etype && n->type != T) {
			ll = ncase->list;
			nvar = ncase->nname;
			if(nvar != N) {
				if(ll && ll->next == nil && ll->n->type != T && !istype(ll->n->type, TNIL)) {
					// single entry type switch
					nvar->ntype = typenod(ll->n->type);
				} else {
					// multiple entry type switch or default
					nvar->ntype = typenod(n->type);
				}
			}
		}
		typechecklist(ncase->nbody, Etop);
	}

	lineno = lno;
}
Beispiel #15
0
static void *uid2type(int uid) {
	assert(uid >= 0 && uid < nuids);
	if (itemmap[uid] == NULL) {
		Type ty;
		rcc_type_ty type = (void *)items[uid];
		assert(items[uid]);
		assert(items[uid]->uid == uid);
		assert(items[uid]->kind == rcc_Type_enum);
		type = items[uid]->v.rcc_Type.type;
		assert(type);
		switch (type->kind) {
		case rcc_INT_enum:
			ty = btot(INT, type->size);
			assert(ty->align == type->align);
			break;
		case rcc_UNSIGNED_enum:
			ty = btot(UNSIGNED, type->size);
			assert(ty->align == type->align);
			break;
		case rcc_FLOAT_enum:
			ty = btot(FLOAT, type->size);
			assert(ty->align == type->align);
			break;
		case rcc_VOID_enum:
			ty = voidtype;
			break;
		case rcc_POINTER_enum:
			ty = ptr(uid2type(type->v.rcc_POINTER.type));
			break;
		case rcc_ARRAY_enum:
			ty = uid2type(type->v.rcc_ARRAY.type);
			assert(ty->size > 0);
			ty = array(ty, type->size/ty->size, 0);
			break;
		case rcc_CONST_enum:
			ty = qual(CONST, uid2type(type->v.rcc_CONST.type));
			break;
		case rcc_VOLATILE_enum:
			ty = qual(VOLATILE, uid2type(type->v.rcc_VOLATILE.type));
			break;
		case rcc_ENUM_enum: {
			int i, n = Seq_length(type->v.rcc_ENUM.ids);
			ty = newstruct(ENUM, string(type->v.rcc_ENUM.tag));
			ty->type = inttype;
			ty->size = ty->type->size;
			ty->align = ty->type->align;
			ty->u.sym->u.idlist = newarray(n + 1, sizeof *ty->u.sym->u.idlist, PERM);
			for (i = 0; i < n; i++) {
				rcc_enum__ty e = Seq_remlo(type->v.rcc_ENUM.ids);
				Symbol p = install(e->id, &identifiers, GLOBAL, PERM);
				p->type = ty;
				p->sclass = ENUM;
				p->u.value = e->value;
				ty->u.sym->u.idlist[i] = p;
				free(e);
			}
			ty->u.sym->u.idlist[i] = NULL;
			Seq_free(&type->v.rcc_ENUM.ids);
			break;
			}
		case rcc_STRUCT_enum: case rcc_UNION_enum: {
			int i, n;
			Field *tail;
			list_ty fields;
			if (type->kind == rcc_STRUCT_enum) {
				ty = newstruct(STRUCT, string(type->v.rcc_STRUCT.tag));
				fields = type->v.rcc_STRUCT.fields;
			} else {
				ty = newstruct(UNION, string(type->v.rcc_UNION.tag));
				fields = type->v.rcc_UNION.fields;
			}
			itemmap[uid] = ty;	/* recursive types */
			ty->size = type->size;
			ty->align = type->align;
			tail = &ty->u.sym->u.s.flist;
			n = Seq_length(fields);
			for (i = 0; i < n; i++) {
				rcc_field_ty field = Seq_remlo(fields);
				NEW0(*tail, PERM);
				(*tail)->name = (char *)field->id;
				(*tail)->type = uid2type(field->type);
				(*tail)->offset = field->offset;
				(*tail)->bitsize = field->bitsize;
				(*tail)->lsb = field->lsb;
				if (isconst((*tail)->type))
					ty->u.sym->u.s.cfields = 1;
				if (isvolatile((*tail)->type))
					ty->u.sym->u.s.vfields = 1;
				tail = &(*tail)->link;
				free(field);
			}
			Seq_free(&fields);
			break;
			}
		case rcc_FUNCTION_enum: {
			int n = Seq_length(type->v.rcc_FUNCTION.formals);
			if (n > 0) {
				int i;
				Type *proto = newarray(n + 1, sizeof *proto, PERM);
				for (i = 0; i < n; i++) {
					int *formal = Seq_remlo(type->v.rcc_FUNCTION.formals);
					proto[i] = uid2type(*formal);
					free(formal);
				}
				proto[i] = NULL;
				ty = func(uid2type(type->v.rcc_FUNCTION.type), proto, 0);
			} else
				ty = func(uid2type(type->v.rcc_FUNCTION.type), NULL, 1);
			Seq_free(&type->v.rcc_FUNCTION.formals);
			break;
			}
		default: assert(0);
		}
		if (itemmap[uid] == NULL) {
			itemmap[uid] = ty;
			free(type);
			free(items[uid]);
			items[uid] = NULL;
		} else
			assert(itemmap[uid] == ty);
	}
	return itemmap[uid];
}
Beispiel #16
0
int argcnt(const char c)                //count of arguments
{if (isconst(c)) return 0;
 if (isfn(c) && c!=fpow && c!=f_op_pow && c!=f_op_root && c!=froot && c!=flogn || c=='!' || c=='_') return 1;
 return 2;
}
Beispiel #17
0
BOOLEAN comparetypes(TYPE *typ1, TYPE *typ2, int exact)
{
    if (typ1->type == bt_any || typ2->type == bt_any)
        return TRUE;
    while (typ1->type == bt_typedef)
        typ1 = basetype(typ1);
    while (typ2->type == bt_typedef)
        typ2 = basetype(typ2);
    typ1 = replaceTemplateSelector(typ1);
    typ2 = replaceTemplateSelector(typ2);
    if (isDerivedFromTemplate(typ1))
        typ1 = typ1->btp;
    if (isDerivedFromTemplate(typ2))
        typ2 = typ2->btp;
    while (isref(typ1))
        typ1 = basetype(typ1)->btp;
    while (isref(typ2))
        typ2 = basetype(typ2)->btp;
    while (typ1->type == bt_typedef)
        typ1 = basetype(typ1);
    while (typ2->type == bt_typedef)
        typ2 = basetype(typ2);
    if (typ1->type == bt_templateselector && typ2->type == bt_templateselector)
        return templateselectorcompare(typ1->sp->templateSelector, typ2->sp->templateSelector);
    if (typ1->type == bt_templatedecltype && typ2->type == bt_templatedecltype)
        return templatecompareexpressions(typ1->templateDeclType, typ2->templateDeclType);
    if (ispointer(typ1) && ispointer(typ2))
    {
        if (exact)
        {
            int arr = FALSE;
            int first = TRUE;
            while (ispointer(typ1) && ispointer(typ2))
            {
                if (!first && (exact == 1))
                    if ((isconst(typ2) && !isconst(typ1)) || (isvolatile(typ2) && !isvolatile(typ1)))
                        return FALSE;
                first = FALSE;
                typ1 = basetype(typ1);
                typ2 = basetype(typ2);
                if (typ1->type != typ2->type)
                    return FALSE;
                if (arr && typ1->array != typ2->array)	
                    return FALSE;
                if (arr && typ1->size != typ2->size)
                    return FALSE;
                arr |= typ1->array | typ2->array;
                typ1 = typ1->btp;
                typ2 = typ2->btp;				
            }
            if (exact == 1 && ((isconst(typ2) && !isconst(typ1)) || (isvolatile(typ2) && !isvolatile(typ1))))
                return FALSE;
            return comparetypes(typ1, typ2, TRUE);
        }
            
        else
            return TRUE;
    }
    typ1 = basetype(typ1);
    typ2 = basetype(typ2);
    if (exact && (isfunction(typ1) || isfuncptr(typ1)) && (isfunction(typ2) || isfuncptr(typ2)))
    {
        HASHREC *hr1;
        HASHREC *hr2;
        typ1 = basetype(typ1);
        typ2 = basetype(typ2);
        if (ispointer(typ1))
            typ1 = basetype(typ1)->btp;
        if (ispointer(typ2))
            typ2 = basetype(typ2)->btp;
        if (!comparetypes(typ1->btp, typ2->btp, exact))
            return FALSE;
        if (!matchOverload(typ1, typ2, TRUE))
            return FALSE;
        return TRUE;
    }
    if (cparams.prm_cplusplus)
    {
        if (typ1->scoped != typ2->scoped)
            return FALSE;
        if (typ1->type == bt_enum)
        {
            if (typ2->type == bt_enum)
                return typ1->sp == typ2->sp;
            else
                return isint(typ2);
        }
        else if (typ2->type == bt_enum)
        {
            return isint(typ1);
        }
        if (typ1->type == typ2->type && typ1->type == bt_memberptr)
        {
            if (typ1->sp != typ2->sp)
            {
                if (classRefCount(typ1->sp, typ2->sp) != 1)
                    return FALSE;
            }
            return comparetypes(typ1->btp, typ2->btp, exact);
        }
    }
    if (typ1->type == typ2->type && (isstructured(typ1) || (exact && typ1->type == bt_enum)))
        return typ1->sp == typ2->sp;
    if (typ1->type == typ2->type || (!exact && isarithmetic(typ2) && isarithmetic(typ1)))
        return TRUE;
    if (isfunction(typ1) && isfunction(typ2) && 
        typ1->sp->linkage == typ2->sp->linkage)
        return TRUE;
    else if (!exact && ((ispointer(typ1) && (isfuncptr(typ2) || isfunction(typ2) || isint(typ2)))
             || (ispointer(typ2) && (isfuncptr(typ1) || isfunction(typ1) || isint(typ1)))))
            return (TRUE);
    else if (typ1->type == bt_enum && isint(typ2))
    {
        return TRUE;
    }
    else if (typ2->type == bt_enum && isint(typ1))
    {
        return TRUE;
    }
    return FALSE;
}
Beispiel #18
-1
char* TSolver::convtopol()   //converts symbol-function string to polish record
{if (S==NULL || !strlen(S)) seterr(E_VOID);
 char* r;
 if (Err!=E_NO)
   {ERROR:
    if (r!=NULL) free(r);
    free(S);
    return S=NULL;
   }
 int i,j=0;
 int p;
 int SL=strlen(S);
 r=(char*)calloc(SL*2+2,sizeof(char));
 r[0]='\0';
 cst_clear;
 for (i=0;S[i]!='\0';i++)
   {if (isnumc(S[i]) || isconst(S[i]) || (S[i]=='-' && (minusE || minusN)))
      {r[j++]=S[i];
       continue;
      }
    if (S[i]=='!')
      {addspc();
       r[j++]=S[i];
       addspc();
       continue;
      }
    p=prior(S[i]);
      {if (S[i]==')')
	 {addspc();
	  while ((!cst_free) && cst_end!='(')
	    {r[j++]=cpop();
	     r[j++]=' ';
	    }
	  cpop();
	  if ((!cst_free) && isfn(cst_end))
	    {r[j++]=cpop();
	     r[j++]=' ';
	    }
	  continue;
	 }

       if (S[i]==']')
	 {addspc();
	  while ((!cst_free) && cst_end!='[')
	    {r[j++]=cpop();
	     r[j++]=' ';
	    }
	  cpop();
	  r[j++]=f_abs;
          r[j++]=' ';
	  continue;
	 }
       if ((((!cst_free) && (p>=prior(cst_end)) && (prior(cst_end)>0)&&cst_end!='_'&&S[i]!='_') || S[i]==','))
	   {addspc();
	    while ((!cst_free) && p>=prior(cst_end) && prior(cst_end)>0)
	      {r[j++]=cpop();
	       r[j++]=' ';
	      }
	    if (S[i]==',') continue;
	   }
       cpush(S[i]);
       if (j>0) addspc();
      }
   }
 if (Err!=E_NO) goto ERROR;
 if (r[j-1]!=' ') r[j++]=' ';
 while (!cst_free)
  {r[j++]=cpop();
   r[j++]=' ';
  }
 if (r[j-1]!=' ') r[j++]=' ';
 r[j]='\0';
 free(S);
 S=strdbl(r);
 free(r);
#ifdef debug
 printf("%s\n",S);
#endif
 poled=1;
 return S;
}