view dmd/Catch.d @ 114:e28b18c23469

added a module dmd.common for commonly used stuff it currently holds code for consistency checking of predefined versions also added a VisualD project file
author Trass3r
date Wed, 01 Sep 2010 18:21:58 +0200
parents cab4c37afb89
children af724d3510d7
line wrap: on
line source

module dmd.Catch;

import dmd.common;
import dmd.Loc;
import dmd.Type;
import dmd.Scope;
import dmd.Identifier;
import dmd.VarDeclaration;
import dmd.Statement;
import dmd.OutBuffer;
import dmd.Id;
import dmd.TypeIdentifier;
import dmd.Util;
import dmd.ScopeDsymbol;
import dmd.HdrGenState;
import dmd.BE;

class Catch
{
    Loc loc;
    Type type;
    Identifier ident;
    VarDeclaration var = null;
    Statement handler;

    this(Loc loc, Type t, Identifier id, Statement handler)
	{
		//printf("Catch(%s, loc = %s)\n", id.toChars(), loc.toChars());
		this.loc = loc;
		this.type = t;
		this.ident = id;
		this.handler = handler;
	}

    Catch syntaxCopy()
	{
		Catch c = new Catch(loc, (type ? type.syntaxCopy() : null), ident, (handler ? handler.syntaxCopy() : null));
		return c;
	}

    void semantic(Scope sc)
	{
		ScopeDsymbol sym;

		//printf("Catch.semantic(%s)\n", ident.toChars());

	version (IN_GCC) {
	} else {
		if (sc.tf)
		{
			/* This is because the _d_local_unwind() gets the stack munged
			 * up on this. The workaround is to place any try-catches into
			 * a separate function, and call that.
			 * To fix, have the compiler automatically convert the finally
			 * body into a nested function.
			 */
			error(loc, "cannot put catch statement inside finally block");
		}
	}

		sym = new ScopeDsymbol();
		sym.parent = sc.scopesym;
		sc = sc.push(sym);

		if (!type)
			type = new TypeIdentifier(Loc(0), Id.Object_);
		type = type.semantic(loc, sc);
		if (!type.toBasetype().isClassHandle())
			error("can only catch class objects, not '%s'", type.toChars());
		else if (ident)
		{
			var = new VarDeclaration(loc, type, ident, null);
			var.parent = sc.parent;
			sc.insert(var);
		}
		handler = handler.semantic(sc);

		sc.pop();
	}

    BE blockExit()
	{
		return handler ? handler.blockExit() : BE.BEfallthru;
	}

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