Mercurial > projects > ddmd
view dmd/ArrayScopeSymbol.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | e28b18c23469 |
children | b0d41ff5e0df |
line wrap: on
line source
module dmd.ArrayScopeSymbol; import dmd.common; import dmd.ScopeDsymbol; import dmd.Expression; import dmd.TypeTuple; import dmd.TupleDeclaration; import dmd.Scope; import dmd.Dsymbol; import dmd.Loc; import dmd.TOK; import dmd.Identifier; import dmd.Id; import dmd.TY; import dmd.TupleExp; import dmd.StringExp; import dmd.WANT; import dmd.TypeExp; import dmd.Type; import dmd.SliceExp; import dmd.IndexExp; import dmd.IntegerExp; import dmd.STC; import dmd.ExpInitializer; import dmd.VarDeclaration; import dmd.ArrayLiteralExp; import dmd.expression.Util; class ArrayScopeSymbol : ScopeDsymbol { Expression exp; // IndexExp or SliceExp TypeTuple type; // for tuple[length] TupleDeclaration td; // for tuples of objects Scope sc; this(Scope sc, Expression e) { register(); super(); assert(e.op == TOKindex || e.op == TOKslice); this.exp = e; this.sc = sc; } this(Scope sc, TypeTuple t) { register(); exp = null; type = t; td = null; this.sc = sc; } this(Scope sc, TupleDeclaration s) { register(); exp = null; type = null; td = s; this.sc = sc; } override Dsymbol search(Loc loc, Identifier ident, int flags) { //printf("ArrayScopeSymbol.search('%s', flags = %d)\n", ident.toChars(), flags); if (ident == Id.length || ident == Id.dollar) { VarDeclaration* pvar; Expression ce; L1: if (td) { /* $ gives the number of elements in the tuple */ VarDeclaration v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null); Expression e = new IntegerExp(Loc(0), td.objects.dim, Type.tsize_t); v.init = new ExpInitializer(Loc(0), e); v.storage_class |= STCstatic | STCconst; v.semantic(sc); return v; } if (type) { /* $ gives the number of type entries in the type tuple */ VarDeclaration v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null); Expression e = new IntegerExp(Loc(0), type.arguments.dim, Type.tsize_t); v.init = new ExpInitializer(Loc(0), e); v.storage_class |= STCstatic | STCconst; v.semantic(sc); return v; } if (exp.op == TOKindex) { /* array[index] where index is some function of $ */ IndexExp ie = cast(IndexExp)exp; pvar = &ie.lengthVar; ce = ie.e1; } else if (exp.op == TOKslice) { /* array[lwr .. upr] where lwr or upr is some function of $ */ SliceExp se = cast(SliceExp)exp; pvar = &se.lengthVar; ce = se.e1; } else /* Didn't find $, look in enclosing scope(s). */ return null; /* If we are indexing into an array that is really a type * tuple, rewrite this as an index into a type tuple and * try again. */ if (ce.op == TOKtype) { Type t = (cast(TypeExp)ce).type; if (t.ty == Ttuple) { type = cast(TypeTuple)t; goto L1; } } /* *pvar is lazily initialized, so if we refer to $ * multiple times, it gets set only once. */ if (!*pvar) // if not already initialized { /* Create variable v and set it to the value of $, * which will be a constant. */ VarDeclaration v = new VarDeclaration(loc, Type.tsize_t, Id.dollar, null); if (ce.op == TOKvar) { // if ce is const, get its initializer ce = fromConstInitializer(WANTvalue | WANTinterpret, ce); } if (ce.op == TOKstring) { /* It is for a string literal, so the * length will be a const. */ Expression e = new IntegerExp(Loc(0), (cast(StringExp)ce).len, Type.tsize_t); v.init = new ExpInitializer(Loc(0), e); v.storage_class |= STCstatic | STCconst; } else if (ce.op == TOKarrayliteral) { /* It is for an array literal, so the * length will be a const. */ Expression e = new IntegerExp(Loc(0), (cast(ArrayLiteralExp)ce).elements.dim, Type.tsize_t); v.init = new ExpInitializer(Loc(0), e); v.storage_class |= STCstatic | STCconst; } else if (ce.op == TOKtuple) { /* It is for an expression tuple, so the * length will be a const. */ Expression e = new IntegerExp(Loc(0), (cast(TupleExp)ce).exps.dim, Type.tsize_t); v.init = new ExpInitializer(Loc(0), e); v.storage_class |= STCstatic | STCconst; } *pvar = v; } (*pvar).semantic(sc); return (*pvar); } return null; } override ArrayScopeSymbol isArrayScopeSymbol() { return this; } }