view dmd/TypedefDeclaration.d @ 135:af1bebfd96a4 dmd2037

dmd 2.038
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Mon, 13 Sep 2010 22:19:42 +0100
parents e28b18c23469
children 14feb7ae01a6
line wrap: on
line source

module dmd.TypedefDeclaration;

import dmd.common;
import dmd.Declaration;
import dmd.Initializer;
import dmd.Type;
import dmd.Loc;
import dmd.Identifier;
import dmd.Dsymbol;
import dmd.Module;
import dmd.Scope;
import dmd.OutBuffer;
import dmd.ExpInitializer;
import dmd.HdrGenState;
import dmd.TypeTypedef;
import dmd.Global;
import dmd.STC;
import dmd.Id;

import dmd.backend.SC;
import dmd.backend.FL;
import dmd.backend.SFL;
import dmd.backend.Symbol;
import dmd.backend.Util;
import dmd.backend.LIST;
import dmd.backend.Classsym;
import dmd.codegen.Util;

class TypedefDeclaration : Declaration
{
    Type basetype;
    Initializer init;
    int sem = 0;// 0: semantic() has not been run
				// 1: semantic() is in progress
				// 2: semantic() has been run
				// 3: semantic2() has been run

    this(Loc loc, Identifier id, Type basetype, Initializer init)
	{
		super(id);
		
		this.type = new TypeTypedef(this);
		this.basetype = basetype.toBasetype();
		this.init = init;

	version (_DH) {
		this.htype = null;
		this.hbasetype = null;
	}
		this.loc = loc;
		this.sinit = null;
	}
	
version (DumbClone) {
} else {
	Type clone()
	{
		assert(false);
	}
}
    override Dsymbol syntaxCopy(Dsymbol)
	{
		assert(false);
	}
	
    override void semantic(Scope sc)
	{
		//printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
		if (sem == 0)
		{	
			sem = 1;
			basetype = basetype.semantic(loc, sc);
			sem = 2;
version(DMDV2) {
    	    type = type.addStorageClass(storage_class);
}
			type = type.semantic(loc, sc);
			if (sc.parent.isFuncDeclaration() && init)
				semantic2(sc);
			storage_class |= sc.stc & STCdeprecated;
		}
		else if (sem == 1)
		{
			error("circular definition");
		}
	}
	
    override void semantic2(Scope sc)
	{
		//printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
		if (sem == 2)
		{	
			sem = 3;
			if (init)
			{
				init = init.semantic(sc, basetype);

				ExpInitializer ie = init.isExpInitializer();
				if (ie)
				{
					if (ie.exp.type == basetype)
						ie.exp.type = type;
				}
			}
		}
	}
	
    override string mangle()
	{
		//printf("TypedefDeclaration::mangle() '%s'\n", toChars());
		return Dsymbol.mangle();
	}
	
    override string kind()
	{
		assert(false);
	}
	
    override Type getType()
	{
		return type;
	}
	
    override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
	{
		assert(false);
	}

version (_DH) {
    Type htype;
    Type hbasetype;
}

    override void toDocBuffer(OutBuffer buf)
	{
		assert(false);
	}

    override void toObjFile(int multiobj)			// compile to .obj file
	{
		//printf("TypedefDeclaration::toObjFile('%s')\n", toChars());
		if (global.params.symdebug)
			toDebug();

		type.getTypeInfo(null);	// generate TypeInfo

		TypeTypedef tc = cast(TypeTypedef)type;
		if (type.isZeroInit(Loc(0)) || !tc.sym.init) {
			;
		} else
		{
			SC scclass = SCglobal;
			if (inTemplateInstance())
				scclass = SCcomdat;

			// Generate static initializer
			toInitializer();
			sinit.Sclass = scclass;
			sinit.Sfl = FLdata;

		version (ELFOBJ) { // Burton
			sinit.Sseg = Segment.CDATA;
		}
		version (MACHOBJ) {
			sinit.Sseg = Segment.DATA;
		}
			sinit.Sdt = tc.sym.init.toDt();
			outdata(sinit);
		}
	}
	
    void toDebug()
	{
		assert(false);
	}
	
    override int cvMember(ubyte* p)
	{
		assert(false);
	}

    override TypedefDeclaration isTypedefDeclaration() { return this; }

    Symbol* sinit;
    Symbol* toInitializer()
	{
		Symbol* s;
		Classsym* stag;

		if (!sinit)
		{
			stag = fake_classsym(Id.ClassInfo);
			s = toSymbolX("__init", SCextern, stag.Stype, "Z");
			s.Sfl = FLextern;
			s.Sflags |= SFLnodebug;
			slist_add(s);
			sinit = s;
		}
		return sinit;
	}
}