view dmd/ConditionalDeclaration.d @ 32:81796b717a39

A few bad cast fixed. TODO: either get rid of dyncast(), or derive all objects from intermediate supertype.
author korDen
date Tue, 18 May 2010 17:51:46 +0400
parents 460959608115
children 2e2a5c3f943a
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;
    Array elsedecl;	// array of Dsymbol's for else block

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

    assert(!s);
    dd = new ConditionalDeclaration(condition.syntaxCopy(),
	Dsymbol.arraySyntaxCopy(decl),
	Dsymbol.arraySyntaxCopy(elsedecl));
    return dd;
	}
	
    bool oneMember(Dsymbol* ps)
	{
		//printf("ConditionalDeclaration.oneMember(), inc = %d\n", condition.inc);
		if (condition.inc)
		{
			Array d = condition.include(null, null) ? decl : elsedecl;
			return Dsymbol.oneMembers(d, ps);
		}
		*ps = null;
		return true;
	}
	
    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.
	 */
	Array d = decl ? decl : elsedecl;
	for (uint i = 0; i < d.dim; i++)
	{   Dsymbol s = cast(Dsymbol)d.data[i];
	    s.emitComment(sc);
	}
    }
	}
	
	// Decide if 'then' or 'else' code should be included

    Array include(Scope sc, ScopeDsymbol sd)
	{
		//printf("ConditionalDeclaration.include()\n");
		assert(condition);
		return condition.include(sc, sd) ? decl : elsedecl;
	}
	
    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)
		{
			Array d = decl;

			for (int j = 0; j < 2; j++)
			{
				if (d)
				{
					for (uint i = 0; i < d.dim; i++)
					{   
						Dsymbol s = cast(Dsymbol)d.data[i];
						//printf("ConditionalDeclaration::addComment %s\n", s.toChars());
						s.addComment(comment);
					}
				}
				d = elsedecl;
			}
		}
	}
	
    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();
	}
}