view dmd/TemplateValueParameter.d @ 39:d4825905adc2

TemplateValueParameter.specialization implemented
author korDen
date Sat, 21 Aug 2010 07:07:10 +0400
parents 89cc05dbdae1
children caa9bdb08ae6
line wrap: on
line source

module dmd.TemplateValueParameter;

import dmd.TemplateParameter;
import dmd.Scope;
import dmd.Declaration;
import dmd.ArrayTypes;
import dmd.Type;
import dmd.Expression;
import dmd.Loc;
import dmd.Identifier;
import dmd.OutBuffer;
import dmd.HdrGenState;
import dmd.MATCH;
import dmd.VarDeclaration;
import dmd.STC;
import dmd.Util;
import dmd.TY;
import dmd.WANT;
import dmd.TOK;

class TemplateValueParameter : TemplateParameter
{
    /* Syntax:
     *	valType ident : specValue = defaultValue
     */

    Type valType;
    Expression specValue;
    Expression defaultValue;

    static Expression edummy;

    this(Loc loc, Identifier ident, Type valType, Expression specValue, Expression defaultValue)
	{
		super(loc, ident);
		
		this.valType = valType;
		this.specValue = specValue;
		this.defaultValue = defaultValue;
	}

    TemplateValueParameter isTemplateValueParameter()
	{
		return this;
	}
	
    TemplateParameter syntaxCopy()
	{
		TemplateValueParameter tp = new TemplateValueParameter(loc, ident, valType, specValue, defaultValue);
		tp.valType = valType.syntaxCopy();
		if (specValue)
			tp.specValue = specValue.syntaxCopy();
		if (defaultValue)
			tp.defaultValue = defaultValue.syntaxCopy();
		return tp;
	}

    void declareParameter(Scope sc)
	{
		VarDeclaration v = new VarDeclaration(loc, valType, ident, null);
		v.storage_class = STC.STCtemplateparameter;
		if (!sc.insert(v))
			error(loc, "parameter '%s' multiply defined", ident.toChars());
		sparam = v;
	}

    void semantic(Scope sc)
	{
		sparam.semantic(sc);
		valType = valType.semantic(loc, sc);
		if (!(valType.isintegral() || valType.isfloating() || valType.isString()) && valType.ty != TY.Tident)
			error(loc, "arithmetic/string type expected for value-parameter, not %s", valType.toChars());

		if (specValue)
		{   
			Expression e = specValue;

			e = e.semantic(sc);
			e = e.implicitCastTo(sc, valType);
			e = e.optimize(WANTvalue | WANTinterpret);
			if (e.op == TOKint64 || e.op == TOKfloat64 ||
				e.op == TOKcomplex80 || e.op == TOKnull || e.op == TOKstring)
				specValue = e;
			//e.toInteger();
		}

static if (false) {	// defer semantic analysis to arg match
		if (defaultValue)
		{   
			Expression e = defaultValue;

			e = e.semantic(sc);
			e = e.implicitCastTo(sc, valType);
			e = e.optimize(WANTvalue | WANTinterpret);
			if (e.op == TOKint64)
				defaultValue = e;
			//e.toInteger();
		}
}
	}

    void print(Object oarg, Object oded)
	{
		assert(false);
	}

    void toCBuffer(OutBuffer buf, HdrGenState* hgs)
	{
		assert(false);
	}

    Object specialization()
	{
		return specValue;
	}

    Object defaultArg(Loc loc, Scope sc)
	{
		assert(false);
	}

    bool overloadMatch(TemplateParameter tp)
	{
		TemplateValueParameter tvp = tp.isTemplateValueParameter();

		if (tvp)
		{
			if (valType != tvp.valType)
				return false;

			if (valType && !valType.equals(tvp.valType))
				return false;

			if (specValue != tvp.specValue)
				return false;

			return true;			// match
		}

		return false;
	}

    MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags)
	{
		assert(false);
	}

    void* dummyArg()
	{
		assert(false);
	}
}