Mercurial > projects > ddmd
view dmd/CompoundStatement.d @ 32:81796b717a39
A few bad cast fixed. TODO: either get rid of dyncast(), or derive all objects from intermediate supertype.
author | korDen |
---|---|
date | Tue, 18 May 2010 17:51:46 +0400 |
parents | 0613413fa94c |
children | cab4c37afb89 |
line wrap: on
line source
module dmd.CompoundStatement; import dmd.Loc; import dmd.Statement; import dmd.Array; import dmd.TryCatchStatement; import dmd.TryFinallyStatement; import dmd.Catch; import dmd.ScopeStatement; import dmd.Identifier; import dmd.Lexer; import dmd.ThrowStatement; import dmd.IdentifierExp; import dmd.Scope; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.ArrayTypes; import dmd.ReturnStatement; import dmd.Expression; import dmd.InterState; import dmd.InlineDoState; import dmd.InlineCostState; import dmd.InlineScanState; import dmd.IfStatement; import dmd.IRState; import dmd.BE; import dmd.Util; class CompoundStatement : Statement { Statements statements; this(Loc loc, Statements s) { super(loc); statements = s; } this(Loc loc, Statement s1, Statement s2) { super(loc); statements = new Statements(); statements.reserve(2); statements.push(cast(void*)s1); statements.push(cast(void*)s2); } Statement syntaxCopy() { Statements a = new Statements(); a.setDim(statements.dim); for (size_t i = 0; i < statements.dim; i++) { Statement s = cast(Statement)statements.data[i]; if (s) s = s.syntaxCopy(); a.data[i] = cast(void*)s; } return new CompoundStatement(loc, a); } void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } static int indent = 0; static int depth = 0; Statement semantic(Scope sc) { Statement s; //printf("CompoundStatement.semantic(this = %p, sc = %p)\n", this, sc); for (size_t i = 0; i < statements.dim; ) { s = cast(Statement) statements.data[i]; if (s) { Statements a = s.flatten(sc); if (a) { statements.remove(i); statements.insert(i, a); continue; } s = s.semantic(sc); statements.data[i] = cast(void*)s; if (s) { Statement sentry; Statement sexception; Statement sfinally; s.scopeCode(sc, &sentry, &sexception, &sfinally); if (sentry) { sentry = sentry.semantic(sc); if (s.isDeclarationStatement()) { statements.insert(i, cast(void*)sentry); i++; } else statements.data[i] = cast(void*)sentry; } if (sexception) { if (i + 1 == statements.dim && !sfinally) { static if (true) { sexception = sexception.semantic(sc); } else { statements.push(sexception); if (sfinally) // Assume sexception does not throw statements.push(sfinally); } } else { /* Rewrite: * s; s1; s2; * As: * s; * try { s1; s2; } * catch (Object __o) * { sexception; throw __o; } */ Statement body_; Statements aa = new Statements(); for (int j = i + 1; j < statements.dim; j++) { aa.push(statements.data[j]); } body_ = new CompoundStatement(Loc(0), aa); body_ = new ScopeStatement(Loc(0), body_); Identifier id = Lexer.uniqueId("__o"); Statement handler = new ThrowStatement(Loc(0), new IdentifierExp(Loc(0), id)); handler = new CompoundStatement(Loc(0), sexception, handler); Array catches = new Array(); Catch ctch = new Catch(Loc(0), null, id, handler); catches.push(cast(void*)ctch); s = new TryCatchStatement(Loc(0), body_, catches); if (sfinally) s = new TryFinallyStatement(Loc(0), s, sfinally); s = s.semantic(sc); statements.setDim(i + 1); statements.push(cast(void*)s); break; } } else if (sfinally) { if (0 && i + 1 == statements.dim) { statements.push(cast(void*)sfinally); } else { /* Rewrite: * s; s1; s2; * As: * s; try { s1; s2; } finally { sfinally; } */ Statement body_; Statements aa = new Statements(); for (int j = i + 1; j < statements.dim; j++) { aa.push(statements.data[j]); } body_ = new CompoundStatement(Loc(0), aa); s = new TryFinallyStatement(Loc(0), body_, sfinally); s = s.semantic(sc); statements.setDim(i + 1); statements.push(cast(void*)s); break; } } } } i++; } if (statements.dim == 1) { return cast(Statement)statements.data[0]; } return this; } bool usesEH() { assert(false); } BE blockExit() { //printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim); BE result = BE.BEfallthru; for (size_t i = 0; i < statements.dim; i++) { Statement s = cast(Statement)statements.data[i]; if (s) { //printf("result = x%x\n", result); //printf("%s\n", s->toChars()); if (!(result & BE.BEfallthru) && !s.comeFrom()) { if (s.blockExit() != BE.BEhalt) s.warning("statement is not reachable"); } result &= ~BE.BEfallthru; result |= s.blockExit(); } } return result; } bool comeFrom() { assert(false); } bool isEmpty() { for (int i = 0; i < statements.dim; i++) { Statement s = cast(Statement) statements.data[i]; if (s && !s.isEmpty()) return false; } return true; } Statements flatten(Scope sc) { return statements; } ReturnStatement isReturnStatement() { ReturnStatement rs = null; for (int i = 0; i < statements.dim; i++) { Statement s = cast(Statement) statements.data[i]; if (s) { rs = s.isReturnStatement(); if (rs) break; } } return rs; } Expression interpret(InterState* istate) { assert(false); } int inlineCost(InlineCostState* ics) { int cost = 0; for (size_t i = 0; i < statements.dim; i++) { Statement s = cast(Statement)statements.data[i]; if (s) { cost += s.inlineCost(ics); if (cost >= COST_MAX) break; } } return cost; } Expression doInline(InlineDoState ids) { Expression e = null; //printf("CompoundStatement.doInline() %d\n", statements.dim); for (size_t i = 0; i < statements.dim; i++) { Statement s = cast(Statement)statements.data[i]; if (s) { Expression e2 = s.doInline(ids); e = Expression.combine(e, e2); if (s.isReturnStatement()) break; /* Check for: * if (condition) * return exp1; * else * return exp2; */ IfStatement ifs = s.isIfStatement(); if (ifs && ifs.elsebody && ifs.ifbody && ifs.ifbody.isReturnStatement() && ifs.elsebody.isReturnStatement() ) break; } } return e; } Statement inlineScan(InlineScanState* iss) { for (size_t i = 0; i < statements.dim; i++) { Statement s = cast(Statement) statements.data[i]; if (s) statements.data[i] = cast(void*)s.inlineScan(iss); } return this; } void toIR(IRState* irs) { if (statements) { size_t dim = statements.dim; for (size_t i = 0 ; i < dim ; i++) { Statement s = cast(Statement)statements.data[i]; if (s !is null) { s.toIR(irs); } } } } CompoundStatement isCompoundStatement() { return this; } }