Showing with 74 additions and 83 deletions.
  1. +0 −2 src/arraytypes.h
  2. +2 −0 src/glue.c
  3. +5 −0 src/irstate.c
  4. +1 −0 src/irstate.h
  5. +1 −3 src/magicport.json
  6. +0 −1 src/mars.c
  7. +65 −60 src/s2ir.c
  8. +0 −6 src/statement.c
  9. +0 −11 src/statement.h
2 changes: 0 additions & 2 deletions src/arraytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,4 @@ typedef Array<class GotoStatement *> GotoStatements;

typedef Array<class TemplateInstance *> TemplateInstances;

typedef Array<struct block *> Blocks;

#endif
2 changes: 2 additions & 0 deletions src/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,8 @@ void FuncDeclaration_toObjFile(FuncDeclaration *fd, bool multiobj)
IRState irs(m, fd);
Dsymbols deferToObj; // write these to OBJ file later
irs.deferToObj = &deferToObj;
AA *labels = NULL;
irs.labels = &labels;

symbol *shidden = NULL;
Symbol *sthis = NULL;
Expand Down
5 changes: 5 additions & 0 deletions src/irstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ IRState::IRState(IRState *irs, Statement *s)
blx = irs->blx;
deferToObj = irs->deferToObj;
varsInScope = irs->varsInScope;
labels = irs->labels;
}
else
{
Expand All @@ -49,6 +50,7 @@ IRState::IRState(IRState *irs, Statement *s)
blx = NULL;
deferToObj = NULL;
varsInScope = NULL;
labels = NULL;
}
}

Expand All @@ -74,6 +76,7 @@ IRState::IRState(IRState *irs, Dsymbol *s)
blx = irs->blx;
deferToObj = irs->deferToObj;
varsInScope = irs->varsInScope;
labels = irs->labels;
}
else
{
Expand All @@ -84,6 +87,7 @@ IRState::IRState(IRState *irs, Dsymbol *s)
blx = NULL;
deferToObj = NULL;
varsInScope = NULL;
labels = NULL;
}
}

Expand All @@ -107,6 +111,7 @@ IRState::IRState(Module *m, Dsymbol *s)
deferToObj = NULL;
startaddress = NULL;
varsInScope = NULL;
labels = NULL;
}

block *IRState::getBreakBlock(Identifier *ident)
Expand Down
1 change: 1 addition & 0 deletions src/irstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct IRState
elem *ehidden; // transmit hidden pointer to CallExp::toElem()
Symbol *startaddress;
VarDeclarations *varsInScope; // variables that are in scope that will need destruction later
AA **labels; // table of labels used/declared in function

block *breakBlock;
block *contBlock;
Expand Down
4 changes: 1 addition & 3 deletions src/magicport.json
Original file line number Diff line number Diff line change
Expand Up @@ -1023,8 +1023,7 @@
"typedef GotoCaseStatements",
"typedef ReturnStatements",
"typedef GotoStatements",
"typedef TemplateInstances",
"typedef Blocks"
"typedef TemplateInstances"
]
},
{
Expand Down Expand Up @@ -2593,7 +2592,6 @@
"function parse_conf_arg",
"function Dsymbols_create",
"function VarDeclarations_create",
"function Blocks_create",
"function Expressions_create"
]
},
Expand Down
1 change: 0 additions & 1 deletion src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -1901,5 +1901,4 @@ static const char* parse_conf_arg(Strings *args)

Dsymbols *Dsymbols_create() { return new Dsymbols(); }
VarDeclarations *VarDeclarations_create() { return new VarDeclarations(); }
Blocks *Blocks_create() { return new Blocks(); }
Expressions *Expressions_create() { return new Expressions(); }
125 changes: 65 additions & 60 deletions src/s2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "global.h"
#include "dt.h"

#include "aav.h"
#include "rmem.h"
#include "target.h"
#include "visitor.h"
Expand All @@ -44,7 +45,6 @@ Symbol *toStringSymbol(const char *str, size_t len, size_t sz);
elem *exp2_copytotemp(elem *e);
elem *incUsageElem(IRState *irs, Loc loc);
elem *addressElem(elem *e, Type *t, bool alwaysCopy = false);
Blocks *Blocks_create();
type *Type_toCtype(Type *t);
elem *toElemDtor(Expression *e, IRState *irs);
Symbol *toSymbol(Type *t);
Expand Down Expand Up @@ -85,31 +85,53 @@ block *block_calloc(Blockx *blx)
return b;
}

/****************************************
* Our label symbol, with vector to keep track of forward references.
*/

struct Label
{
block *lblock; // The block to which the label is defined.
block *fwdrefs; // The first use of the label before it is defined.
};

/****************************************
* Get or create a label declaration.
*/

static Label *getLabel(IRState *irs, Blockx *blx, Statement *s)
{
Label **slot = (Label **)dmd_aaGet(irs->labels, (void *)s);

if (*slot == NULL)
{
Label *label = new Label();
label->lblock = blx ? block_calloc(blx) : block_calloc();
label->fwdrefs = NULL;
*slot = label;
}
return *slot;
}

/**************************************
* Convert label to block.
*/

block *labelToBlock(Loc loc, Blockx *blx, LabelDsymbol *label, int flag = 0)
block *labelToBlock(IRState *irs, Loc loc, Blockx *blx, LabelDsymbol *label, int flag = 0)
{
if (!label->statement)
{
error(loc, "undefined label %s", label->toChars());
return NULL;
}
LabelStatement *s = label->statement;
if (!s->lblock)
{ s->lblock = block_calloc(blx);
s->lblock->Btry = NULL; // fill this in later

if (flag)
{
// Keep track of the forward reference to this block, so we can check it later
if (!s->fwdrefs)
s->fwdrefs = Blocks_create();
s->fwdrefs->push(blx->curblock);
}
Label *l = getLabel(irs, NULL, label->statement);
if (flag)
{
// Keep track of the forward reference to this block, so we can check it later
if (!l->fwdrefs)
l->fwdrefs = blx->curblock;
}
return s->lblock;
return l->lblock;
}

/**************************************
Expand Down Expand Up @@ -386,7 +408,7 @@ class S2irVisitor : public Visitor
assert(s->label->statement);
assert(s->tf == s->label->statement->tf);

block *bdest = labelToBlock(s->loc, blx, s->label, 1);
block *bdest = labelToBlock(irs, s->loc, blx, s->label, 1);
if (!bdest)
return;
block *b = blx->curblock;
Expand Down Expand Up @@ -416,39 +438,31 @@ class S2irVisitor : public Visitor
IRState mystate(irs,s);
mystate.ident = s->ident;

if (s->lblock)
Label *label = getLabel(irs, blx, s);
// At last, we know which try block this label is inside
label->lblock->Btry = blx->tryblock;

// Go through the forward references and check.
if (label->fwdrefs)
{
// At last, we know which try block this label is inside
s->lblock->Btry = blx->tryblock;
block *b = label->fwdrefs;

/* Go through the forward references and check.
*/
if (s->fwdrefs)
if (b->Btry != label->lblock->Btry)
{
for (size_t i = 0; i < s->fwdrefs->dim; i++)
{ block *b = (*s->fwdrefs)[i];

if (b->Btry != s->lblock->Btry)
// Check that lblock is in an enclosing try block
for (block *bt = b->Btry; bt != label->lblock->Btry; bt = bt->Btry)
{
if (!bt)
{
// Check that lblock is in an enclosing try block
for (block *bt = b->Btry; bt != s->lblock->Btry; bt = bt->Btry)
{
if (!bt)
{
//printf("b->Btry = %p, s->lblock->Btry = %p\n", b->Btry, s->lblock->Btry);
s->error("cannot goto into try block");
break;
}
}
//printf("b->Btry = %p, label->lblock->Btry = %p\n", b->Btry, label->lblock->Btry);
s->error("cannot goto into try block");
break;
}

}
s->fwdrefs = NULL;
}
}
else
s->lblock = block_calloc(blx);
block_next(blx,BCgoto,s->lblock);
block_next(blx, BCgoto, label->lblock);
bc->appendSucc(blx->curblock);
if (s->statement)
Statement_toIR(s->statement, &mystate);
Expand Down Expand Up @@ -502,10 +516,9 @@ class S2irVisitor : public Visitor
elem *e = el_bin(OPeqeq, TYbool, el_copytree(econd), ecase);
block *b = blx->curblock;
block_appendexp(b, e);
block *bcase = block_calloc(blx);
cs->cblock = bcase;
Label *clabel = getLabel(irs, blx, cs);
block_next(blx, BCiftrue, NULL);
b->appendSucc(bcase);
b->appendSucc(clabel->lblock);
b->appendSucc(blx->curblock);
}

Expand Down Expand Up @@ -626,13 +639,12 @@ class S2irVisitor : public Visitor
{
Blockx *blx = irs->blx;
block *bcase = blx->curblock;
if (!s->cblock)
s->cblock = block_calloc(blx);
block_next(blx,BCgoto,s->cblock);
Label *clabel = getLabel(irs, blx, s);
block_next(blx, BCgoto, clabel->lblock);
block *bsw = irs->getSwitchBlock();
if (bsw->BC == BCswitch)
bsw->appendSucc(s->cblock); // second entry in pair
bcase->appendSucc(s->cblock);
bsw->appendSucc(clabel->lblock); // second entry in pair
bcase->appendSucc(clabel->lblock);
if (blx->tryblock != bsw->Btry)
s->error("case cannot be in different try block level from switch");
incUsage(irs, s->loc);
Expand Down Expand Up @@ -688,17 +700,10 @@ class S2irVisitor : public Visitor

void visit(GotoCaseStatement *s)
{
block *b;
Blockx *blx = irs->blx;
block *bdest = s->cs->cblock;

if (!bdest)
{
bdest = block_calloc(blx);
s->cs->cblock = bdest;
}

b = blx->curblock;
Label *clabel = getLabel(irs, blx, s->cs);
block *bdest = clabel->lblock;
block *b = blx->curblock;

// The rest is equivalent to GotoStatement

Expand Down Expand Up @@ -1210,7 +1215,7 @@ class S2irVisitor : public Visitor
case FLblock:
// FLblock and FLblockoff have LabelDsymbol's - convert to blocks
label = c->IEVlsym1;
b = labelToBlock(s->loc, blx, label);
b = labelToBlock(irs, s->loc, blx, label);
basm->appendSucc(b);
c->IEV1.Vblock = b;
break;
Expand All @@ -1232,7 +1237,7 @@ class S2irVisitor : public Visitor
case FLblockoff:
case FLblock:
label = c->IEVlsym2;
b = labelToBlock(s->loc, blx, label);
b = labelToBlock(irs, s->loc, blx, label);
basm->appendSucc(b);
c->IEV2.Vblock = b;
break;
Expand Down
6 changes: 0 additions & 6 deletions src/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -3498,7 +3498,6 @@ CaseStatement::CaseStatement(Loc loc, Expression *exp, Statement *s)
this->exp = exp;
this->statement = s;
index = 0;
cblock = NULL;
}

Statement *CaseStatement::syntaxCopy()
Expand Down Expand Up @@ -3724,9 +3723,6 @@ DefaultStatement::DefaultStatement(Loc loc, Statement *s)
: Statement(loc)
{
this->statement = s;
#ifdef IN_GCC
cblock = NULL;
#endif
}

Statement *DefaultStatement::syntaxCopy()
Expand Down Expand Up @@ -5137,8 +5133,6 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
this->lastVar = NULL;
this->gotoTarget = NULL;
this->breaks = false;
this->lblock = NULL;
this->fwdrefs = NULL;
}

Statement *LabelStatement::syntaxCopy()
Expand Down
11 changes: 0 additions & 11 deletions src/statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ class DefaultStatement;
class LabelStatement;

// Back end
#ifdef IN_GCC
typedef union tree_node block;
#else
struct block;
#endif
struct code;

bool inferAggregate(ForeachStatement *fes, Scope *sc, Dsymbol *&sapply);
Expand Down Expand Up @@ -439,7 +434,6 @@ class CaseStatement : public Statement
Statement *statement;

int index; // which case it is (since we sort this)
block *cblock; // back end: label for the block

CaseStatement(Loc loc, Expression *exp, Statement *s);
Statement *syntaxCopy();
Expand Down Expand Up @@ -469,9 +463,6 @@ class DefaultStatement : public Statement
{
public:
Statement *statement;
#ifdef IN_GCC
block *cblock; // back end: label for the block
#endif

DefaultStatement(Loc loc, Statement *s);
Statement *syntaxCopy();
Expand Down Expand Up @@ -697,8 +688,6 @@ class LabelStatement : public Statement
Statement *gotoTarget; // interpret

bool breaks; // someone did a 'break ident'
block *lblock; // back end
Blocks *fwdrefs; // forward references to this LabelStatement

LabelStatement(Loc loc, Identifier *ident, Statement *statement);
Statement *syntaxCopy();
Expand Down