Mercurial > projects > ddmd
diff dmd/ThisExp.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | cab4c37afb89 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/ThisExp.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,189 @@ +module dmd.ThisExp; + +import dmd.Expression; +import dmd.Declaration; +import dmd.StructDeclaration; +import dmd.ClassDeclaration; +import dmd.Dsymbol; +import dmd.FuncDeclaration; +import dmd.backend.elem; +import dmd.CSX; +import dmd.InterState; +import dmd.OutBuffer; +import dmd.Loc; +import dmd.Scope; +import dmd.Type; +import dmd.TOK; +import dmd.InlineCostState; +import dmd.InlineDoState; +import dmd.IRState; +import dmd.HdrGenState; +import dmd.VarExp; +import dmd.TY; + +import dmd.codegen.Util; +import dmd.backend.TYM; +import dmd.backend.Util; +import dmd.backend.OPER; + +class ThisExp : Expression +{ + Declaration var; + + this(Loc loc) + { + super(loc, TOK.TOKthis, ThisExp.sizeof); + //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum); + } + + Expression semantic(Scope sc) + { + FuncDeclaration fd; + FuncDeclaration fdthis; + + version (LOGSEMANTIC) { + printf("ThisExp::semantic()\n"); + } + if (type) + { + //assert(global.errors || var); + return this; + } + + /* Special case for typeof(this) and typeof(super) since both + * should work even if they are not inside a non-static member function + */ + if (sc.intypeof) + { + // Find enclosing struct or class + for (Dsymbol s = sc.parent; 1; s = s.parent) + { + if (!s) + { + error("%s is not in a class or struct scope", toChars()); + goto Lerr; + } + ClassDeclaration cd = s.isClassDeclaration(); + if (cd) + { + type = cd.type; + return this; + } + StructDeclaration sd = s.isStructDeclaration(); + if (sd) + { + version (STRUCTTHISREF) { + type = sd.type; + } else { + type = sd.type.pointerTo(); + } + return this; + } + } + } + + fdthis = sc.parent.isFuncDeclaration(); + fd = hasThis(sc); // fd is the uplevel function with the 'this' variable + if (!fd) + goto Lerr; + + assert(fd.vthis); + var = fd.vthis; + assert(var.parent); + type = var.type; + var.isVarDeclaration().checkNestedReference(sc, loc); + if (!sc.intypeof) + sc.callSuper |= CSXthis; + return this; + + Lerr: + error("'this' is only defined in non-static member functions, not %s", sc.parent.toChars()); + type = Type.terror; + return this; + } + + Expression interpret(InterState* istate) + { + assert(false); + } + + bool isBool(bool result) + { + return result ? true : false; + } + + void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + buf.writestring("this"); + } + +version (DMDV2) { + int isLvalue() + { + return 1; + } +} + Expression toLvalue(Scope sc, Expression e) + { + return this; + } + + void scanForNestedRef(Scope sc) + { + assert(false); + } + + int inlineCost(InlineCostState* ics) + { + FuncDeclaration fd = ics.fd; + if (!ics.hdrscan) + if (fd.isNested() || !ics.hasthis) + return COST_MAX; + + return 1; + } + + Expression doInline(InlineDoState ids) + { + //if (!ids.vthis) + //error("no 'this' when inlining %s", ids.parent.toChars()); + if (!ids.vthis) + { + return this; + } + + VarExp ve = new VarExp(loc, ids.vthis); + ve.type = type; + return ve; + } + + elem* toElem(IRState* irs) + { + elem* ethis; + FuncDeclaration fd; + + //printf("ThisExp::toElem()\n"); + assert(irs.sthis); + + if (var) + { + assert(var.parent); + fd = var.toParent2().isFuncDeclaration(); + assert(fd); + ethis = getEthis(loc, irs, fd); + } + else + ethis = el_var(irs.sthis); + + version (STRUCTTHISREF) { + if (type.ty == Tstruct) + { + ethis = el_una(OPind, TYstruct, ethis); + ethis.Enumbytes = cast(uint)type.size(); + } + } + el_setLoc(ethis,loc); + return ethis; + } +} +