view dmd/ConditionalDeclaration.d @ 74:7e0d548de9e6

Switch Arrays of Dsymbols to the new templated Vector type
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Sun, 29 Aug 2010 09:43:40 +0100
parents 2e2a5c3f943a
children ad4792a1cfd6
line wrap: on
line source

module dmd.ConditionalDeclaration;

import dmd.AttribDeclaration;
import dmd.Condition;
import dmd.Array;
import dmd.Dsymbol;
import dmd.Scope;
import dmd.ScopeDsymbol;
import dmd.OutBuffer;
import dmd.HdrGenState;

class ConditionalDeclaration : AttribDeclaration
{
    Condition condition;
    Dsymbols elsedecl;	// array of Dsymbol's for else block

    this(Condition condition, Dsymbols decl, Dsymbols elsedecl)
	{
		super(decl);
		//printf("ConditionalDeclaration.ConditionalDeclaration()\n");
		this.condition = condition;
		this.elsedecl = elsedecl;
	}
	
    override Dsymbol syntaxCopy(Dsymbol s)
	{
    ConditionalDeclaration dd;

    assert(!s);
    dd = new ConditionalDeclaration(condition.syntaxCopy(),
	Dsymbol.arraySyntaxCopy(decl),
	Dsymbol.arraySyntaxCopy(elsedecl));
    return dd;
	}
	
    override bool oneMember(Dsymbol* ps)
	{
		//printf("ConditionalDeclaration.oneMember(), inc = %d\n", condition.inc);
		if (condition.inc)
		{
			auto d = condition.include(null, null) ? decl : elsedecl;
			return Dsymbol.oneMembers(d, ps);
		}
		*ps = null;
		return true;
	}
	
    override void emitComment(Scope sc)
	{
    //printf("ConditionalDeclaration.emitComment(sc = %p)\n", sc);
    if (condition.inc)
    {
	AttribDeclaration.emitComment(sc);
    }
    else if (sc.docbuf)
    {
	/* If generating doc comment, be careful because if we're inside
	 * a template, then include(NULL, NULL) will fail.
	 */
	auto d = decl ? decl : elsedecl;
	foreach(s; d)
	    s.emitComment(sc);
    }
	}
	
	// Decide if 'then' or 'else' code should be included

    override Dsymbols include(Scope sc, ScopeDsymbol sd)
	{
		//printf("ConditionalDeclaration.include()\n");
		assert(condition);
		return condition.include(sc, sd) ? decl : elsedecl;
	}
	
    override void addComment(ubyte* comment)
	{
		/* Because addComment is called by the parser, if we called
		 * include() it would define a version before it was used.
		 * But it's no problem to drill down to both decl and elsedecl,
		 * so that's the workaround.
		 */

		if (comment)
		{
			auto d = decl;

			for (int j = 0; j < 2; j++)
			{
				if (d)
				{
					foreach(s; d)
						//printf("ConditionalDeclaration::addComment %s\n", s.toChars());
						s.addComment(comment);
				}
				d = elsedecl;
			}
		}
	}
	
    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
	{
    condition.toCBuffer(buf, hgs);
    if (decl || elsedecl)
    {
	buf.writenl();
	buf.writeByte('{');
	buf.writenl();
	if (decl)
	{
	    for (uint i = 0; i < decl.dim; i++)
	    {
		Dsymbol s = cast(Dsymbol)decl.data[i];

		buf.writestring("    ");
		s.toCBuffer(buf, hgs);
	    }
	}
	buf.writeByte('}');
	if (elsedecl)
	{
	    buf.writenl();
	    buf.writestring("else");
	    buf.writenl();
	    buf.writeByte('{');
	    buf.writenl();
	    for (uint i = 0; i < elsedecl.dim; i++)
	    {
		Dsymbol s = cast(Dsymbol)elsedecl.data[i];

		buf.writestring("    ");
		s.toCBuffer(buf, hgs);
	    }
	    buf.writeByte('}');
	}
    }
    else
	buf.writeByte(':');
    buf.writenl();
	}
}