view dmd/TypeNext.d @ 56:51605de93870

TupleExp.optimize UnrolledLoopStatement.ctor UnrolledLoopStatement.semantic UnrolledLoopStatement.blockExit OrOrExp.checkSideEffect FuncExp.syntaxCopy FuncLiteralDeclaration.syntaxCopy WhileStatement.hasBreak StructInitializer.toExpression StructLiteralExp.ctor StructLiteralExp.optimize BinExp.commonSemanticAssign ModAssignExp.opId Argument.isLazyArray CommaExp.implicitConvTo CommaExp.castTo TypeClass.isBaseOf createTypeInfoArray TypeTuple.getTypeInfoDeclaration TypeInfoTupleDeclaration.ctor TypeNext.constConv XorExp.implicitConvTo TemplateParameter.isTemplateValueParameter
author korDen
date Sat, 21 Aug 2010 14:16:53 +0400
parents 10317f0c89a5
children 2e2a5c3f943a
line wrap: on
line source

module dmd.TypeNext;

import dmd.Type;
import dmd.TY;
import dmd.OutBuffer;
import dmd.Loc;
import dmd.Scope;
import dmd.MATCH;
import dmd.MOD;

class TypeNext : Type
{
    Type next;

    this(TY ty, Type next)
	{
		super(ty);
		this.next = next;
	}
version (DumbClone) {
} else {
	final TypeNext cloneTo(TypeNext t)
	{
		super.cloneTo(t);
		return t;
	}

	TypeNext clone()
	{
		assert(this.classinfo == TypeNext.classinfo);
		return cloneTo(new TypeNext(ty, next));
	}
}
    void toDecoBuffer(OutBuffer buf, int flag)
	{
		super.toDecoBuffer(buf, flag);
		assert(next !is this);
		//printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this.ty, next, next.ty);
		next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod);
	}

    void checkDeprecated(Loc loc, Scope sc)
	{
		Type.checkDeprecated(loc, sc);
		if (next)	// next can be null if TypeFunction and auto return type
			next.checkDeprecated(loc, sc);
	}
	
    Type reliesOnTident()
	{
		return next.reliesOnTident();
	}
	
    Type nextOf()
	{
		return next;
	}
	
    Type makeConst()
	{
		//printf("TypeNext::makeConst() %p, %s\n", this, toChars());
		if (cto)
		{
			assert(cto.mod == MOD.MODconst);
			return cto;
		}
		
		TypeNext t = cast(TypeNext)super.makeConst();
		if (ty != TY.Tfunction && ty != TY.Tdelegate &&
			(next.deco || next.ty == TY.Tfunction) &&
			!next.isInvariant() && !next.isConst())
		{
			if (next.isShared())
				t.next = next.sharedConstOf();
			else
				t.next = next.constOf();
		}
		//printf("TypeNext::makeConst() returns %p, %s\n", t, t.toChars());
		return t;
	}
	
    Type makeInvariant()
	{
		//printf("TypeNext::makeInvariant() %s\n", toChars());
		if (ito)
		{	
			assert(ito.isInvariant());
			return ito;
		}
		TypeNext t = cast(TypeNext)Type.makeInvariant();
		if (ty != TY.Tfunction && ty != TY.Tdelegate && (next.deco || next.ty == TY.Tfunction) && !next.isInvariant())
		{	
			t.next = next.invariantOf();
		}
		return t;
	}
	
    Type makeShared()
	{
		//printf("TypeNext::makeShared() %s\n", toChars());
		if (sto)
		{	
			assert(sto.mod == MODshared);
			return sto;
		}    
		TypeNext t = cast(TypeNext)Type.makeShared();
		if (ty != Tfunction && ty != Tdelegate &&
			(next.deco || next.ty == Tfunction) &&
			!next.isInvariant() && !next.isShared())
		{
			if (next.isConst())
				t.next = next.sharedConstOf();
			else
				t.next = next.sharedOf();
		}

		//printf("TypeNext::makeShared() returns %p, %s\n", t, t.toChars());
		return t;
	}
	
    Type makeSharedConst()
	{
		assert(false);
	}
	
    MATCH constConv(Type to)
	{
		MATCH m = Type.constConv(to);

		if (m == MATCHconst && next.constConv((cast(TypeNext)to).next) == MATCHnomatch)
			m = MATCHnomatch;
		return m;
	}
	
    void transitive()
	{
		/* Invoke transitivity of type attributes
		 */
		next = next.addMod(mod);
	}
}