Mercurial > projects > ddmd
view dmd/TypeTypeof.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
line wrap: on
line source
module dmd.TypeTypeof; import dmd.common; import dmd.TypeFunction; 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; import dmd.DDMDExtensions; class TypeTypeof : TypeQualified { mixin insertMemberExtension!(typeof(this)); Expression exp; this(Loc loc, Expression exp) { register(); super(TY.Ttypeof, loc); this.exp = exp; } override Type syntaxCopy() { //printf("TypeTypeof.syntaxCopy() %s\n", toChars()); TypeTypeof t; t = new TypeTypeof(loc, exp.syntaxCopy()); t.syntaxCopyHelper(this); t.mod = mod; return t; } override Dsymbol toDsymbol(Scope sc) { Type t = semantic(loc, sc); if (t is this) return null; return t.toDsymbol(sc); } override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { if (mod != this.mod) { toCBuffer3(buf, hgs, mod); return; } buf.writestring("typeof("); exp.toCBuffer(buf, hgs); buf.writeByte(')'); toCBuffer2Helper(buf, hgs); } override Type semantic(Loc loc, Scope sc) { Expression e; Type t; //printf("TypeTypeof.semantic() %.*s\n", toChars()); //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); if (exp.type && exp.type.ty == Tfunction && (cast(TypeFunction)exp.type).isproperty) exp = resolveProperties(sc, exp); sc.intypeof--; if (exp.op == TOK.TOKtype) { error(loc, "argument %s to typeof is not an expression", exp.toChars()); goto Lerr; } 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()); goto Lerr; } /* 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; } override ulong size(Loc loc) { assert(false); } }