void visit(GotoStatement *s) { Blockx *blx = irs->blx; assert(s->label->statement); assert(s->tf == s->label->statement->tf); block *bdest = labelToBlock(irs, s->loc, blx, s->label, 1); if (!bdest) return; block *b = blx->curblock; incUsage(irs, s->loc); b->appendSucc(bdest); block_setLoc(b, s->loc); // Check that bdest is in an enclosing try block for (block *bt = b->Btry; bt != bdest->Btry; bt = bt->Btry) { if (!bt) { //printf("b->Btry = %p, bdest->Btry = %p\n", b->Btry, bdest->Btry); s->error("cannot goto into try block"); break; } } block_next(blx,BCgoto,NULL); }
void GotoStatement::toIR(IRState *irs) { Blockx *blx = irs->blx; if (!label->statement) { error("label %s is undefined", label->toChars()); return; } if (tf != label->statement->tf) error("cannot goto forward out of or into finally block"); block *bdest = labelToBlock(loc, blx, label, 1); if (!bdest) return; block *b = blx->curblock; incUsage(irs, loc); if (b->Btry != bdest->Btry) { // Check that bdest is in an enclosing try block for (block *bt = b->Btry; bt != bdest->Btry; bt = bt->Btry) { if (!bt) { //printf("b->Btry = %p, bdest->Btry = %p\n", b->Btry, bdest->Btry); error("cannot goto into try block"); break; } } } list_append(&b->Bsucc,bdest); block_next(blx,BCgoto,NULL); }
void visit(AsmStatement *s) { block *bpre; block *basm; Declaration *d; Symbol *sym; Blockx *blx = irs->blx; //printf("AsmStatement::toIR(asmcode = %x)\n", asmcode); bpre = blx->curblock; block_next(blx,BCgoto,NULL); basm = blx->curblock; bpre->appendSucc(basm); basm->Bcode = s->asmcode; basm->Balign = s->asmalign; // Loop through each instruction, fixing Dsymbols into Symbol's for (code *c = s->asmcode; c; c = c->next) { LabelDsymbol *label; block *b; switch (c->IFL1) { case FLblockoff: case FLblock: // FLblock and FLblockoff have LabelDsymbol's - convert to blocks label = c->IEVlsym1; b = labelToBlock(irs, s->loc, blx, label); basm->appendSucc(b); c->IEV1.Vblock = b; break; case FLdsymbol: case FLfunc: sym = toSymbol(c->IEVdsym1); if (sym->Sclass == SCauto && sym->Ssymnum == -1) symbol_add(sym); c->IEVsym1 = sym; c->IFL1 = sym->Sfl ? sym->Sfl : FLauto; break; } // Repeat for second operand switch (c->IFL2) { case FLblockoff: case FLblock: label = c->IEVlsym2; b = labelToBlock(irs, s->loc, blx, label); basm->appendSucc(b); c->IEV2.Vblock = b; break; case FLdsymbol: case FLfunc: d = c->IEVdsym2; sym = toSymbol(d); if (sym->Sclass == SCauto && sym->Ssymnum == -1) symbol_add(sym); c->IEVsym2 = sym; c->IFL2 = sym->Sfl ? sym->Sfl : FLauto; if (d->isDataseg()) sym->Sflags |= SFLlivexit; break; } //c->print(); } basm->bIasmrefparam = s->refparam; // are parameters reference? basm->usIasmregs = s->regs; // registers modified block_next(blx,BCasm, NULL); basm->prependSucc(blx->curblock); if (s->naked) { blx->funcsym->Stype->Tty |= mTYnaked; } }