view dmd/TypeQualified.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 69d078c417c6
children 2e2a5c3f943a
line wrap: on
line source

module dmd.TypeQualified;

import dmd.Type;
import dmd.Import;
import dmd.TypeExp;
import dmd.DotIdExp;
import dmd.VarDeclaration;
import dmd.EnumMember;
import dmd.TupleDeclaration;
import dmd.Id;
import dmd.VarExp;
import dmd.TemplateInstance;
import dmd.Loc;
import dmd.Array;
import dmd.TY;
import dmd.Identifier;
import dmd.OutBuffer;
import dmd.HdrGenState;
import dmd.Scope;
import dmd.Dsymbol;
import dmd.DYNCAST;
import dmd.Expression;
import dmd.Util;

class TypeQualified : Type
{
    Loc loc;
    Array idents;	// array of Identifier's representing ident.ident.ident etc.

    this(TY ty, Loc loc)
	{
		super(ty);
		this.loc = loc;
		
		idents = new Array();
	}
	
version (DumbClone) {
} else {
	Type clone()
	{
		assert(false);
	}
}	
    void syntaxCopyHelper(TypeQualified t)
	{
		//printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
		idents.setDim(t.idents.dim);
		for (int i = 0; i < idents.dim; i++)
		{
			Object o = cast(Object)t.idents.data[i];
			if (TemplateInstance ti = cast(TemplateInstance)o)
			{
				o = ti.syntaxCopy(null);
			}

			idents.data[i] = cast(void*)o;
		}
	}
	
    void addIdent(Object ident)
	{
		assert(ident !is null);
		idents.push(cast(void*)ident);
	}
	
    void toCBuffer2Helper(OutBuffer buf, HdrGenState* hgs)
	{
		int i;

		for (i = 0; i < idents.dim; i++)
		{
			Identifier id = cast(Identifier)idents.data[i];
			buf.writeByte('.');

			if (id.dyncast() == DYNCAST.DYNCAST_DSYMBOL)
			{
				TemplateInstance ti = cast(TemplateInstance)id;
				ti.toCBuffer(buf, hgs);
			} else {
				buf.writestring(id.toChars());
			}
		}
	}
	
    ulong size(Loc loc)
	{
		assert(false);
	}
	
	/*************************************
	* Takes an array of Identifiers and figures out if
	 * it represents a Type or an Expression.
	 * Output:
	 *	if expression, *pe is set
	 *	if type, *pt is set
	 */
    void resolveHelper(Loc loc, Scope sc, Dsymbol s, Dsymbol scopesym, Expression* pe, Type* pt, Dsymbol* ps)
	{
		VarDeclaration v;
		EnumMember em;
		TupleDeclaration td;
		Expression e;

static if (false) {
		printf("TypeQualified.resolveHelper(sc = %p, idents = '%s')\n", sc, toChars());
		if (scopesym)
			printf("\tscopesym = '%s'\n", scopesym.toChars());
}
		*pe = null;
		*pt = null;
		*ps = null;
		if (s)
		{
			//printf("\t1: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
			s.checkDeprecated(loc, sc);		// check for deprecated aliases
			s = s.toAlias();
			//printf("\t2: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
			for (int i = 0; i < idents.dim; i++)
			{
				Object o = cast(Object)idents.data[i];
				
				Dsymbol sm = s.searchX(loc, sc, o);
				Identifier id = cast(Identifier)o;
				//printf("\t3: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
				//printf("\tgetType = '%s'\n", s.getType().toChars());
				if (!sm)
				{	
					Type t;

					v = s.isVarDeclaration();
					if (v && id == Id.length)
					{
						e = v.getConstInitializer();
						if (!e)
							e = new VarExp(loc, v);
						t = e.type;
						if (!t)
						goto Lerror;
						goto L3;
					}
					t = s.getType();
					if (!t && s.isDeclaration())
						t = s.isDeclaration().type;
					if (t)
					{
						sm = t.toDsymbol(sc);
						if (sm)
						{	sm = sm.search(loc, id, 0);
						if (sm)
							goto L2;
						}
						//e = t.getProperty(loc, id);
						e = new TypeExp(loc, t);
						e = t.dotExp(sc, e, id);
						i++;
					L3:
						for (; i < idents.dim; i++)
						{
							id = cast(Identifier)idents.data[i];
							//printf("e: '%s', id: '%s', type = %p\n", e.toChars(), id.toChars(), e.type);
							if (id == Id.offsetof)
							{   e = new DotIdExp(e.loc, e, id);
								e = e.semantic(sc);
							}
							else
								e = e.type.dotExp(sc, e, id);
						}
						*pe = e;
					}
					else
					  Lerror:
						error(loc, "identifier '%s' of '%s' is not defined", id.toChars(), toChars());
					return;
				}
			L2:
				s = sm.toAlias();
			}

			v = s.isVarDeclaration();
			if (v)
			{
///static if (false) {
///				// It's not a type, it's an expression
///				Expression *e = v.getConstInitializer();
///				if (e)
///				{
///					*pe = e.copy();	// make copy so we can change loc
///					(*pe).loc = loc;
///				}
///				else
///}
				{
///static if (false) {
///					WithScopeSymbol withsym;
///					if (scopesym && (withsym = scopesym.isWithScopeSymbol()) !is null)
///					{
///						// Same as wthis.ident
///						e = new VarExp(loc, withsym.withstate.wthis);
///						e = new DotIdExp(loc, e, ident);
///						//assert(0);	// BUG: should handle this
///					}
///					else
///}
						*pe = new VarExp(loc, v);
				}
				return;
			}
			em = s.isEnumMember();
			if (em)
			{
				// It's not a type, it's an expression
				*pe = em.value.copy();
				return;
			}

		L1:
			Type t = s.getType();
			if (!t)
			{
				// If the symbol is an import, try looking inside the import
				Import si;

				si = s.isImport();
				if (si)
				{
					s = si.search(loc, s.ident, 0);
					if (s && s != si)
						goto L1;
					s = si;
				}
				*ps = s;
				return;
			}
			if (t.ty == TY.Tinstance && t != this && !t.deco)
			{   
				error(loc, "forward reference to '%s'", t.toChars());
				return;
			}

			if (t != this)
			{
				if (t.reliesOnTident())
				{
					Scope scx;

					for (scx = sc; 1; scx = scx.enclosing)
					{
						if (!scx)
						{   
							error(loc, "forward reference to '%s'", t.toChars());
							return;
						}
						if (scx.scopesym == scopesym)
							break;
					}
					t = t.semantic(loc, scx);
					//((TypeIdentifier *)t).resolve(loc, scx, pe, &t, ps);
				}
			}
			if (t.ty == TY.Ttuple)
				*pt = t;
			else
				*pt = t.merge();
		}
		if (!s)
		{
			error(loc, "identifier '%s' is not defined", toChars());
		}
	}
}