mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 10:57:35 +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 AnonymousAggregateDeclaration;
|
||||||
struct FuncDeclaration;
|
struct FuncDeclaration;
|
||||||
struct DocComment;
|
struct DocComment;
|
||||||
|
struct EnclosingHandler;
|
||||||
enum LINK;
|
enum LINK;
|
||||||
enum PROT;
|
enum PROT;
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ struct Scope
|
||||||
LabelStatement *slabel; // enclosing labelled statement
|
LabelStatement *slabel; // enclosing labelled statement
|
||||||
SwitchStatement *sw; // enclosing switch statement
|
SwitchStatement *sw; // enclosing switch statement
|
||||||
TryFinallyStatement *tf; // enclosing try finally statement; set inside its finally block
|
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 *sbreak; // enclosing statement that supports "break"
|
||||||
Statement *scontinue; // enclosing statement that supports "continue"
|
Statement *scontinue; // enclosing statement that supports "continue"
|
||||||
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
||||||
|
|
|
@ -560,7 +560,7 @@ UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
|
||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
statements = s;
|
statements = s;
|
||||||
enclosingtryfinally = NULL;
|
enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *UnrolledLoopStatement::syntaxCopy()
|
Statement *UnrolledLoopStatement::syntaxCopy()
|
||||||
|
@ -582,7 +582,7 @@ Statement *UnrolledLoopStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
//printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc);
|
//printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc);
|
||||||
|
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
sc->noctor++;
|
sc->noctor++;
|
||||||
Scope *scd = sc->push();
|
Scope *scd = sc->push();
|
||||||
|
@ -773,7 +773,7 @@ WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b)
|
||||||
{
|
{
|
||||||
condition = c;
|
condition = c;
|
||||||
body = b;
|
body = b;
|
||||||
enclosingtryfinally = NULL;
|
enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *WhileStatement::syntaxCopy()
|
Statement *WhileStatement::syntaxCopy()
|
||||||
|
@ -808,7 +808,7 @@ Statement *WhileStatement::semantic(Scope *sc)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
condition = condition->semantic(sc);
|
condition = condition->semantic(sc);
|
||||||
condition = resolveProperties(sc, condition);
|
condition = resolveProperties(sc, condition);
|
||||||
|
@ -875,7 +875,7 @@ DoStatement::DoStatement(Loc loc, Statement *b, Expression *c)
|
||||||
{
|
{
|
||||||
body = b;
|
body = b;
|
||||||
condition = c;
|
condition = c;
|
||||||
enclosingtryfinally = NULL;
|
enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *DoStatement::syntaxCopy()
|
Statement *DoStatement::syntaxCopy()
|
||||||
|
@ -887,7 +887,7 @@ Statement *DoStatement::syntaxCopy()
|
||||||
|
|
||||||
Statement *DoStatement::semantic(Scope *sc)
|
Statement *DoStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
sc->noctor++;
|
sc->noctor++;
|
||||||
if (body)
|
if (body)
|
||||||
|
@ -951,7 +951,7 @@ ForStatement::ForStatement(Loc loc, Statement *init, Expression *condition, Expr
|
||||||
this->condition = condition;
|
this->condition = condition;
|
||||||
this->increment = increment;
|
this->increment = increment;
|
||||||
this->body = body;
|
this->body = body;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *ForStatement::syntaxCopy()
|
Statement *ForStatement::syntaxCopy()
|
||||||
|
@ -971,7 +971,7 @@ Statement *ForStatement::syntaxCopy()
|
||||||
|
|
||||||
Statement *ForStatement::semantic(Scope *sc)
|
Statement *ForStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
ScopeDsymbol *sym = new ScopeDsymbol();
|
ScopeDsymbol *sym = new ScopeDsymbol();
|
||||||
sym->parent = sc->scopesym;
|
sym->parent = sc->scopesym;
|
||||||
|
@ -1085,7 +1085,7 @@ ForeachStatement::ForeachStatement(Loc loc, enum TOK op, Arguments *arguments,
|
||||||
this->arguments = arguments;
|
this->arguments = arguments;
|
||||||
this->aggr = aggr;
|
this->aggr = aggr;
|
||||||
this->body = body;
|
this->body = body;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
|
|
||||||
this->key = NULL;
|
this->key = NULL;
|
||||||
this->value = NULL;
|
this->value = NULL;
|
||||||
|
@ -1114,7 +1114,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||||
Type *tn = NULL;
|
Type *tn = NULL;
|
||||||
Type *tnv = NULL;
|
Type *tnv = NULL;
|
||||||
|
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
func = sc->func;
|
func = sc->func;
|
||||||
if (func->fes)
|
if (func->fes)
|
||||||
|
@ -1981,7 +1981,7 @@ SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b)
|
||||||
cases = NULL;
|
cases = NULL;
|
||||||
hasNoDefault = 0;
|
hasNoDefault = 0;
|
||||||
// LLVMDC
|
// LLVMDC
|
||||||
enclosingtryfinally = NULL;
|
enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *SwitchStatement::syntaxCopy()
|
Statement *SwitchStatement::syntaxCopy()
|
||||||
|
@ -1996,7 +1996,7 @@ Statement *SwitchStatement::semantic(Scope *sc)
|
||||||
//printf("SwitchStatement::semantic(%p)\n", this);
|
//printf("SwitchStatement::semantic(%p)\n", this);
|
||||||
assert(!cases); // ensure semantic() is only run once
|
assert(!cases); // ensure semantic() is only run once
|
||||||
|
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
condition = condition->semantic(sc);
|
condition = condition->semantic(sc);
|
||||||
condition = resolveProperties(sc, condition);
|
condition = resolveProperties(sc, condition);
|
||||||
|
@ -2284,7 +2284,7 @@ GotoDefaultStatement::GotoDefaultStatement(Loc loc)
|
||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
sw = NULL;
|
sw = NULL;
|
||||||
enclosingtryfinally = NULL;
|
enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *GotoDefaultStatement::syntaxCopy()
|
Statement *GotoDefaultStatement::syntaxCopy()
|
||||||
|
@ -2295,7 +2295,7 @@ Statement *GotoDefaultStatement::syntaxCopy()
|
||||||
|
|
||||||
Statement *GotoDefaultStatement::semantic(Scope *sc)
|
Statement *GotoDefaultStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
sw = sc->sw;
|
sw = sc->sw;
|
||||||
if (!sw)
|
if (!sw)
|
||||||
error("goto default not in switch statement");
|
error("goto default not in switch statement");
|
||||||
|
@ -2319,7 +2319,7 @@ GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
|
||||||
{
|
{
|
||||||
cs = NULL;
|
cs = NULL;
|
||||||
this->exp = exp;
|
this->exp = exp;
|
||||||
enclosingtryfinally = NULL;
|
enclosinghandler = NULL;
|
||||||
sw = NULL;
|
sw = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2332,7 +2332,7 @@ Statement *GotoCaseStatement::syntaxCopy()
|
||||||
|
|
||||||
Statement *GotoCaseStatement::semantic(Scope *sc)
|
Statement *GotoCaseStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
if (exp)
|
if (exp)
|
||||||
exp = exp->semantic(sc);
|
exp = exp->semantic(sc);
|
||||||
|
|
||||||
|
@ -2391,7 +2391,7 @@ ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
|
||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
this->exp = exp;
|
this->exp = exp;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *ReturnStatement::syntaxCopy()
|
Statement *ReturnStatement::syntaxCopy()
|
||||||
|
@ -2406,7 +2406,7 @@ Statement *ReturnStatement::syntaxCopy()
|
||||||
Statement *ReturnStatement::semantic(Scope *sc)
|
Statement *ReturnStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
//printf("ReturnStatement::semantic() %s\n", toChars());
|
//printf("ReturnStatement::semantic() %s\n", toChars());
|
||||||
this->enclosingtryfinally = sc->tfOfTry;
|
this->enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
FuncDeclaration *fd = sc->parent->isFuncDeclaration();
|
FuncDeclaration *fd = sc->parent->isFuncDeclaration();
|
||||||
Scope *scx = sc;
|
Scope *scx = sc;
|
||||||
|
@ -2667,7 +2667,7 @@ BreakStatement::BreakStatement(Loc loc, Identifier *ident)
|
||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
this->ident = ident;
|
this->ident = ident;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *BreakStatement::syntaxCopy()
|
Statement *BreakStatement::syntaxCopy()
|
||||||
|
@ -2678,7 +2678,7 @@ Statement *BreakStatement::syntaxCopy()
|
||||||
|
|
||||||
Statement *BreakStatement::semantic(Scope *sc)
|
Statement *BreakStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
// If:
|
// If:
|
||||||
// break Identifier;
|
// break Identifier;
|
||||||
if (ident)
|
if (ident)
|
||||||
|
@ -2761,7 +2761,7 @@ ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
|
||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
this->ident = ident;
|
this->ident = ident;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *ContinueStatement::syntaxCopy()
|
Statement *ContinueStatement::syntaxCopy()
|
||||||
|
@ -2772,7 +2772,7 @@ Statement *ContinueStatement::syntaxCopy()
|
||||||
|
|
||||||
Statement *ContinueStatement::semantic(Scope *sc)
|
Statement *ContinueStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
//printf("ContinueStatement::semantic() %p\n", this);
|
//printf("ContinueStatement::semantic() %p\n", this);
|
||||||
if (ident)
|
if (ident)
|
||||||
{
|
{
|
||||||
|
@ -2866,6 +2866,8 @@ SynchronizedStatement::SynchronizedStatement(Loc loc, Expression *exp, Statement
|
||||||
this->exp = exp;
|
this->exp = exp;
|
||||||
this->body = body;
|
this->body = body;
|
||||||
this->esync = NULL;
|
this->esync = NULL;
|
||||||
|
// LLVMDC
|
||||||
|
this->llsync = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body)
|
SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body)
|
||||||
|
@ -2874,6 +2876,8 @@ SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *bo
|
||||||
this->exp = NULL;
|
this->exp = NULL;
|
||||||
this->body = body;
|
this->body = body;
|
||||||
this->esync = esync;
|
this->esync = esync;
|
||||||
|
// LLVMDC
|
||||||
|
this->llsync = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *SynchronizedStatement::syntaxCopy()
|
Statement *SynchronizedStatement::syntaxCopy()
|
||||||
|
@ -2902,7 +2906,12 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (body)
|
if (body)
|
||||||
|
{
|
||||||
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
sc->tfOfTry = new EnclosingSynchro(this);
|
||||||
body = body->semantic(sc);
|
body = body->semantic(sc);
|
||||||
|
sc->tfOfTry = enclosinghandler;
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3205,7 +3214,7 @@ TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *fi
|
||||||
{
|
{
|
||||||
this->body = body;
|
this->body = body;
|
||||||
this->finalbody = finalbody;
|
this->finalbody = finalbody;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *TryFinallyStatement::syntaxCopy()
|
Statement *TryFinallyStatement::syntaxCopy()
|
||||||
|
@ -3219,10 +3228,10 @@ Statement *TryFinallyStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
//printf("TryFinallyStatement::semantic()\n");
|
//printf("TryFinallyStatement::semantic()\n");
|
||||||
|
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
sc->tfOfTry = this;
|
sc->tfOfTry = new EnclosingTryFinally(this);
|
||||||
body = body->semantic(sc);
|
body = body->semantic(sc);
|
||||||
sc->tfOfTry = enclosingtryfinally;
|
sc->tfOfTry = enclosinghandler;
|
||||||
|
|
||||||
sc = sc->push();
|
sc = sc->push();
|
||||||
sc->tf = this;
|
sc->tf = this;
|
||||||
|
@ -3399,6 +3408,7 @@ VolatileStatement::VolatileStatement(Loc loc, Statement *statement)
|
||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
this->statement = statement;
|
this->statement = statement;
|
||||||
|
this->enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *VolatileStatement::syntaxCopy()
|
Statement *VolatileStatement::syntaxCopy()
|
||||||
|
@ -3410,7 +3420,13 @@ Statement *VolatileStatement::syntaxCopy()
|
||||||
|
|
||||||
Statement *VolatileStatement::semantic(Scope *sc)
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3457,7 +3473,7 @@ GotoStatement::GotoStatement(Loc loc, Identifier *ident)
|
||||||
this->ident = ident;
|
this->ident = ident;
|
||||||
this->label = NULL;
|
this->label = NULL;
|
||||||
this->tf = NULL;
|
this->tf = NULL;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *GotoStatement::syntaxCopy()
|
Statement *GotoStatement::syntaxCopy()
|
||||||
|
@ -3471,7 +3487,7 @@ Statement *GotoStatement::semantic(Scope *sc)
|
||||||
|
|
||||||
//printf("GotoStatement::semantic()\n");
|
//printf("GotoStatement::semantic()\n");
|
||||||
tf = sc->tf;
|
tf = sc->tf;
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
label = fd->searchLabel(ident);
|
label = fd->searchLabel(ident);
|
||||||
if (!label->statement && sc->fes)
|
if (!label->statement && sc->fes)
|
||||||
{
|
{
|
||||||
|
@ -3515,7 +3531,7 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
|
||||||
this->ident = ident;
|
this->ident = ident;
|
||||||
this->statement = statement;
|
this->statement = statement;
|
||||||
this->tf = NULL;
|
this->tf = NULL;
|
||||||
this->enclosingtryfinally = NULL;
|
this->enclosinghandler = NULL;
|
||||||
this->lblock = NULL;
|
this->lblock = NULL;
|
||||||
this->isReturnLabel = 0;
|
this->isReturnLabel = 0;
|
||||||
this->llvmBB = NULL;
|
this->llvmBB = NULL;
|
||||||
|
@ -3539,7 +3555,7 @@ Statement *LabelStatement::semantic(Scope *sc)
|
||||||
else
|
else
|
||||||
ls->statement = this;
|
ls->statement = this;
|
||||||
tf = sc->tf;
|
tf = sc->tf;
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
sc = sc->push();
|
sc = sc->push();
|
||||||
sc->scopesym = sc->enclosing->scopesym;
|
sc->scopesym = sc->enclosing->scopesym;
|
||||||
sc->callSuper |= CSXlabel;
|
sc->callSuper |= CSXlabel;
|
||||||
|
|
|
@ -50,6 +50,8 @@ struct HdrGenState;
|
||||||
struct InterState;
|
struct InterState;
|
||||||
struct CaseStatement;
|
struct CaseStatement;
|
||||||
struct LabelStatement;
|
struct LabelStatement;
|
||||||
|
struct VolatileStatement;
|
||||||
|
struct SynchronizedStatement;
|
||||||
|
|
||||||
enum TOK;
|
enum TOK;
|
||||||
|
|
||||||
|
@ -77,6 +79,35 @@ struct block;
|
||||||
#endif
|
#endif
|
||||||
struct code;
|
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
|
struct Statement : Object
|
||||||
{
|
{
|
||||||
Loc loc;
|
Loc loc;
|
||||||
|
@ -196,7 +227,7 @@ struct CompoundStatement : Statement
|
||||||
struct UnrolledLoopStatement : Statement
|
struct UnrolledLoopStatement : Statement
|
||||||
{
|
{
|
||||||
Statements *statements;
|
Statements *statements;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
UnrolledLoopStatement(Loc loc, Statements *statements);
|
UnrolledLoopStatement(Loc loc, Statements *statements);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -241,7 +272,7 @@ struct WhileStatement : Statement
|
||||||
{
|
{
|
||||||
Expression *condition;
|
Expression *condition;
|
||||||
Statement *body;
|
Statement *body;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
WhileStatement(Loc loc, Expression *c, Statement *b);
|
WhileStatement(Loc loc, Expression *c, Statement *b);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -263,7 +294,7 @@ struct DoStatement : Statement
|
||||||
{
|
{
|
||||||
Statement *body;
|
Statement *body;
|
||||||
Expression *condition;
|
Expression *condition;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
DoStatement(Loc loc, Statement *b, Expression *c);
|
DoStatement(Loc loc, Statement *b, Expression *c);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -287,7 +318,7 @@ struct ForStatement : Statement
|
||||||
Expression *condition;
|
Expression *condition;
|
||||||
Expression *increment;
|
Expression *increment;
|
||||||
Statement *body;
|
Statement *body;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body);
|
ForStatement(Loc loc, Statement *init, Expression *condition, Expression *increment, Statement *body);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -312,7 +343,7 @@ struct ForeachStatement : Statement
|
||||||
Arguments *arguments; // array of Argument*'s
|
Arguments *arguments; // array of Argument*'s
|
||||||
Expression *aggr;
|
Expression *aggr;
|
||||||
Statement *body;
|
Statement *body;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
VarDeclaration *key;
|
VarDeclaration *key;
|
||||||
VarDeclaration *value;
|
VarDeclaration *value;
|
||||||
|
@ -409,7 +440,7 @@ struct SwitchStatement : Statement
|
||||||
Expression *condition;
|
Expression *condition;
|
||||||
Statement *body;
|
Statement *body;
|
||||||
DefaultStatement *sdefault;
|
DefaultStatement *sdefault;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
Array gotoCases; // array of unresolved GotoCaseStatement's
|
Array gotoCases; // array of unresolved GotoCaseStatement's
|
||||||
Array *cases; // array of CaseStatement's
|
Array *cases; // array of CaseStatement's
|
||||||
|
@ -484,7 +515,7 @@ struct DefaultStatement : Statement
|
||||||
struct GotoDefaultStatement : Statement
|
struct GotoDefaultStatement : Statement
|
||||||
{
|
{
|
||||||
SwitchStatement *sw;
|
SwitchStatement *sw;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
GotoDefaultStatement(Loc loc);
|
GotoDefaultStatement(Loc loc);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -500,7 +531,7 @@ struct GotoCaseStatement : Statement
|
||||||
{
|
{
|
||||||
Expression *exp; // NULL, or which case to goto
|
Expression *exp; // NULL, or which case to goto
|
||||||
CaseStatement *cs; // case statement it resolves to
|
CaseStatement *cs; // case statement it resolves to
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
SwitchStatement *sw;
|
SwitchStatement *sw;
|
||||||
|
|
||||||
GotoCaseStatement(Loc loc, Expression *exp);
|
GotoCaseStatement(Loc loc, Expression *exp);
|
||||||
|
@ -525,7 +556,7 @@ struct SwitchErrorStatement : Statement
|
||||||
struct ReturnStatement : Statement
|
struct ReturnStatement : Statement
|
||||||
{
|
{
|
||||||
Expression *exp;
|
Expression *exp;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
ReturnStatement(Loc loc, Expression *exp);
|
ReturnStatement(Loc loc, Expression *exp);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -546,7 +577,7 @@ struct ReturnStatement : Statement
|
||||||
struct BreakStatement : Statement
|
struct BreakStatement : Statement
|
||||||
{
|
{
|
||||||
Identifier *ident;
|
Identifier *ident;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
BreakStatement(Loc loc, Identifier *ident);
|
BreakStatement(Loc loc, Identifier *ident);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -564,7 +595,7 @@ struct BreakStatement : Statement
|
||||||
struct ContinueStatement : Statement
|
struct ContinueStatement : Statement
|
||||||
{
|
{
|
||||||
Identifier *ident;
|
Identifier *ident;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
ContinueStatement(Loc loc, Identifier *ident);
|
ContinueStatement(Loc loc, Identifier *ident);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -583,6 +614,7 @@ struct SynchronizedStatement : Statement
|
||||||
{
|
{
|
||||||
Expression *exp;
|
Expression *exp;
|
||||||
Statement *body;
|
Statement *body;
|
||||||
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
SynchronizedStatement(Loc loc, Expression *exp, Statement *body);
|
SynchronizedStatement(Loc loc, Expression *exp, Statement *body);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -599,6 +631,7 @@ struct SynchronizedStatement : Statement
|
||||||
elem *esync;
|
elem *esync;
|
||||||
SynchronizedStatement(Loc loc, elem *esync, Statement *body);
|
SynchronizedStatement(Loc loc, elem *esync, Statement *body);
|
||||||
void toIR(IRState *irs);
|
void toIR(IRState *irs);
|
||||||
|
llvm::Value* llsync;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WithStatement : Statement
|
struct WithStatement : Statement
|
||||||
|
@ -656,7 +689,7 @@ struct TryFinallyStatement : Statement
|
||||||
{
|
{
|
||||||
Statement *body;
|
Statement *body;
|
||||||
Statement *finalbody;
|
Statement *finalbody;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody);
|
TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -705,6 +738,7 @@ struct ThrowStatement : Statement
|
||||||
struct VolatileStatement : Statement
|
struct VolatileStatement : Statement
|
||||||
{
|
{
|
||||||
Statement *statement;
|
Statement *statement;
|
||||||
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
VolatileStatement(Loc loc, Statement *statement);
|
VolatileStatement(Loc loc, Statement *statement);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -723,7 +757,7 @@ struct GotoStatement : Statement
|
||||||
Identifier *ident;
|
Identifier *ident;
|
||||||
LabelDsymbol *label;
|
LabelDsymbol *label;
|
||||||
TryFinallyStatement *tf;
|
TryFinallyStatement *tf;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
GotoStatement(Loc loc, Identifier *ident);
|
GotoStatement(Loc loc, Identifier *ident);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
|
@ -741,7 +775,7 @@ struct LabelStatement : Statement
|
||||||
Identifier *ident;
|
Identifier *ident;
|
||||||
Statement *statement;
|
Statement *statement;
|
||||||
TryFinallyStatement *tf;
|
TryFinallyStatement *tf;
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
block *lblock; // back end
|
block *lblock; // back end
|
||||||
int isReturnLabel;
|
int isReturnLabel;
|
||||||
|
|
||||||
|
@ -798,7 +832,7 @@ struct AsmStatement : Statement
|
||||||
|
|
||||||
struct AsmBlockStatement : CompoundStatement
|
struct AsmBlockStatement : CompoundStatement
|
||||||
{
|
{
|
||||||
TryFinallyStatement *enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
AsmBlockStatement(Loc loc, Statements *s);
|
AsmBlockStatement(Loc loc, Statements *s);
|
||||||
Statements *flatten(Scope *sc);
|
Statements *flatten(Scope *sc);
|
||||||
|
|
|
@ -381,7 +381,7 @@ assert(0);
|
||||||
AsmBlockStatement::AsmBlockStatement(Loc loc, Statements* s)
|
AsmBlockStatement::AsmBlockStatement(Loc loc, Statements* s)
|
||||||
: CompoundStatement(loc, s)
|
: CompoundStatement(loc, s)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = NULL;
|
enclosinghandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rewrite argument indices to the block scope indices
|
// 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);
|
sw->addCase(llvm::ConstantInt::get(llvm::IntegerType::get(32), it->first), casebb);
|
||||||
|
|
||||||
p->scope() = IRScope(casebb,bb);
|
p->scope() = IRScope(casebb,bb);
|
||||||
DtoGoto(&loc, it->second, enclosingtryfinally);
|
DtoGoto(&loc, it->second, enclosinghandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->scope() = IRScope(bb,oldend);
|
p->scope() = IRScope(bb,oldend);
|
||||||
|
@ -669,7 +669,7 @@ Statement *AsmBlockStatement::syntaxCopy()
|
||||||
// necessary for in-asm branches
|
// necessary for in-asm branches
|
||||||
Statement *AsmBlockStatement::semantic(Scope *sc)
|
Statement *AsmBlockStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
enclosingtryfinally = sc->tfOfTry;
|
enclosinghandler = sc->tfOfTry;
|
||||||
|
|
||||||
return CompoundStatement::semantic(sc);
|
return CompoundStatement::semantic(sc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1253,7 +1253,7 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
|
||||||
|
|
||||||
const LLType* st = cinfo->type->ir.type->get();
|
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)
|
static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
#include "declaration.h"
|
#include "declaration.h"
|
||||||
|
#include "statement.h"
|
||||||
|
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "tollvm.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;
|
begin = b;
|
||||||
end = e;
|
end = e;
|
||||||
//builder.SetInsertPoint(b);
|
//builder.SetInsertPoint(b);
|
||||||
this->s = s;
|
this->s = s;
|
||||||
this->enclosingtryfinally = enclosingtryfinally;
|
this->enclosinghandler = enclosinghandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
IRState::IRState()
|
IRState::IRState()
|
||||||
{
|
{
|
||||||
interfaceInfoType = NULL;
|
interfaceInfoType = NULL;
|
||||||
|
mutexType = NULL;
|
||||||
|
|
||||||
dmodule = 0;
|
dmodule = 0;
|
||||||
module = 0;
|
module = 0;
|
||||||
emitMain = false;
|
emitMain = false;
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct FuncDeclaration;
|
||||||
struct Module;
|
struct Module;
|
||||||
struct TypeStruct;
|
struct TypeStruct;
|
||||||
struct BaseClass;
|
struct BaseClass;
|
||||||
struct TryFinallyStatement;
|
struct EnclosingHandler;
|
||||||
|
|
||||||
struct IrModule;
|
struct IrModule;
|
||||||
|
|
||||||
|
@ -44,10 +44,10 @@ struct IRLoopScope : IRScope
|
||||||
// generating statement
|
// generating statement
|
||||||
Statement* s;
|
Statement* s;
|
||||||
// the try of a TryFinally that encloses the loop
|
// the try of a TryFinally that encloses the loop
|
||||||
TryFinallyStatement* enclosingtryfinally;
|
EnclosingHandler* enclosinghandler;
|
||||||
|
|
||||||
IRLoopScope();
|
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
|
struct IRBuilderHelper
|
||||||
|
@ -96,7 +96,8 @@ struct IRState
|
||||||
llvm::Module* module;
|
llvm::Module* module;
|
||||||
|
|
||||||
// interface info type, used in DtoInterfaceInfoType
|
// interface info type, used in DtoInterfaceInfoType
|
||||||
llvm::StructType* interfaceInfoType;
|
const LLStructType* interfaceInfoType;
|
||||||
|
const LLStructType* mutexType;
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
typedef std::vector<IrFunction*> FunctionVector;
|
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
|
// shortcuts for the common llvm types
|
||||||
|
|
||||||
typedef llvm::Type LLType;
|
#define LLType llvm::Type
|
||||||
typedef llvm::FunctionType LLFunctionType;
|
#define LLFunctionType llvm::FunctionType
|
||||||
typedef llvm::PointerType LLPointerType;
|
#define LLPointerType llvm::PointerType
|
||||||
typedef llvm::StructType LLStructType;
|
#define LLStructType llvm::StructType
|
||||||
typedef llvm::ArrayType LLArrayType;
|
#define LLArrayType llvm::ArrayType
|
||||||
typedef llvm::IntegerType LLIntegerType;
|
#define LLIntegerType llvm::IntegerType
|
||||||
typedef llvm::OpaqueType LLOpaqueType;
|
#define LLOpaqueType llvm::OpaqueType
|
||||||
|
|
||||||
typedef llvm::Value LLValue;
|
#define LLValue llvm::Value
|
||||||
typedef llvm::GlobalValue LLGlobalValue;
|
#define LLGlobalValue llvm::GlobalValue
|
||||||
typedef llvm::GlobalVariable LLGlobalVariable;
|
#define LLGlobalVariable llvm::GlobalVariable
|
||||||
typedef llvm::Function LLFunction;
|
#define LLFunction llvm::Function
|
||||||
|
|
||||||
typedef llvm::Constant LLConstant;
|
#define LLConstant llvm::Constant
|
||||||
typedef llvm::ConstantStruct LLConstantStruct;
|
#define LLConstantStruct llvm::ConstantStruct
|
||||||
typedef llvm::ConstantArray LLConstantArray;
|
#define LLConstantArray llvm::ConstantArray
|
||||||
typedef llvm::ConstantInt LLConstantInt;
|
#define LLConstantInt llvm::ConstantInt
|
||||||
|
|
||||||
typedef llvm::PATypeHolder LLPATypeHolder;
|
#define LLPATypeHolder llvm::PATypeHolder
|
||||||
|
|
||||||
#define LLSmallVector llvm::SmallVector
|
#define LLSmallVector llvm::SmallVector
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,7 @@ LabelStatement* DtoLabelStatement(Identifier* ident)
|
||||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// GOTO HELPER
|
// GOTO HELPER
|
||||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||||
void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfinally)
|
void DtoGoto(Loc* loc, Identifier* target, EnclosingHandler* enclosinghandler)
|
||||||
{
|
{
|
||||||
assert(!gIR->scopereturned());
|
assert(!gIR->scopereturned());
|
||||||
|
|
||||||
|
@ -189,42 +189,115 @@ void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfina
|
||||||
lblstmt->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc());
|
lblstmt->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc());
|
||||||
|
|
||||||
// find finallys between goto and label
|
// find finallys between goto and label
|
||||||
TryFinallyStatement* endfinally = enclosingtryfinally;
|
EnclosingHandler* endfinally = enclosinghandler;
|
||||||
while(endfinally != NULL && endfinally != lblstmt->enclosingtryfinally) {
|
while(endfinally != NULL && endfinally != lblstmt->enclosinghandler) {
|
||||||
endfinally = endfinally->enclosingtryfinally;
|
endfinally = endfinally->getEnclosing();
|
||||||
}
|
}
|
||||||
|
|
||||||
// error if didn't find tf statement of label
|
// 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());
|
error("cannot goto into try block", loc->toChars());
|
||||||
|
|
||||||
// emit code for finallys between goto and label
|
// emit code for finallys between goto and label
|
||||||
DtoFinallyBlocks(enclosingtryfinally, endfinally);
|
DtoEnclosingHandlers(enclosinghandler, endfinally);
|
||||||
|
|
||||||
llvm::BranchInst::Create(lblstmt->llvmBB, gIR->scopebb());
|
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
|
// verify that end encloses start
|
||||||
TryFinallyStatement* endfinally = start;
|
EnclosingHandler* endfinally = start;
|
||||||
while(endfinally != NULL && endfinally != end) {
|
while(endfinally != NULL && endfinally != end) {
|
||||||
endfinally = endfinally->enclosingtryfinally;
|
endfinally = endfinally->getEnclosing();
|
||||||
}
|
}
|
||||||
assert(endfinally == end);
|
assert(endfinally == end);
|
||||||
|
|
||||||
// emit code for finallys between start and end
|
// emit code for finallys between start and end
|
||||||
TryFinallyStatement* tf = start;
|
EnclosingHandler* tf = start;
|
||||||
while(tf != end) {
|
while(tf != end) {
|
||||||
tf->finalbody->toIR(gIR);
|
tf->emitCode(gIR);
|
||||||
tf = tf->enclosingtryfinally;
|
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
|
// 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
|
// return the LabelStatement from the current function with the given identifier or NULL if not found
|
||||||
LabelStatement* DtoLabelStatement(Identifier* ident);
|
LabelStatement* DtoLabelStatement(Identifier* ident);
|
||||||
// emit goto
|
// 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
|
// generates IR for finally blocks between the 'start' and 'end' statements
|
||||||
// will begin with the finally block belonging to 'start' and does not include
|
// will begin with the finally block belonging to 'start' and does not include
|
||||||
// the finally block of 'end'
|
// 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
|
// nested variable/class helpers
|
||||||
LLValue* DtoNestedContext(FuncDeclaration* func);
|
LLValue* DtoNestedContext(FuncDeclaration* func);
|
||||||
|
|
|
@ -852,10 +852,32 @@ static void LLVM_D_BuildRuntimeModule()
|
||||||
palist = palist.addAttr(2, llvm::ParamAttr::ByVal);
|
palist = palist.addAttr(2, llvm::ParamAttr::ByVal);
|
||||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)->setParamAttrs(palist);
|
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())
|
if (!e->inPlace())
|
||||||
DtoAssign(rvar, e);
|
DtoAssign(rvar, e);
|
||||||
|
|
||||||
DtoFinallyBlocks(enclosingtryfinally, NULL);
|
DtoEnclosingHandlers(enclosinghandler, NULL);
|
||||||
|
|
||||||
if (f->inVolatile) {
|
|
||||||
// store-load barrier
|
|
||||||
DtoMemoryBarrier(false, false, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
|
if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
|
||||||
llvm::ReturnInst::Create(p->scopebb());
|
llvm::ReturnInst::Create(p->scopebb());
|
||||||
|
@ -95,12 +90,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||||
Logger::cout() << "return value after cast: " << *v << '\n';
|
Logger::cout() << "return value after cast: " << *v << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
DtoFinallyBlocks(enclosingtryfinally, NULL);
|
DtoEnclosingHandlers(enclosinghandler, NULL);
|
||||||
|
|
||||||
if (gIR->func()->inVolatile) {
|
|
||||||
// store-load barrier
|
|
||||||
DtoMemoryBarrier(false, false, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
||||||
llvm::ReturnInst::Create(v, p->scopebb());
|
llvm::ReturnInst::Create(v, p->scopebb());
|
||||||
|
@ -109,12 +99,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(p->topfunc()->getReturnType() == LLType::VoidTy);
|
assert(p->topfunc()->getReturnType() == LLType::VoidTy);
|
||||||
DtoFinallyBlocks(enclosingtryfinally, NULL);
|
DtoEnclosingHandlers(enclosinghandler, NULL);
|
||||||
|
|
||||||
if (gIR->func()->inVolatile) {
|
|
||||||
// store-load barrier
|
|
||||||
DtoMemoryBarrier(false, false, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
||||||
llvm::ReturnInst::Create(p->scopebb());
|
llvm::ReturnInst::Create(p->scopebb());
|
||||||
|
@ -275,7 +260,7 @@ void WhileStatement::toIR(IRState* p)
|
||||||
gIR->scope() = IRScope(whilebodybb,endbb);
|
gIR->scope() = IRScope(whilebodybb,endbb);
|
||||||
|
|
||||||
// while body code
|
// while body code
|
||||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,whilebb,endbb));
|
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,whilebb,endbb));
|
||||||
body->toIR(p);
|
body->toIR(p);
|
||||||
p->loopbbs.pop_back();
|
p->loopbbs.pop_back();
|
||||||
|
|
||||||
|
@ -310,7 +295,7 @@ void DoStatement::toIR(IRState* p)
|
||||||
gIR->scope() = IRScope(dowhilebb,endbb);
|
gIR->scope() = IRScope(dowhilebb,endbb);
|
||||||
|
|
||||||
// do-while body code
|
// 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);
|
body->toIR(p);
|
||||||
p->loopbbs.pop_back();
|
p->loopbbs.pop_back();
|
||||||
|
|
||||||
|
@ -351,7 +336,7 @@ void ForStatement::toIR(IRState* p)
|
||||||
assert(!gIR->scopereturned());
|
assert(!gIR->scopereturned());
|
||||||
llvm::BranchInst::Create(forbb, gIR->scopebb());
|
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
|
// replace current scope
|
||||||
gIR->scope() = IRScope(forbb,forbodybb);
|
gIR->scope() = IRScope(forbb,forbodybb);
|
||||||
|
@ -410,7 +395,7 @@ void BreakStatement::toIR(IRState* p)
|
||||||
if (ident != 0) {
|
if (ident != 0) {
|
||||||
Logger::println("ident = %s", ident->toChars());
|
Logger::println("ident = %s", ident->toChars());
|
||||||
|
|
||||||
DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally);
|
DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler);
|
||||||
|
|
||||||
// get the loop statement the label refers to
|
// get the loop statement the label refers to
|
||||||
Statement* targetLoopStatement = target->statement;
|
Statement* targetLoopStatement = target->statement;
|
||||||
|
@ -431,7 +416,7 @@ void BreakStatement::toIR(IRState* p)
|
||||||
assert(found);
|
assert(found);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DtoFinallyBlocks(enclosingtryfinally, p->loopbbs.back().enclosingtryfinally);
|
DtoEnclosingHandlers(enclosinghandler, p->loopbbs.back().enclosinghandler);
|
||||||
llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb());
|
llvm::BranchInst::Create(p->loopbbs.back().end, p->scopebb());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +439,7 @@ void ContinueStatement::toIR(IRState* p)
|
||||||
if (ident != 0) {
|
if (ident != 0) {
|
||||||
Logger::println("ident = %s", ident->toChars());
|
Logger::println("ident = %s", ident->toChars());
|
||||||
|
|
||||||
DtoFinallyBlocks(enclosingtryfinally, target->enclosingtryfinally);
|
DtoEnclosingHandlers(enclosinghandler, target->enclosinghandler);
|
||||||
|
|
||||||
// get the loop statement the label refers to
|
// get the loop statement the label refers to
|
||||||
Statement* targetLoopStatement = target->statement;
|
Statement* targetLoopStatement = target->statement;
|
||||||
|
@ -473,7 +458,7 @@ void ContinueStatement::toIR(IRState* p)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DtoFinallyBlocks(enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally);
|
DtoEnclosingHandlers(enclosinghandler, gIR->loopbbs.back().enclosinghandler);
|
||||||
llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb());
|
llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -599,6 +584,11 @@ void ThrowStatement::toIR(IRState* p)
|
||||||
//Logger::cout() << "arg: " << *arg << '\n';
|
//Logger::cout() << "arg: " << *arg << '\n';
|
||||||
gIR->ir->CreateCall(fn, arg, "");
|
gIR->ir->CreateCall(fn, arg, "");
|
||||||
gIR->ir->CreateUnreachable();
|
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);
|
assert(body);
|
||||||
|
|
||||||
p->scope() = IRScope(bodybb, endbb);
|
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);
|
body->toIR(p);
|
||||||
p->loopbbs.pop_back();
|
p->loopbbs.pop_back();
|
||||||
|
|
||||||
|
@ -851,7 +841,7 @@ void UnrolledLoopStatement::toIR(IRState* p)
|
||||||
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend);
|
llvm::BasicBlock* endbb = llvm::BasicBlock::Create("unrolledend", p->topfunc(), oldend);
|
||||||
|
|
||||||
p->scope() = IRScope(p->scopebb(),endbb);
|
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)
|
for (int i=0; i<statements->dim; ++i)
|
||||||
{
|
{
|
||||||
|
@ -974,7 +964,7 @@ void ForeachStatement::toIR(IRState* p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emit body
|
// emit body
|
||||||
p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,nextbb,endbb));
|
p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb));
|
||||||
body->toIR(p);
|
body->toIR(p);
|
||||||
p->loopbbs.pop_back();
|
p->loopbbs.pop_back();
|
||||||
|
|
||||||
|
@ -1047,7 +1037,7 @@ void GotoStatement::toIR(IRState* p)
|
||||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||||
llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend);
|
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);
|
p->scope() = IRScope(bb,oldend);
|
||||||
}
|
}
|
||||||
|
@ -1068,7 +1058,7 @@ void GotoDefaultStatement::toIR(IRState* p)
|
||||||
assert(!p->scopereturned());
|
assert(!p->scopereturned());
|
||||||
assert(sw->sdefault->bodyBB);
|
assert(sw->sdefault->bodyBB);
|
||||||
|
|
||||||
DtoFinallyBlocks(enclosingtryfinally, sw->enclosingtryfinally);
|
DtoEnclosingHandlers(enclosinghandler, sw->enclosinghandler);
|
||||||
|
|
||||||
llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb());
|
llvm::BranchInst::Create(sw->sdefault->bodyBB, p->scopebb());
|
||||||
p->scope() = IRScope(bb,oldend);
|
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());
|
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());
|
llvm::BranchInst::Create(cs->bodyBB, p->scopebb());
|
||||||
p->scope() = IRScope(bb,oldend);
|
p->scope() = IRScope(bb,oldend);
|
||||||
|
@ -1122,56 +1112,47 @@ 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)
|
void SynchronizedStatement::toIR(IRState* p)
|
||||||
{
|
{
|
||||||
Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars());
|
Logger::println("SynchronizedStatement::toIR(): %s", loc.toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
Logger::attention(loc, "synchronized is currently ignored. only the body will be emitted");
|
|
||||||
|
|
||||||
if (global.params.symdebug)
|
if (global.params.symdebug)
|
||||||
DtoDwarfStopPoint(loc.linnum);
|
DtoDwarfStopPoint(loc.linnum);
|
||||||
|
|
||||||
|
// enter lock
|
||||||
|
if (exp)
|
||||||
|
{
|
||||||
|
llsync = exp->toElem(p)->getRVal();
|
||||||
|
DtoEnterMonitor(llsync);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
llsync = generate_unique_critical_section();
|
||||||
|
DtoEnterCritical(llsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit body
|
||||||
body->toIR(p);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/* this has moved to asmstmt.cpp
|
|
||||||
void AsmStatement::toIR(IRState* p)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void VolatileStatement::toIR(IRState* p)
|
void VolatileStatement::toIR(IRState* p)
|
||||||
{
|
{
|
||||||
Logger::println("VolatileStatement::toIR(): %s", loc.toChars());
|
Logger::println("VolatileStatement::toIR(): %s", loc.toChars());
|
||||||
|
@ -1181,8 +1162,7 @@ void VolatileStatement::toIR(IRState* p)
|
||||||
DtoDwarfStopPoint(loc.linnum);
|
DtoDwarfStopPoint(loc.linnum);
|
||||||
|
|
||||||
// mark in-volatile
|
// mark in-volatile
|
||||||
bool old = gIR->func()->inVolatile;
|
// FIXME
|
||||||
gIR->func()->inVolatile = true;
|
|
||||||
|
|
||||||
// has statement
|
// has statement
|
||||||
if (statement != NULL)
|
if (statement != NULL)
|
||||||
|
@ -1193,7 +1173,7 @@ void VolatileStatement::toIR(IRState* p)
|
||||||
// do statement
|
// do statement
|
||||||
statement->toIR(p);
|
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())
|
if (statement->fallOffEnd())
|
||||||
{
|
{
|
||||||
// store-load
|
// store-load
|
||||||
|
@ -1208,7 +1188,7 @@ void VolatileStatement::toIR(IRState* p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore volatile state
|
// restore volatile state
|
||||||
gIR->func()->inVolatile = old;
|
// FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -637,6 +637,7 @@ size_t getTypeStoreSize(const LLType* t)
|
||||||
|
|
||||||
size_t getABITypeSize(const LLType* t)
|
size_t getABITypeSize(const LLType* t)
|
||||||
{
|
{
|
||||||
|
Logger::cout() << "getting abi type of: " << *t << '\n';
|
||||||
return gTargetData->getABITypeSize(t);
|
return gTargetData->getABITypeSize(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,12 +678,49 @@ const LLStructType* DtoInterfaceInfoType()
|
||||||
return gIR->interfaceInfoType;
|
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
|
// some types
|
||||||
const LLType* DtoSize_t();
|
const LLType* DtoSize_t();
|
||||||
const LLStructType* DtoInterfaceInfoType();
|
const LLStructType* DtoInterfaceInfoType();
|
||||||
|
const LLStructType* DtoMutexType();
|
||||||
|
|
||||||
// getelementptr helpers
|
// getelementptr helpers
|
||||||
LLValue* DtoGEP1(LLValue* ptr, LLValue* i0, const char* var=NULL, llvm::BasicBlock* bb=NULL);
|
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 "gen/tollvm.h"
|
||||||
#include "ir/irfunction.h"
|
#include "ir/irfunction.h"
|
||||||
|
|
||||||
|
@ -27,9 +29,4 @@ IrFunction::IrFunction(FuncDeclaration* fd)
|
||||||
|
|
||||||
srcfileArg = NULL;
|
srcfileArg = NULL;
|
||||||
msgArg = NULL;
|
msgArg = NULL;
|
||||||
inVolatile = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
IrFunction::~IrFunction()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,7 @@ struct IrFunction : IrBase
|
||||||
llvm::AllocaInst* srcfileArg;
|
llvm::AllocaInst* srcfileArg;
|
||||||
llvm::AllocaInst* msgArg;
|
llvm::AllocaInst* msgArg;
|
||||||
|
|
||||||
bool inVolatile;
|
|
||||||
|
|
||||||
IrFunction(FuncDeclaration* fd);
|
IrFunction(FuncDeclaration* fd);
|
||||||
virtual ~IrFunction();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue