view dmd/TypeEnum.d @ 135:af1bebfd96a4 dmd2037

dmd 2.038
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Mon, 13 Sep 2010 22:19:42 +0100
parents e28b18c23469
children 0c8cc2a10f99
line wrap: on
line source

module dmd.TypeEnum;

import dmd.common;
import dmd.Type;
import dmd.EnumDeclaration;
import dmd.Scope;
import dmd.Loc;
import dmd.Id;
import dmd.ErrorExp;
import dmd.Dsymbol;
import dmd.EnumMember;
import dmd.OutBuffer;
import dmd.HdrGenState;
import dmd.Expression;
import dmd.Identifier;
import dmd.MATCH;
import dmd.OutBuffer;
import dmd.CppMangleState;
import dmd.TypeInfoDeclaration;
import dmd.TypeInfoEnumDeclaration;
import dmd.ArrayTypes;
import dmd.TY;
import dmd.MOD;
import dmd.Util;

import dmd.backend.TYPE;

class TypeEnum : Type
{
    EnumDeclaration sym;

    this(EnumDeclaration sym)
	{
		super(TY.Tenum);
		this.sym = sym;
	}
	
version (DumbClone) {
} else {
	Type clone()
	{
		assert(false);
	}
}
    override Type syntaxCopy()
	{
		assert(false);
	}
	
    override ulong size(Loc loc)
	{
		if (!sym.memtype)
		{
			error(loc, "enum %s is forward referenced", sym.toChars());
			return 4;
		}
		return sym.memtype.size(loc);
	}
	
    override uint alignsize()
	{
		assert(false);
	}
	
    override string toChars()
	{
		assert(false);
	}
	
    override Type semantic(Loc loc, Scope sc)
	{
		//printf("TypeEnum::semantic() %s\n", toChars());
		//sym.semantic(sc);
		return merge();
	}
	
    override Dsymbol toDsymbol(Scope sc)
	{
		return sym;
	}
	
    override void toDecoBuffer(OutBuffer buf, int flag)
	{
		string name = sym.mangle();
		Type.toDecoBuffer(buf, flag);
		buf.printf("%s", name);
	}
	
    override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
	{
		if (mod != this.mod)
		{	
			toCBuffer3(buf, hgs, mod);
			return;
		}
		buf.writestring(sym.toChars());
	}

    override Expression dotExp(Scope sc, Expression e, Identifier ident)
	{
	version (LOGDOTEXP) {
		printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e.toChars(), ident.toChars(), toChars());
	}
		Dsymbol s = sym.search(e.loc, ident, 0);
		if (!s)
		{
			if (ident is Id.max ||
				ident is Id.min ||
				ident is Id.init_ ||
				ident is Id.stringof_ ||
				!sym.memtype
			   )
			{
				return getProperty(e.loc, ident);
			}

			return sym.memtype.dotExp(sc, e, ident);
		}

		EnumMember m = s.isEnumMember();
		Expression em = m.value.copy();
		em.loc = e.loc;
		return em;
	}
	
    override Expression getProperty(Loc loc, Identifier ident)
	{
		assert(false);
	}
	
    override bool isintegral()
	{
	    return sym.memtype.isintegral();
	}
	
    override bool isfloating()
	{
	    return sym.memtype.isfloating();
	}
	
    override bool isreal()
	{
		return sym.memtype.isreal();
	}
	
    override bool isimaginary()
	{
		return sym.memtype.isimaginary();
	}
	
    override bool iscomplex()
	{
		return sym.memtype.iscomplex();
	}
	
    override bool checkBoolean()
	{
		return sym.memtype.checkBoolean();
	}
	
    override bool isAssignable()
	{
		return sym.memtype.isAssignable();
	}
	
    override bool isscalar()
	{
	    return sym.memtype.isscalar();
	}
	
    override bool isunsigned()
	{
		return sym.memtype.isunsigned();
	}
	
    override MATCH implicitConvTo(Type to)
	{
		MATCH m;

		//printf("TypeEnum::implicitConvTo()\n");
		if (ty == to.ty && sym == (cast(TypeEnum)to).sym)
			m = (mod == to.mod) ? MATCHexact : MATCHconst;
		else if (sym.memtype.implicitConvTo(to))
			m = MATCHconvert;	// match with conversions
		else
			m = MATCHnomatch;	// no match
		return m;
	}
	
    override MATCH constConv(Type to)
	{
        if (equals(to))
	        return MATCHexact;
        if (ty == to.ty && sym == (cast(TypeEnum)to).sym &&
	        MODimplicitConv(mod, to.mod))
	        return MATCHconst;
        return MATCHnomatch;
	}
	
    override Type toBasetype()
	{
        if (sym.scope_)
        {
    	    sym.semantic(null);	// attempt to resolve forward reference
        }
		if (!sym.memtype)
		{
			debug writef("2: ");
			error(sym.loc, "enum %s is forward referenced", sym.toChars());
			return tint32;
		}

		return sym.memtype.toBasetype();
	}
	
    override Expression defaultInit(Loc loc)
	{
	version (LOGDEFAULTINIT) {
		printf("TypeEnum::defaultInit() '%s'\n", toChars());
	}
		// Initialize to first member of enum
		//printf("%s\n", sym.defaultval.type.toChars());
		if (!sym.defaultval)
		{
			error(loc, "forward reference of %s.init", toChars());
			return new ErrorExp();
		}
		return sym.defaultval;
	}
	
    override bool isZeroInit(Loc loc)
	{
		if (!sym.defaultval)
		{
			debug writef("3: ");
			error(loc, "enum %s is forward referenced", sym.toChars());
			return 0;
		}
		return sym.defaultval.isBool(false);
	}
	
	override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
	{
		// Extra check
		if (tparam && tparam.ty == Tenum)
		{
			TypeEnum tp = cast(TypeEnum)tparam;

			if (sym != tp.sym)
				return MATCHnomatch;
		}
		return Type.deduceType(sc, tparam, parameters, dedtypes);
	}
	
    override TypeInfoDeclaration getTypeInfoDeclaration()
	{
		return new TypeInfoEnumDeclaration(this);
	}
	
    override bool hasPointers()
	{
		return toBasetype().hasPointers();
	}
	
version (CPP_MANGLE) {
    void toCppMangle(OutBuffer buf, CppMangleState* cms)
	{
		assert(false);
	}
}

    override type* toCtype()
	{
		return sym.memtype.toCtype();
	}
}