view dmd/FuncExp.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 ecf732dfe11e
line wrap: on
line source

module dmd.FuncExp;

import dmd.Expression;
import dmd.backend.elem;
import dmd.OutBuffer;
import dmd.Loc;
import dmd.Scope;
import dmd.InlineCostState;
import dmd.IRState;
import dmd.HdrGenState;
import dmd.FuncLiteralDeclaration;
import dmd.TOK;
import dmd.TypeFunction;
import dmd.TypeDelegate;
import dmd.TY;
import dmd.Type;
import dmd.Global;

import dmd.backend.Util;
import dmd.codegen.Util;
import dmd.backend.TYM;
import dmd.backend.Symbol;

class FuncExp : Expression
{
	FuncLiteralDeclaration fd;

	this(Loc loc, FuncLiteralDeclaration fd)
	{
		super(loc, TOK.TOKfunction, FuncExp.sizeof);
		this.fd = fd;
	}

	Expression syntaxCopy()
	{
		return new FuncExp(loc, cast(FuncLiteralDeclaration)fd.syntaxCopy(null));
	}

	Expression semantic(Scope sc)
	{
version (LOGSEMANTIC) {
		printf("FuncExp.semantic(%s)\n", toChars());
}
		if (!type)
		{
			fd.semantic(sc);

			//fd.parent = sc.parent;
			if (global.errors)
			{
			}
			else
			{
				fd.semantic2(sc);
				if (!global.errors ||
					// need to infer return type
					(fd.type && fd.type.ty == TY.Tfunction && !fd.type.nextOf()))
				{
					fd.semantic3(sc);

					if (!global.errors && global.params.useInline)
						fd.inlineScan();
				}
			}

			// need to infer return type
			if (global.errors && fd.type && fd.type.ty == TY.Tfunction && !fd.type.nextOf())
				(cast(TypeFunction)fd.type).next = Type.terror;

			// Type is a "delegate to" or "pointer to" the function literal
			if (fd.isNested())
			{
				type = new TypeDelegate(fd.type);
				type = type.semantic(loc, sc);
			}
			else
			{
				type = fd.type.pointerTo();
			}

			fd.tookAddressOf++;
		}

		return this;
	}

	void scanForNestedRef(Scope sc)
	{
		assert(false);
	}

	string toChars()
	{
		assert(false);
	}

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

	elem* toElem(IRState* irs)
	{
		elem* e;
		Symbol* s;

		//printf("FuncExp::toElem() %s\n", toChars());
		s = fd.toSymbol();
		e = el_ptr(s);
		if (fd.isNested())
		{
			elem* ethis = getEthis(loc, irs, fd);
			e = el_pair(TYM.TYullong, ethis, e);
		}

		irs.deferToObj.push(cast(void*)fd);
		el_setLoc(e,loc);
		return e;
	}

	int inlineCost(InlineCostState* ics)
	{
		assert(false);
	}
}