mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 17:11:44 +03:00
[svn r330] Implemented synchronized statements.
Changed the tryfinally handlers to a more generalized EnclosingHandler. Changed ClassInfoS to be mutable so they can be used as locks. Added new BB after throw ala return/break etc.
This commit is contained in:
parent
ac3744a59d
commit
0d160ffc76
16 changed files with 350 additions and 177 deletions
|
@ -29,6 +29,7 @@ struct AggregateDeclaration;
|
|||
struct AnonymousAggregateDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct DocComment;
|
||||
struct EnclosingHandler;
|
||||
enum LINK;
|
||||
enum PROT;
|
||||
|
||||
|
@ -45,7 +46,7 @@ struct Scope
|
|||
LabelStatement *slabel; // enclosing labelled statement
|
||||
SwitchStatement *sw; // enclosing switch statement
|
||||
TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block
|
||||
TryFinallyStatement *tfOfTry; // enclosing try finally statement; set inside its try block
|
||||
EnclosingHandler *tfOfTry; // enclosing try-finally, volatile or synchronized statement; set inside its try or body block
|
||||
Statement *sbreak; // enclosing statement that supports "break"
|
||||
Statement *scontinue; // enclosing statement that supports "continue"
|
||||
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
||||
|
|
|
@ -560,7 +560,7 @@ UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
|
|||
: Statement(loc)
|
||||
{
|
||||
statements = s;
|
||||
enclosingtryfinally = NULL;
|
||||
enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *UnrolledLoopStatement::syntaxCopy()
|
||||
|
@ -582,7 +582,7 @@ Statement *UnrolledLoopStatement::semantic(Scope *sc)
|
|||
{
|
||||
//printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc);
|
||||
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
|
||||
sc->noctor++;
|
||||
Scope *scd = sc->push();
|
||||
|
@ -773,7 +773,7 @@ WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b)
|
|||
{
|
||||
condition = c;
|
||||
body = b;
|
||||
enclosingtryfinally = NULL;
|
||||
enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *WhileStatement::syntaxCopy()
|
||||
|
@ -808,7 +808,7 @@ Statement *WhileStatement::semantic(Scope *sc)
|
|||
}
|
||||
#endif
|
||||
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
|
||||
condition = condition->semantic(sc);
|
||||
condition = resolveProperties(sc, condition);
|
||||
|
@ -875,7 +875,7 @@ DoStatement::DoStatement(Loc loc, Statement *b, Expression *c)
|
|||
{
|
||||
body = b;
|
||||
condition = c;
|
||||
enclosingtryfinally = NULL;
|
||||
enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *DoStatement::syntaxCopy()
|
||||
|
@ -887,7 +887,7 @@ Statement *DoStatement::syntaxCopy()
|
|||
|
||||
Statement *DoStatement::semantic(Scope *sc)
|
||||
{
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
|
||||
sc->noctor++;
|
||||
if (body)
|
||||
|
@ -951,7 +951,7 @@ ForStatement::ForStatement(Loc loc, Statement *init, Expression *condition, Expr
|
|||
this->condition = condition;
|
||||
this->increment = increment;
|
||||
this->body = body;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *ForStatement::syntaxCopy()
|
||||
|
@ -971,7 +971,7 @@ Statement *ForStatement::syntaxCopy()
|
|||
|
||||
Statement *ForStatement::semantic(Scope *sc)
|
||||
{
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
|
||||
ScopeDsymbol *sym = new ScopeDsymbol();
|
||||
sym->parent = sc->scopesym;
|
||||
|
@ -1085,7 +1085,7 @@ ForeachStatement::ForeachStatement(Loc loc, enum TOK op, Arguments *arguments,
|
|||
this->arguments = arguments;
|
||||
this->aggr = aggr;
|
||||
this->body = body;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
|
||||
this->key = NULL;
|
||||
this->value = NULL;
|
||||
|
@ -1114,7 +1114,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
|||
Type *tn = NULL;
|
||||
Type *tnv = NULL;
|
||||
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
|
||||
func = sc->func;
|
||||
if (func->fes)
|
||||
|
@ -1981,7 +1981,7 @@ SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b)
|
|||
cases = NULL;
|
||||
hasNoDefault = 0;
|
||||
// LLVMDC
|
||||
enclosingtryfinally = NULL;
|
||||
enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *SwitchStatement::syntaxCopy()
|
||||
|
@ -1996,7 +1996,7 @@ Statement *SwitchStatement::semantic(Scope *sc)
|
|||
//printf("SwitchStatement::semantic(%p)\n", this);
|
||||
assert(!cases); // ensure semantic() is only run once
|
||||
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
|
||||
condition = condition->semantic(sc);
|
||||
condition = resolveProperties(sc, condition);
|
||||
|
@ -2284,7 +2284,7 @@ GotoDefaultStatement::GotoDefaultStatement(Loc loc)
|
|||
: Statement(loc)
|
||||
{
|
||||
sw = NULL;
|
||||
enclosingtryfinally = NULL;
|
||||
enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *GotoDefaultStatement::syntaxCopy()
|
||||
|
@ -2295,7 +2295,7 @@ Statement *GotoDefaultStatement::syntaxCopy()
|
|||
|
||||
Statement *GotoDefaultStatement::semantic(Scope *sc)
|
||||
{
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
sw = sc->sw;
|
||||
if (!sw)
|
||||
error("goto default not in switch statement");
|
||||
|
@ -2319,7 +2319,7 @@ GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
|
|||
{
|
||||
cs = NULL;
|
||||
this->exp = exp;
|
||||
enclosingtryfinally = NULL;
|
||||
enclosinghandler = NULL;
|
||||
sw = NULL;
|
||||
}
|
||||
|
||||
|
@ -2332,7 +2332,7 @@ Statement *GotoCaseStatement::syntaxCopy()
|
|||
|
||||
Statement *GotoCaseStatement::semantic(Scope *sc)
|
||||
{
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
if (exp)
|
||||
exp = exp->semantic(sc);
|
||||
|
||||
|
@ -2391,7 +2391,7 @@ ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
|
|||
: Statement(loc)
|
||||
{
|
||||
this->exp = exp;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *ReturnStatement::syntaxCopy()
|
||||
|
@ -2406,7 +2406,7 @@ Statement *ReturnStatement::syntaxCopy()
|
|||
Statement *ReturnStatement::semantic(Scope *sc)
|
||||
{
|
||||
//printf("ReturnStatement::semantic() %s\n", toChars());
|
||||
this->enclosingtryfinally = sc->tfOfTry;
|
||||
this->enclosinghandler = sc->tfOfTry;
|
||||
|
||||
FuncDeclaration *fd = sc->parent->isFuncDeclaration();
|
||||
Scope *scx = sc;
|
||||
|
@ -2667,7 +2667,7 @@ BreakStatement::BreakStatement(Loc loc, Identifier *ident)
|
|||
: Statement(loc)
|
||||
{
|
||||
this->ident = ident;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *BreakStatement::syntaxCopy()
|
||||
|
@ -2678,7 +2678,7 @@ Statement *BreakStatement::syntaxCopy()
|
|||
|
||||
Statement *BreakStatement::semantic(Scope *sc)
|
||||
{
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
// If:
|
||||
// break Identifier;
|
||||
if (ident)
|
||||
|
@ -2761,7 +2761,7 @@ ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
|
|||
: Statement(loc)
|
||||
{
|
||||
this->ident = ident;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *ContinueStatement::syntaxCopy()
|
||||
|
@ -2772,7 +2772,7 @@ Statement *ContinueStatement::syntaxCopy()
|
|||
|
||||
Statement *ContinueStatement::semantic(Scope *sc)
|
||||
{
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
//printf("ContinueStatement::semantic() %p\n", this);
|
||||
if (ident)
|
||||
{
|
||||
|
@ -2866,6 +2866,8 @@ SynchronizedStatement::SynchronizedStatement(Loc loc, Expression *exp, Statement
|
|||
this->exp = exp;
|
||||
this->body = body;
|
||||
this->esync = NULL;
|
||||
// LLVMDC
|
||||
this->llsync = NULL;
|
||||
}
|
||||
|
||||
SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body)
|
||||
|
@ -2874,6 +2876,8 @@ SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *bo
|
|||
this->exp = NULL;
|
||||
this->body = body;
|
||||
this->esync = esync;
|
||||
// LLVMDC
|
||||
this->llsync = NULL;
|
||||
}
|
||||
|
||||
Statement *SynchronizedStatement::syntaxCopy()
|
||||
|
@ -2902,7 +2906,12 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
|
|||
}
|
||||
}
|
||||
if (body)
|
||||
{
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
sc->tfOfTry = new EnclosingSynchro(this);
|
||||
body = body->semantic(sc);
|
||||
sc->tfOfTry = enclosinghandler;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -3205,7 +3214,7 @@ TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *fi
|
|||
{
|
||||
this->body = body;
|
||||
this->finalbody = finalbody;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *TryFinallyStatement::syntaxCopy()
|
||||
|
@ -3219,10 +3228,10 @@ Statement *TryFinallyStatement::semantic(Scope *sc)
|
|||
{
|
||||
//printf("TryFinallyStatement::semantic()\n");
|
||||
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
sc->tfOfTry = this;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
sc->tfOfTry = new EnclosingTryFinally(this);
|
||||
body = body->semantic(sc);
|
||||
sc->tfOfTry = enclosingtryfinally;
|
||||
sc->tfOfTry = enclosinghandler;
|
||||
|
||||
sc = sc->push();
|
||||
sc->tf = this;
|
||||
|
@ -3399,6 +3408,7 @@ VolatileStatement::VolatileStatement(Loc loc, Statement *statement)
|
|||
: Statement(loc)
|
||||
{
|
||||
this->statement = statement;
|
||||
this->enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *VolatileStatement::syntaxCopy()
|
||||
|
@ -3410,7 +3420,13 @@ Statement *VolatileStatement::syntaxCopy()
|
|||
|
||||
Statement *VolatileStatement::semantic(Scope *sc)
|
||||
{
|
||||
statement = statement ? statement->semantic(sc) : NULL;
|
||||
if (statement)
|
||||
{
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
sc->tfOfTry = new EnclosingVolatile(this);
|
||||
statement = statement->semantic(sc);
|
||||
sc->tfOfTry = enclosinghandler;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -3457,7 +3473,7 @@ GotoStatement::GotoStatement(Loc loc, Identifier *ident)
|
|||
this->ident = ident;
|
||||
this->label = NULL;
|
||||
this->tf = NULL;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
Statement *GotoStatement::syntaxCopy()
|
||||
|
@ -3471,7 +3487,7 @@ Statement *GotoStatement::semantic(Scope *sc)
|
|||
|
||||
//printf("GotoStatement::semantic()\n");
|
||||
tf = sc->tf;
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
label = fd->searchLabel(ident);
|
||||
if (!label->statement && sc->fes)
|
||||
{
|
||||
|
@ -3515,7 +3531,7 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
|
|||
this->ident = ident;
|
||||
this->statement = statement;
|
||||
this->tf = NULL;
|
||||
this->enclosingtryfinally = NULL;
|
||||
this->enclosinghandler = NULL;
|
||||
this->lblock = NULL;
|
||||
this->isReturnLabel = 0;
|
||||
this->llvmBB = NULL;
|
||||
|
@ -3539,7 +3555,7 @@ Statement *LabelStatement::semantic(Scope *sc)
|
|||
else
|
||||
ls->statement = this;
|
||||
tf = sc->tf;
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
sc = sc->push();
|
||||
sc->scopesym = sc->enclosing->scopesym;
|
||||
sc->callSuper |= CSXlabel;
|
||||
|
|
|
@ -50,6 +50,8 @@ struct HdrGenState;
|
|||
struct InterState;
|
||||
struct CaseStatement;
|
||||
struct LabelStatement;
|
||||
struct VolatileStatement;
|
||||
struct SynchronizedStatement;
|
||||
|
||||
enum TOK;
|
||||
|
||||
|
@ -77,6 +79,35 @@ struct block;
|
|||
#endif
|
||||
struct code;
|
||||
|
||||
// LLVMDC this is used for tracking try-finally, synchronized and volatile scopes
|
||||
// definitions in gen/llvmhelpers.cpp
|
||||
struct EnclosingHandler : Object
|
||||
{
|
||||
virtual void emitCode(IRState* p) = 0;
|
||||
virtual EnclosingHandler* getEnclosing() = 0;
|
||||
};
|
||||
struct EnclosingTryFinally : EnclosingHandler
|
||||
{
|
||||
TryFinallyStatement* tf;
|
||||
void emitCode(IRState* p);
|
||||
EnclosingHandler* getEnclosing();
|
||||
EnclosingTryFinally(TryFinallyStatement* _tf) : tf(_tf) {}
|
||||
};
|
||||
struct EnclosingVolatile : EnclosingHandler
|
||||
{
|
||||
VolatileStatement* v;
|
||||
void emitCode(IRState* p);
|
||||
EnclosingHandler* getEnclosing();
|
||||
EnclosingVolatile(VolatileStatement* _tf) : v(_tf) {}
|
||||
};
|
||||
struct EnclosingSynchro : EnclosingHandler
|
||||
{
|
||||
SynchronizedStatement* s;
|
||||
void emitCode(IRState* p);
|
||||
EnclosingHandler* getEnclosing();
|
||||
EnclosingSynchro(SynchronizedStatement* _tf) : s(_tf) {}
|
||||
};
|
||||
|
||||
struct Statement : Object
|
||||
{
|
||||
Loc loc;
|
||||
|
@ -196,7 +227,7 @@ struct CompoundStatement : Statement
|
|||
struct UnrolledLoopStatement : Statement
|
||||
{
|
||||
Statements *statements;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
UnrolledLoopStatement(Loc loc, Statements *statements);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -241,7 +272,7 @@ struct WhileStatement : Statement
|
|||
{
|
||||
Expression *condition;
|
||||
Statement *body;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
WhileStatement(Loc loc, Expression *c, Statement *b);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -263,7 +294,7 @@ struct DoStatement : Statement
|
|||
{
|
||||
Statement *body;
|
||||
Expression *condition;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
DoStatement(Loc loc, Statement *b, Expression *c);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -287,7 +318,7 @@ struct ForStatement : Statement
|
|||
Expression *condition;
|
||||
Expression *increment;
|
||||
Statement *body;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -312,7 +343,7 @@ struct ForeachStatement : Statement
|
|||
Arguments *arguments; // array of Argument*'s
|
||||
Expression *aggr;
|
||||
Statement *body;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
VarDeclaration *key;
|
||||
VarDeclaration *value;
|
||||
|
@ -409,7 +440,7 @@ struct SwitchStatement : Statement
|
|||
Expression *condition;
|
||||
Statement *body;
|
||||
DefaultStatement *sdefault;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
Array gotoCases; // array of unresolved GotoCaseStatement's
|
||||
Array *cases; // array of CaseStatement's
|
||||
|
@ -484,7 +515,7 @@ struct DefaultStatement : Statement
|
|||
struct GotoDefaultStatement : Statement
|
||||
{
|
||||
SwitchStatement *sw;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
GotoDefaultStatement(Loc loc);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -500,7 +531,7 @@ struct GotoCaseStatement : Statement
|
|||
{
|
||||
Expression *exp; // NULL, or which case to goto
|
||||
CaseStatement *cs; // case statement it resolves to
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
SwitchStatement *sw;
|
||||
|
||||
GotoCaseStatement(Loc loc, Expression *exp);
|
||||
|
@ -525,7 +556,7 @@ struct SwitchErrorStatement : Statement
|
|||
struct ReturnStatement : Statement
|
||||
{
|
||||
Expression *exp;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
ReturnStatement(Loc loc, Expression *exp);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -546,7 +577,7 @@ struct ReturnStatement : Statement
|
|||
struct BreakStatement : Statement
|
||||
{
|
||||
Identifier *ident;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
BreakStatement(Loc loc, Identifier *ident);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -564,7 +595,7 @@ struct BreakStatement : Statement
|
|||
struct ContinueStatement : Statement
|
||||
{
|
||||
Identifier *ident;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
ContinueStatement(Loc loc, Identifier *ident);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -583,6 +614,7 @@ struct SynchronizedStatement : Statement
|
|||
{
|
||||
Expression *exp;
|
||||
Statement *body;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
SynchronizedStatement(Loc loc, Expression *exp, Statement *body);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -599,6 +631,7 @@ struct SynchronizedStatement : Statement
|
|||
elem *esync;
|
||||
SynchronizedStatement(Loc loc, elem *esync, Statement *body);
|
||||
void toIR(IRState *irs);
|
||||
llvm::Value* llsync;
|
||||
};
|
||||
|
||||
struct WithStatement : Statement
|
||||
|
@ -656,7 +689,7 @@ struct TryFinallyStatement : Statement
|
|||
{
|
||||
Statement *body;
|
||||
Statement *finalbody;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -705,6 +738,7 @@ struct ThrowStatement : Statement
|
|||
struct VolatileStatement : Statement
|
||||
{
|
||||
Statement *statement;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
VolatileStatement(Loc loc, Statement *statement);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -723,7 +757,7 @@ struct GotoStatement : Statement
|
|||
Identifier *ident;
|
||||
LabelDsymbol *label;
|
||||
TryFinallyStatement *tf;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
GotoStatement(Loc loc, Identifier *ident);
|
||||
Statement *syntaxCopy();
|
||||
|
@ -741,7 +775,7 @@ struct LabelStatement : Statement
|
|||
Identifier *ident;
|
||||
Statement *statement;
|
||||
TryFinallyStatement *tf;
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
block *lblock; // back end
|
||||
int isReturnLabel;
|
||||
|
||||
|
@ -798,7 +832,7 @@ struct AsmStatement : Statement
|
|||
|
||||
struct AsmBlockStatement : CompoundStatement
|
||||
{
|
||||
TryFinallyStatement *enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
AsmBlockStatement(Loc loc, Statements *s);
|
||||
Statements *flatten(Scope *sc);
|
||||
|
|
|
@ -381,7 +381,7 @@ assert(0);
|
|||
AsmBlockStatement::AsmBlockStatement(Loc loc, Statements* s)
|
||||
: CompoundStatement(loc, s)
|
||||
{
|
||||
enclosingtryfinally = NULL;
|
||||
enclosinghandler = NULL;
|
||||
}
|
||||
|
||||
// rewrite argument indices to the block scope indices
|
||||
|
@ -638,7 +638,7 @@ void AsmBlockStatement::toIR(IRState* p)
|
|||
sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->first), casebb);
|
||||
|
||||
p->scope() = IRScope(casebb,bb);
|
||||
DtoGoto(&loc, it->second, enclosingtryfinally);
|
||||
DtoGoto(&loc, it->second, enclosinghandler);
|
||||
}
|
||||
|
||||
p->scope() = IRScope(bb,oldend);
|
||||
|
@ -669,7 +669,7 @@ Statement *AsmBlockStatement::syntaxCopy()
|
|||
// necessary for in-asm branches
|
||||
Statement *AsmBlockStatement::semantic(Scope *sc)
|
||||
{
|
||||
enclosingtryfinally = sc->tfOfTry;
|
||||
enclosinghandler = sc->tfOfTry;
|
||||
|
||||
return CompoundStatement::semantic(sc);
|
||||
}
|
||||
|
|
|
@ -1253,7 +1253,7 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
|
|||
|
||||
const LLType* st = cinfo->type->ir.type->get();
|
||||
|
||||
cd->ir.irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module);
|
||||
cd->ir.irStruct->classInfo = new llvm::GlobalVariable(st, false, DtoLinkage(cd), NULL, gname, gIR->module);
|
||||
}
|
||||
|
||||
static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
#include "statement.h"
|
||||
|
||||
#include "gen/irstate.h"
|
||||
#include "tollvm.h"
|
||||
|
@ -35,19 +36,21 @@ IRLoopScope::IRLoopScope()
|
|||
{
|
||||
}
|
||||
|
||||
IRLoopScope::IRLoopScope(Statement* s, TryFinallyStatement* enclosingtryfinally, llvm::BasicBlock* b, llvm::BasicBlock* e)
|
||||
IRLoopScope::IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e)
|
||||
{
|
||||
begin = b;
|
||||
end = e;
|
||||
//builder.SetInsertPoint(b);
|
||||
this->s = s;
|
||||
this->enclosingtryfinally = enclosingtryfinally;
|
||||
this->enclosinghandler = enclosinghandler;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
IRState::IRState()
|
||||
{
|
||||
interfaceInfoType = NULL;
|
||||
mutexType = NULL;
|
||||
|
||||
dmodule = 0;
|
||||
module = 0;
|
||||
emitMain = false;
|
||||
|
|
|
@ -23,7 +23,7 @@ struct FuncDeclaration;
|
|||
struct Module;
|
||||
struct TypeStruct;
|
||||
struct BaseClass;
|
||||
struct TryFinallyStatement;
|
||||
struct EnclosingHandler;
|
||||
|
||||
struct IrModule;
|
||||
|
||||
|
@ -44,10 +44,10 @@ struct IRLoopScope : IRScope
|
|||
// generating statement
|
||||
Statement* s;
|
||||
// the try of a TryFinally that encloses the loop
|
||||
TryFinallyStatement* enclosingtryfinally;
|
||||
EnclosingHandler* enclosinghandler;
|
||||
|
||||
IRLoopScope();
|
||||
IRLoopScope(Statement* s, TryFinallyStatement* enclosingtryfinally, llvm::BasicBlock* b, llvm::BasicBlock* e);
|
||||
IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e);
|
||||
};
|
||||
|
||||
struct IRBuilderHelper
|
||||
|
@ -96,7 +96,8 @@ struct IRState
|
|||
llvm::Module* module;
|
||||
|
||||
// interface info type, used in DtoInterfaceInfoType
|
||||
llvm::StructType* interfaceInfoType;
|
||||
const LLStructType* interfaceInfoType;
|
||||
const LLStructType* mutexType;
|
||||
|
||||
// functions
|
||||
typedef std::vector<IrFunction*> FunctionVector;
|
||||
|
|
32
gen/llvm.h
32
gen/llvm.h
|
@ -20,25 +20,25 @@ using llvm::IRBuilder;
|
|||
|
||||
// shortcuts for the common llvm types
|
||||
|
||||
typedef llvm::Type LLType;
|
||||
typedef llvm::FunctionType LLFunctionType;
|
||||
typedef llvm::PointerType LLPointerType;
|
||||
typedef llvm::StructType LLStructType;
|
||||
typedef llvm::ArrayType LLArrayType;
|
||||
typedef llvm::IntegerType LLIntegerType;
|
||||
typedef llvm::OpaqueType LLOpaqueType;
|
||||
#define LLType llvm::Type
|
||||
#define LLFunctionType llvm::FunctionType
|
||||
#define LLPointerType llvm::PointerType
|
||||
#define LLStructType llvm::StructType
|
||||
#define LLArrayType llvm::ArrayType
|
||||
#define LLIntegerType llvm::IntegerType
|
||||
#define LLOpaqueType llvm::OpaqueType
|
||||
|
||||
typedef llvm::Value LLValue;
|
||||
typedef llvm::GlobalValue LLGlobalValue;
|
||||
typedef llvm::GlobalVariable LLGlobalVariable;
|
||||
typedef llvm::Function LLFunction;
|
||||
#define LLValue llvm::Value
|
||||
#define LLGlobalValue llvm::GlobalValue
|
||||
#define LLGlobalVariable llvm::GlobalVariable
|
||||
#define LLFunction llvm::Function
|
||||
|
||||
typedef llvm::Constant LLConstant;
|
||||
typedef llvm::ConstantStruct LLConstantStruct;
|
||||
typedef llvm::ConstantArray LLConstantArray;
|
||||
typedef llvm::ConstantInt LLConstantInt;
|
||||
#define LLConstant llvm::Constant
|
||||
#define LLConstantStruct llvm::ConstantStruct
|
||||
#define LLConstantArray llvm::ConstantArray
|
||||
#define LLConstantInt llvm::ConstantInt
|
||||
|
||||
typedef llvm::PATypeHolder LLPATypeHolder;
|
||||
#define LLPATypeHolder llvm::PATypeHolder
|
||||
|
||||
#define LLSmallVector llvm::SmallVector
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ LabelStatement* DtoLabelStatement(Identifier* ident)
|
|||
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GOTO HELPER
|
||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfinally)
|
||||
void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler)
|
||||
{
|
||||
assert(!gIR->scopereturned());
|
||||
|
||||
|
@ -189,42 +189,115 @@ void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfina
|
|||
lblstmt->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc());
|
||||
|
||||
// find finallys between goto and label
|
||||
TryFinallyStatement* endfinally = enclosingtryfinally;
|
||||
while(endfinally != NULL && endfinally != lblstmt->enclosingtryfinally) {
|
||||
endfinally = endfinally->enclosingtryfinally;
|
||||
EnclosingHandler* endfinally = enclosinghandler;
|
||||
while(endfinally != NULL && endfinally != lblstmt->enclosinghandler) {
|
||||
endfinally = endfinally->getEnclosing();
|
||||
}
|
||||
|
||||
// error if didn't find tf statement of label
|
||||
if(endfinally != lblstmt->enclosingtryfinally)
|
||||
if(endfinally != lblstmt->enclosinghandler)
|
||||
error("cannot goto into try block", loc->toChars());
|
||||
|
||||
// emit code for finallys between goto and label
|
||||
DtoFinallyBlocks(enclosingtryfinally, endfinally);
|
||||
DtoEnclosingHandlers(enclosinghandler, endfinally);
|
||||
|
||||
llvm::BranchInst::Create(lblstmt->llvmBB, gIR->scopebb());
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TRY FINALLY HELPER
|
||||
// TRY-FINALLY, VOLATILE AND SYNCHRONIZED HELPER
|
||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
void DtoFinallyBlocks(TryFinallyStatement* start, TryFinallyStatement* end)
|
||||
|
||||
void EnclosingSynchro::emitCode(IRState * p)
|
||||
{
|
||||
if (s->exp)
|
||||
DtoLeaveMonitor(s->llsync);
|
||||
else
|
||||
DtoLeaveCritical(s->llsync);
|
||||
}
|
||||
|
||||
EnclosingHandler* EnclosingSynchro::getEnclosing()
|
||||
{
|
||||
return s->enclosinghandler;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EnclosingVolatile::emitCode(IRState * p)
|
||||
{
|
||||
// store-load barrier
|
||||
DtoMemoryBarrier(false, false, true, false);
|
||||
}
|
||||
|
||||
EnclosingHandler* EnclosingVolatile::getEnclosing()
|
||||
{
|
||||
return v->enclosinghandler;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EnclosingTryFinally::emitCode(IRState * p)
|
||||
{
|
||||
assert(tf->finalbody);
|
||||
tf->finalbody->toIR(p);
|
||||
}
|
||||
|
||||
EnclosingHandler* EnclosingTryFinally::getEnclosing()
|
||||
{
|
||||
return tf->enclosinghandler;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoEnclosingHandlers(EnclosingHandler* start, EnclosingHandler* end)
|
||||
{
|
||||
// verify that end encloses start
|
||||
TryFinallyStatement* endfinally = start;
|
||||
EnclosingHandler* endfinally = start;
|
||||
while(endfinally != NULL && endfinally != end) {
|
||||
endfinally = endfinally->enclosingtryfinally;
|
||||
endfinally = endfinally->getEnclosing();
|
||||
}
|
||||
assert(endfinally == end);
|
||||
|
||||
// emit code for finallys between start and end
|
||||
TryFinallyStatement* tf = start;
|
||||
EnclosingHandler* tf = start;
|
||||
while(tf != end) {
|
||||
tf->finalbody->toIR(gIR);
|
||||
tf = tf->enclosingtryfinally;
|
||||
tf->emitCode(gIR);
|
||||
tf = tf->getEnclosing();
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SYNCHRONIZED SECTION HELPERS
|
||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
void DtoEnterCritical(LLValue* g)
|
||||
{
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_criticalenter");
|
||||
gIR->ir->CreateCall(fn, g, "");
|
||||
}
|
||||
|
||||
void DtoLeaveCritical(LLValue* g)
|
||||
{
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_criticalexit");
|
||||
gIR->ir->CreateCall(fn, g, "");
|
||||
}
|
||||
|
||||
void DtoEnterMonitor(LLValue* v)
|
||||
{
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_monitorenter");
|
||||
v = DtoBitCast(v, fn->getFunctionType()->getParamType(0));
|
||||
gIR->ir->CreateCall(fn, v, "");
|
||||
}
|
||||
|
||||
void DtoLeaveMonitor(LLValue* v)
|
||||
{
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_monitorexit");
|
||||
v = DtoBitCast(v, fn->getFunctionType()->getParamType(0));
|
||||
gIR->ir->CreateCall(fn, v, "");
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||
// NESTED VARIABLE HELPERS
|
||||
|
|
|
@ -16,12 +16,22 @@ void DtoAssert(Loc* loc, DValue* msg);
|
|||
// return the LabelStatement from the current function with the given identifier or NULL if not found
|
||||
LabelStatement* DtoLabelStatement(Identifier* ident);
|
||||
// emit goto
|
||||
void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfinally);
|
||||
void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosingtryfinally);
|
||||
|
||||
// generates IR for finally blocks between the 'start' and 'end' statements
|
||||
// will begin with the finally block belonging to 'start' and does not include
|
||||
// the finally block of 'end'
|
||||
void DtoFinallyBlocks(TryFinallyStatement* start, TryFinallyStatement* end);
|
||||
void DtoEnclosingHandlers(EnclosingHandler* start, EnclosingHandler* end);
|
||||
|
||||
// enters a critical section
|
||||
void DtoEnterCritical(LLValue* g);
|
||||
// leaves a critical section
|
||||
void DtoLeaveCritical(LLValue* g);
|
||||
|
||||
// enters a monitor lock
|
||||
void DtoEnterMonitor(LLValue* v);
|
||||
// leaves a monitor lock
|
||||
void DtoLeaveMonitor(LLValue* v);
|
||||
|
||||
// nested variable/class helpers
|
||||
LLValue* DtoNestedContext(FuncDeclaration* func);
|
||||
|
|
|
@ -852,10 +852,32 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
palist = palist.addAttr(2, llvm::ParamAttr::ByVal);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// void _d_criticalenter(D_CRITICAL_SECTION *dcs)
|
||||
// void _d_criticalexit(D_CRITICAL_SECTION *dcs)
|
||||
{
|
||||
std::string fname("_d_criticalenter");
|
||||
std::string fname2("_d_criticalexit");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(rt_ptr(DtoMutexType()));
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// void _d_monitorenter(Object h)
|
||||
// void _d_monitorexit(Object h)
|
||||
{
|
||||
std::string fname("_d_monitorenter");
|
||||
std::string fname2("_d_monitorexit");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(objectTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,12 +70,7 @@ void ReturnStatement::toIR(IRState* p)
|
|||
if (!e->inPlace())
|
||||
DtoAssign(rvar, e);
|
||||
|
||||
DtoFinallyBlocks(enclosingtryfinally, NULL);
|
||||
|
||||
if (f->inVolatile) {
|
||||
// store-load barrier
|
||||
DtoMemoryBarrier(false, false, true, false);
|
||||
}
|
||||
DtoEnclosingHandlers(enclosinghandler, NULL);
|
||||
|
||||
if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
|
||||
llvm::ReturnInst::Create(p->scopebb());
|
||||
|
@ -95,12 +90,7 @@ void ReturnStatement::toIR(IRState* p)
|
|||
Logger::cout() << "return value after cast: " << *v << '\n';
|
||||
}
|
||||
|
||||
DtoFinallyBlocks(enclosingtryfinally, NULL);
|
||||
|
||||
if (gIR->func()->inVolatile) {
|
||||
// store-load barrier
|
||||
DtoMemoryBarrier(false, false, true, false);
|
||||
}
|
||||
DtoEnclosingHandlers(enclosinghandler, NULL);
|
||||
|
||||
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
||||
llvm::ReturnInst::Create(v, p->scopebb());
|
||||
|
@ -109,12 +99,7 @@ void ReturnStatement::toIR(IRState* p)
|
|||
else
|
||||
{
|
||||
assert(p->topfunc()->getReturnType() == LLType::VoidTy);
|
||||
DtoFinallyBlocks(enclosingtryfinally, NULL);
|
||||
|
||||
if (gIR->func()->inVolatile) {
|
||||
// store-load barrier
|
||||
DtoMemoryBarrier(false, false, true, false);
|
||||
}
|
||||
DtoEnclosingHandlers(enclosinghandler, NULL);
|
||||
|
||||
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
||||
llvm::ReturnInst::Create(p->scopebb());
|
||||
|
@ -275,7 +260,7 @@ void WhileStatement::toIR(IRState* p)
|
|||
gIR->scope() = IRScope(whilebodybb,endbb);
|
||||
|
||||
// while body code
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,whilebb,endbb));
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,whilebb,endbb));
|
||||
body->toIR(p);
|
||||
p->loopbbs.pop_back();
|
||||
|
||||
|
@ -310,7 +295,7 @@ void DoStatement::toIR(IRState* p)
|
|||
gIR->scope() = IRScope(dowhilebb,endbb);
|
||||
|
||||
// do-while body code
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,dowhilebb,endbb));
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,dowhilebb,endbb));
|
||||
body->toIR(p);
|
||||
p->loopbbs.pop_back();
|
||||
|
||||
|
@ -351,7 +336,7 @@ void ForStatement::toIR(IRState* p)
|
|||
assert(!gIR->scopereturned());
|
||||
llvm::BranchInst::Create(forbb, gIR->scopebb());
|
||||
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,forincbb,endbb));
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,forincbb,endbb));
|
||||
|
||||
// replace current scope
|
||||
gIR->scope() = IRScope(forbb,forbodybb);
|
||||
|
@ -410,7 +395,7 @@ void BreakStatement::toIR(IRState* p)
|
|||
if (ident != 0) {
|
||||
Logger::println("ident = %s", ident->toChars());
|
||||
|
||||
DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally);
|
||||
DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler);
|
||||
|
||||
// get the loop statement the label refers to
|
||||
Statement* targetLoopStatement = target->statement;
|
||||
|
@ -431,7 +416,7 @@ void BreakStatement::toIR(IRState* p)
|
|||
assert(found);
|
||||
}
|
||||
else {
|
||||
DtoFinallyBlocks(enclosingtryfinally, p->loopbbs.back().enclosingtryfinally);
|
||||
DtoEnclosingHandlers(enclosinghandler, p->loopbbs.back().enclosinghandler);
|
||||
llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb());
|
||||
}
|
||||
|
||||
|
@ -454,7 +439,7 @@ void ContinueStatement::toIR(IRState* p)
|
|||
if (ident != 0) {
|
||||
Logger::println("ident = %s", ident->toChars());
|
||||
|
||||
DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally);
|
||||
DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler);
|
||||
|
||||
// get the loop statement the label refers to
|
||||
Statement* targetLoopStatement = target->statement;
|
||||
|
@ -473,7 +458,7 @@ void ContinueStatement::toIR(IRState* p)
|
|||
assert(0);
|
||||
}
|
||||
else {
|
||||
DtoFinallyBlocks(enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally);
|
||||
DtoEnclosingHandlers(enclosinghandler, gIR->loopbbs.back().enclosinghandler);
|
||||
llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb());
|
||||
}
|
||||
}
|
||||
|
@ -599,6 +584,11 @@ void ThrowStatement::toIR(IRState* p)
|
|||
//Logger::cout() << "arg: " << *arg << '\n';
|
||||
gIR->ir->CreateCall(fn, arg, "");
|
||||
gIR->ir->CreateUnreachable();
|
||||
|
||||
// need a block after the throw for now
|
||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterthrow", p->topfunc(), oldend);
|
||||
p->scope() = IRScope(bb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -767,7 +757,7 @@ void SwitchStatement::toIR(IRState* p)
|
|||
assert(body);
|
||||
|
||||
p->scope() = IRScope(bodybb, endbb);
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb));
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb));
|
||||
body->toIR(p);
|
||||
p->loopbbs.pop_back();
|
||||
|
||||
|
@ -851,7 +841,7 @@ void UnrolledLoopStatement::toIR(IRState* p)
|
|||
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend);
|
||||
|
||||
p->scope() = IRScope(p->scopebb(),endbb);
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb));
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb));
|
||||
|
||||
for (int i=0; i<statements->dim; ++i)
|
||||
{
|
||||
|
@ -974,7 +964,7 @@ void ForeachStatement::toIR(IRState* p)
|
|||
}
|
||||
|
||||
// emit body
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,nextbb,endbb));
|
||||
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb));
|
||||
body->toIR(p);
|
||||
p->loopbbs.pop_back();
|
||||
|
||||
|
@ -1047,7 +1037,7 @@ void GotoStatement::toIR(IRState* p)
|
|||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend);
|
||||
|
||||
DtoGoto(&loc, label->ident, enclosingtryfinally);
|
||||
DtoGoto(&loc, label->ident, enclosinghandler);
|
||||
|
||||
p->scope() = IRScope(bb,oldend);
|
||||
}
|
||||
|
@ -1068,7 +1058,7 @@ void GotoDefaultStatement::toIR(IRState* p)
|
|||
assert(!p->scopereturned());
|
||||
assert(sw->sdefault->bodyBB);
|
||||
|
||||
DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally);
|
||||
DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler);
|
||||
|
||||
llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb());
|
||||
p->scope() = IRScope(bb,oldend);
|
||||
|
@ -1093,7 +1083,7 @@ void GotoCaseStatement::toIR(IRState* p)
|
|||
cs->bodyBB = llvm::BasicBlock::Create("goto_case", p->topfunc(), p->scopeend());
|
||||
}
|
||||
|
||||
DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally);
|
||||
DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler);
|
||||
|
||||
llvm::BranchInst::Create(cs->bodyBB, p->scopebb());
|
||||
p->scope() = IRScope(bb,oldend);
|
||||
|
@ -1122,54 +1112,45 @@ void WithStatement::toIR(IRState* p)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static LLConstant* generate_unique_critical_section()
|
||||
{
|
||||
const LLType* Mty = DtoMutexType();
|
||||
return new llvm::GlobalVariable(Mty, false, llvm::GlobalValue::InternalLinkage, LLConstant::getNullValue(Mty), ".uniqueCS", gIR->module);
|
||||
}
|
||||
|
||||
void SynchronizedStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
Logger::attention(loc, "synchronized is currently ignored. only the body will be emitted");
|
||||
|
||||
if (global.params.symdebug)
|
||||
DtoDwarfStopPoint(loc.linnum);
|
||||
|
||||
body->toIR(p);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* this has moved to asmstmt.cpp
|
||||
void AsmStatement::toIR(IRState* p)
|
||||
// enter lock
|
||||
if (exp)
|
||||
{
|
||||
Logger::println("AsmStatement::toIR(): %s", loc.toChars());
|
||||
LOG_SCOPE;
|
||||
// error("%s: inline asm is not yet implemented", loc.toChars());
|
||||
// fatal();
|
||||
|
||||
assert(!asmcode && !asmalign && !refparam && !naked && !regs);
|
||||
|
||||
Token* t = tokens;
|
||||
assert(t);
|
||||
|
||||
std::string asmstr;
|
||||
|
||||
do {
|
||||
Logger::println("token: %s", t->toChars());
|
||||
asmstr.append(t->toChars());
|
||||
asmstr.append(" ");
|
||||
} while (t = t->next);
|
||||
|
||||
Logger::println("asm expr = '%s'", asmstr.c_str());
|
||||
|
||||
// create function type
|
||||
std::vector<const LLType*> args;
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(DtoSize_t(), args, false);
|
||||
|
||||
// create inline asm callee
|
||||
llvm::InlineAsm* inasm = llvm::InlineAsm::get(fty, asmstr, "r,r", false);
|
||||
|
||||
assert(0);
|
||||
llsync = exp->toElem(p)->getRVal();
|
||||
DtoEnterMonitor(llsync);
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
llsync = generate_unique_critical_section();
|
||||
DtoEnterCritical(llsync);
|
||||
}
|
||||
|
||||
// emit body
|
||||
body->toIR(p);
|
||||
|
||||
// exit lock
|
||||
// no point in a unreachable unlock, terminating statements must insert this themselves.
|
||||
if (p->scopereturned())
|
||||
return;
|
||||
else if (exp)
|
||||
DtoLeaveMonitor(llsync);
|
||||
else
|
||||
DtoLeaveCritical(llsync);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VolatileStatement::toIR(IRState* p)
|
||||
|
@ -1181,8 +1162,7 @@ void VolatileStatement::toIR(IRState* p)
|
|||
DtoDwarfStopPoint(loc.linnum);
|
||||
|
||||
// mark in-volatile
|
||||
bool old = gIR->func()->inVolatile;
|
||||
gIR->func()->inVolatile = true;
|
||||
// FIXME
|
||||
|
||||
// has statement
|
||||
if (statement != NULL)
|
||||
|
@ -1193,7 +1173,7 @@ void VolatileStatement::toIR(IRState* p)
|
|||
// do statement
|
||||
statement->toIR(p);
|
||||
|
||||
// no point in a unreachable barrier, terminating statements should insert this themselves.
|
||||
// no point in a unreachable barrier, terminating statements must insert this themselves.
|
||||
if (statement->fallOffEnd())
|
||||
{
|
||||
// store-load
|
||||
|
@ -1208,7 +1188,7 @@ void VolatileStatement::toIR(IRState* p)
|
|||
}
|
||||
|
||||
// restore volatile state
|
||||
gIR->func()->inVolatile = old;
|
||||
// FIXME
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -637,6 +637,7 @@ size_t getTypeStoreSize(const LLType* t)
|
|||
|
||||
size_t getABITypeSize(const LLType* t)
|
||||
{
|
||||
Logger::cout() << "getting abi type of: " << *t << '\n';
|
||||
return gTargetData->getABITypeSize(t);
|
||||
}
|
||||
|
||||
|
@ -677,12 +678,49 @@ const LLStructType* DtoInterfaceInfoType()
|
|||
return gIR->interfaceInfoType;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const LLStructType* DtoMutexType()
|
||||
{
|
||||
if (gIR->mutexType)
|
||||
return gIR->mutexType;
|
||||
|
||||
// win32
|
||||
if (global.params.isWindows)
|
||||
{
|
||||
// CRITICAL_SECTION.sizeof == 68
|
||||
std::vector<const LLType*> types(17, LLType::Int32Ty);
|
||||
return LLStructType::get(types);
|
||||
}
|
||||
|
||||
// pthread_fastlock
|
||||
std::vector<const LLType*> types2;
|
||||
types2.push_back(DtoSize_t());
|
||||
types2.push_back(LLType::Int32Ty);
|
||||
const LLStructType* fastlock = LLStructType::get(types2);
|
||||
|
||||
// pthread_mutex
|
||||
std::vector<const LLType*> types1;
|
||||
types1.push_back(LLType::Int32Ty);
|
||||
types1.push_back(LLType::Int32Ty);
|
||||
types1.push_back(getVoidPtrType());
|
||||
types1.push_back(LLType::Int32Ty);
|
||||
types1.push_back(fastlock);
|
||||
const LLStructType* pmutex = LLStructType::get(types1);
|
||||
|
||||
// D_CRITICAL_SECTION
|
||||
LLOpaqueType* opaque = LLOpaqueType::get();
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(getPtrToType(opaque));
|
||||
types.push_back(pmutex);
|
||||
|
||||
// resolve type
|
||||
pmutex = LLStructType::get(types);
|
||||
LLPATypeHolder pa(pmutex);
|
||||
opaque->refineAbstractTypeTo(pa.get());
|
||||
pmutex = isaStruct(pa.get());
|
||||
|
||||
|
||||
|
||||
gIR->mutexType = pmutex;
|
||||
gIR->module->addTypeName("D_CRITICAL_SECTION", pmutex);
|
||||
return pmutex;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ LLValue* DtoBoolean(LLValue* val);
|
|||
// some types
|
||||
const LLType* DtoSize_t();
|
||||
const LLStructType* DtoInterfaceInfoType();
|
||||
const LLStructType* DtoMutexType();
|
||||
|
||||
// getelementptr helpers
|
||||
LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=NULL, llvm::BasicBlock* bb=NULL);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
#include "gen/llvm.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/irfunction.h"
|
||||
|
||||
|
@ -27,9 +29,4 @@ IrFunction::IrFunction(FuncDeclaration* fd)
|
|||
|
||||
srcfileArg = NULL;
|
||||
msgArg = NULL;
|
||||
inVolatile = false;
|
||||
}
|
||||
|
||||
IrFunction::~IrFunction()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -25,10 +25,7 @@ struct IrFunction : IrBase
|
|||
llvm::AllocaInst* srcfileArg;
|
||||
llvm::AllocaInst* msgArg;
|
||||
|
||||
bool inVolatile;
|
||||
|
||||
IrFunction(FuncDeclaration* fd);
|
||||
virtual ~IrFunction();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue