view dmd/TypeTypeof.d @ 51:b7d29f613539

StaticAssertStatement.syntaxCopy IfStatement.syntaxCopy CompoundDeclarationStatement.syntaxCopy VoidInitializer.syntaxCopy TypeAArray.syntaxCopy TypeTypeof.syntaxCopy TypeAArray.resolve TypeSArray.deduceType TypeAArray.deduceType TypeAArray.implicitConvTo TemplateDeclaration.leastAsSpecialized TemplateTypeParameter.dummyArg TypeIdentifier.deduceType TemplateTypeParameter.syntaxCopy Lexer.hexStringConstant Lexer.delimitedStringConstant GotoDefaultStatement.ctor CaseRangeStatement.ctor Type.castMod StorageClassDeclaration.syntaxCopy TemplateDeclaration.syntaxCopy
author korDen
date Sat, 21 Aug 2010 11:17:42 +0400
parents 10317f0c89a5
children a8740d0dbea4
line wrap: on
line source

module dmd.TypeTypeof;

import dmd.TypeQualified;
import dmd.Expression;
import dmd.Identifier;
import dmd.Scope;
import dmd.Loc;
import dmd.MOD;
import dmd.Type;
import dmd.Dsymbol;
import dmd.OutBuffer;
import dmd.HdrGenState;
import dmd.TY;
import dmd.Util;
import dmd.TOK;

class TypeTypeof : TypeQualified
{
    Expression exp;

    this(Loc loc, Expression exp)
	{
		super(TY.Ttypeof, loc);
		this.exp = exp;
	}
	
version (DumbClone) {
} else {
	Type clone()
	{
		assert(false);
	}
}
	
    Type syntaxCopy()
	{
		//printf("TypeTypeof.syntaxCopy() %s\n", toChars());
		TypeTypeof t;

		t = new TypeTypeof(loc, exp.syntaxCopy());
		t.syntaxCopyHelper(this);
		t.mod = mod;
		return t;
	}
	
    Dsymbol toDsymbol(Scope sc)
	{
		Type t = semantic(loc, sc);
		if (t is this)
			return null;

		return t.toDsymbol(sc);
	}
	
    void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)
	{
		assert(false);
	}

    Type semantic(Loc loc, Scope sc)
	{
		Expression e;
		Type t;

		//printf("TypeTypeof.semantic() %p\n", this);

		//static int nest; if (++nest == 50) *(char*)0=0;

/+static if (false) {
		/* Special case for typeof(this) and typeof(super) since both
		 * should work even if they are not inside a non-static member function
		 */
		if (exp.op == TOK.TOKthis || exp.op == TOK.TOKsuper)
		{
			/ / Find enclosing struct or class
			for (Dsymbol *s = sc.parent; 1; s = s.parent)
			{
				ClassDeclaration *cd;
				StructDeclaration *sd;

				if (!s)
				{
				error(loc, "%s is not in a struct or class scope", exp.toChars());
				goto Lerr;
				}
				cd = s.isClassDeclaration();
				if (cd)
				{
				if (exp.op == TOK.TOKsuper)
				{
					cd = cd.baseClass;
					if (!cd)
					{	error(loc, "class %s has no 'super'", s.toChars());
					goto Lerr;
					}
				}
				t = cd.type;
				break;
				}
				sd = s.isStructDeclaration();
				if (sd)
				{
				if (exp.op == TOK.TOKsuper)
				{
					error(loc, "struct %s has no 'super'", sd.toChars());
					goto Lerr;
				}
				t = sd.type.pointerTo();
				break;
				}
			}
		}
		else
}+/
		{
			sc.intypeof++;
			exp = exp.semantic(sc);
			sc.intypeof--;
			if (exp.op == TOK.TOKtype)
			{
				error(loc, "argument %s to typeof is not an expression", exp.toChars());
			}
			t = exp.type;
			if (!t)
			{
				error(loc, "expression (%s) has no type", exp.toChars());
				goto Lerr;
			}
			if (t.ty == TY.Ttypeof)
				error(loc, "forward reference to %s", toChars());

			/* typeof should reflect the true type,
			 * not what 'auto' would have gotten us.
			 */
			//t = t.toHeadMutable();
		}
		if (idents.dim)
		{
			Dsymbol s = t.toDsymbol(sc);
			for (size_t i = 0; i < idents.dim; i++)
			{
				if (!s)
				break;
				Identifier id = cast(Identifier)idents.data[i];
				s = s.searchX(loc, sc, id);
			}

			if (s)
			{
				t = s.getType();
				if (!t)
				{	
					error(loc, "%s is not a type", s.toChars());
					goto Lerr;
				}
			}
			else
			{   
				error(loc, "cannot resolve .property for %s", toChars());
				goto Lerr;
			}
		}
		return t;

	Lerr:
		return tvoid;
	}
	
    ulong size(Loc loc)
	{
		assert(false);
	}
}