mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-26 16:43:13 +01:00
[svn r19] * Added support for reassigning 'this' inside class constructors.
* Added preliminary support for UnrolledLoopStatement. That is foreach on a tuple.
This commit is contained in:
@@ -511,6 +511,7 @@ struct FuncDeclaration : Declaration
|
||||
FuncDeclaration *isFuncDeclaration() { return this; }
|
||||
|
||||
bool llvmQueued;
|
||||
llvm::Value* llvmThisVar;
|
||||
};
|
||||
|
||||
struct FuncAliasDeclaration : FuncDeclaration
|
||||
|
||||
@@ -74,6 +74,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
|
||||
nrvo_var = NULL;
|
||||
shidden = NULL;
|
||||
llvmQueued = false;
|
||||
llvmThisVar = NULL;
|
||||
}
|
||||
|
||||
Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
||||
@@ -18,6 +18,7 @@ elem::elem()
|
||||
inplace = false;
|
||||
field = false;
|
||||
callconv = (unsigned)-1;
|
||||
isthis = false;
|
||||
|
||||
vardecl = 0;
|
||||
funcdecl = 0;
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
bool inplace;
|
||||
bool field;
|
||||
unsigned callconv;
|
||||
bool isthis;
|
||||
|
||||
VarDeclaration* vardecl;
|
||||
FuncDeclaration* funcdecl;
|
||||
|
||||
@@ -78,9 +78,11 @@ struct IRState : Object
|
||||
// classes TODO move into IRClass
|
||||
typedef std::vector<ClassDeclaration*> ClassDeclVec;
|
||||
ClassDeclVec classes;
|
||||
|
||||
typedef std::vector<FuncDeclaration*> FuncDeclVec;
|
||||
typedef std::vector<FuncDeclVec> ClassMethodVec;
|
||||
ClassMethodVec classmethods;
|
||||
|
||||
typedef std::vector<bool> BoolVec;
|
||||
BoolVec queueClassMethods;
|
||||
|
||||
@@ -111,6 +113,9 @@ struct IRState : Object
|
||||
// VarDeclaration for __dollar, but I can't see how to get the
|
||||
// array pointer from this :(
|
||||
LvalVec arrays;
|
||||
|
||||
// keeping track of the declaration for the current function body
|
||||
FuncDeclVec funcdecls;
|
||||
};
|
||||
|
||||
#endif // LLVMDC_GEN_IRSTATE_H
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "gen/runtime.h"
|
||||
#include "gen/arrays.h"
|
||||
|
||||
/* --------------------------------------------------------------------------------------- */
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CompoundStatement::toIR(IRState* p)
|
||||
{
|
||||
@@ -71,6 +71,8 @@ void CompoundStatement::toIR(IRState* p)
|
||||
//p->bbs.pop();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ReturnStatement::toIR(IRState* p)
|
||||
{
|
||||
static int rsi = 0;
|
||||
@@ -134,6 +136,8 @@ void ReturnStatement::toIR(IRState* p)
|
||||
p->scope().returned = true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExpStatement::toIR(IRState* p)
|
||||
{
|
||||
static int esi = 0;
|
||||
@@ -150,6 +154,8 @@ void ExpStatement::toIR(IRState* p)
|
||||
p->buf.writenl();*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void IfStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -204,6 +210,8 @@ void IfStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(endbb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ScopeStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("ScopeStatement::toIR(): %s", toChars());
|
||||
@@ -240,6 +248,8 @@ void ScopeStatement::toIR(IRState* p)
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void WhileStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -281,6 +291,8 @@ void WhileStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(endbb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DoStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -313,6 +325,8 @@ void DoStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(endbb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ForStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -374,6 +388,8 @@ void ForStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(endbb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void BreakStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -389,6 +405,8 @@ void BreakStatement::toIR(IRState* p)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ContinueStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -404,6 +422,8 @@ void ContinueStatement::toIR(IRState* p)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void OnScopeStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -414,6 +434,8 @@ void OnScopeStatement::toIR(IRState* p)
|
||||
//statement->toIR(p); // this seems to be redundant
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TryFinallyStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -446,6 +468,8 @@ void TryFinallyStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(endbb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TryCatchStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -465,6 +489,8 @@ void TryCatchStatement::toIR(IRState* p)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ThrowStatement::toIR(IRState* p)
|
||||
{
|
||||
static int wsi = 0;
|
||||
@@ -478,6 +504,8 @@ void ThrowStatement::toIR(IRState* p)
|
||||
delete e;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SwitchStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("SwitchStatement::toIR(): %s", toChars());
|
||||
@@ -561,6 +589,35 @@ void SwitchStatement::toIR(IRState* p)
|
||||
gIR->scope() = IRScope(endbb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void UnrolledLoopStatement::toIR(IRState* p)
|
||||
{
|
||||
Logger::println("UnrolledLoopStatement::toIR(): %s", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
llvm::BasicBlock* oldend = gIR->scopeend();
|
||||
llvm::BasicBlock* endbb = new llvm::BasicBlock("unrolledend", p->topfunc(), oldend);
|
||||
|
||||
p->scope() = IRScope(p->scopebb(),endbb);
|
||||
p->loopbbs.push_back(IRScope(p->scopebb(),endbb));
|
||||
|
||||
for (int i=0; i<statements->dim; ++i)
|
||||
{
|
||||
Statement* s = (Statement*)statements->data[i];
|
||||
s->toIR(p);
|
||||
}
|
||||
|
||||
p->loopbbs.pop_back();
|
||||
|
||||
new llvm::BranchInst(endbb, p->scopebb());
|
||||
p->scope() = IRScope(endbb,oldend);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define STUBST(x) void x::toIR(IRState * p) {error("Statement type "#x" not implemented: %s", toChars());fatal();}
|
||||
//STUBST(BreakStatement);
|
||||
//STUBST(ForStatement);
|
||||
@@ -589,5 +646,5 @@ STUBST(LabelStatement);
|
||||
STUBST(GotoCaseStatement);
|
||||
STUBST(GotoDefaultStatement);
|
||||
STUBST(GotoStatement);
|
||||
STUBST(UnrolledLoopStatement);
|
||||
//STUBST(UnrolledLoopStatement);
|
||||
//STUBST(OnScopeStatement);
|
||||
|
||||
29
gen/toir.c
29
gen/toir.c
@@ -384,8 +384,19 @@ elem* AssignExp::toElem(IRState* p)
|
||||
else if (e1ty == Tclass) {
|
||||
if (e2ty == Tclass) {
|
||||
llvm::Value* tmp = r->getValue();
|
||||
Logger::cout() << "tmp: " << *tmp << ", " << *l->mem << '\n';
|
||||
new llvm::StoreInst(tmp, l->mem, p->scopebb());
|
||||
Logger::cout() << "tmp: " << *tmp << " ||| " << *l->mem << '\n';
|
||||
// assignment to this in constructor special case
|
||||
if (l->isthis) {
|
||||
FuncDeclaration* fdecl = p->funcdecls.back();
|
||||
// respecify the this param
|
||||
if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
|
||||
fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", p->topallocapoint());
|
||||
new llvm::StoreInst(tmp, fdecl->llvmThisVar, p->scopebb());
|
||||
}
|
||||
// regular class ref -> class ref assignment
|
||||
else {
|
||||
new llvm::StoreInst(tmp, l->mem, p->scopebb());
|
||||
}
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
@@ -1218,7 +1229,7 @@ elem* DotVarExp::toElem(IRState* p)
|
||||
TypeStruct* ts = (TypeStruct*)e1->type->next;
|
||||
ts->sym->offsetToIndex(vd->offset, vdoffsets);
|
||||
Logger::println("Struct member offset:%d", vd->offset);
|
||||
src = l->val;
|
||||
src = l->val ? l->val : l->mem;
|
||||
}
|
||||
else if (e1->type->ty == Tclass) {
|
||||
TypeClass* tc = (TypeClass*)e1->type;
|
||||
@@ -1279,7 +1290,7 @@ elem* ThisExp::toElem(IRState* p)
|
||||
elem* e = new elem;
|
||||
|
||||
if (VarDeclaration* vd = var->isVarDeclaration()) {
|
||||
assert(vd->llvmValue == 0);
|
||||
/*assert(vd->llvmValue == 0);
|
||||
|
||||
llvm::Function* fn = p->topfunc();
|
||||
assert(fn);
|
||||
@@ -1292,10 +1303,14 @@ elem* ThisExp::toElem(IRState* p)
|
||||
v = ++fn->arg_begin();
|
||||
else
|
||||
v = fn->arg_begin();
|
||||
assert(v);
|
||||
assert(v);*/
|
||||
|
||||
e->val = v;
|
||||
llvm::Value* v = p->funcdecls.back()->llvmThisVar;
|
||||
if (llvm::isa<llvm::AllocaInst>(v))
|
||||
v = new llvm::LoadInst(v, "tmp", p->scopebb());
|
||||
e->mem = v;
|
||||
e->type = elem::VAL;
|
||||
e->isthis = true;
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
@@ -1794,7 +1809,7 @@ elem* NewExp::toElem(IRState* p)
|
||||
|
||||
e->inplace = true;
|
||||
e->type = elem::VAR;
|
||||
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
13
gen/toobj.c
13
gen/toobj.c
@@ -665,9 +665,20 @@ void FuncDeclaration::toObjFile()
|
||||
// function definition
|
||||
if (allow_fbody && fbody != 0)
|
||||
{
|
||||
gIR->funcdecls.push_back(this);
|
||||
|
||||
// first make absolutely sure the type is up to date
|
||||
f->llvmType = llvmValue->getType()->getContainedType(0);
|
||||
|
||||
// this handling
|
||||
if (f->llvmUsesThis) {
|
||||
if (f->llvmRetInPtr)
|
||||
llvmThisVar = ++func->arg_begin();
|
||||
else
|
||||
llvmThisVar = func->arg_begin();
|
||||
assert(llvmThisVar != 0);
|
||||
}
|
||||
|
||||
if (isMain())
|
||||
gIR->emitMain = true;
|
||||
|
||||
@@ -716,6 +727,8 @@ void FuncDeclaration::toObjFile()
|
||||
// possibly assert(lastbb->getNumPredecessors() == 0); ??? try it out sometime ...
|
||||
new llvm::UnreachableInst(lastbb);
|
||||
}
|
||||
|
||||
gIR->funcdecls.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
22
test/classes8.d
Normal file
22
test/classes8.d
Normal file
@@ -0,0 +1,22 @@
|
||||
class A {
|
||||
int i;
|
||||
int l;
|
||||
this(bool b,bool b2=false) {
|
||||
if (b) this = new B;
|
||||
i = 4;
|
||||
if (b2) this = new C;
|
||||
l = 64;
|
||||
}
|
||||
}
|
||||
class B : A{
|
||||
this() {
|
||||
super(false);
|
||||
}
|
||||
}
|
||||
class C : A{
|
||||
this() {
|
||||
super(false);
|
||||
}
|
||||
}
|
||||
void main() {
|
||||
}
|
||||
13
test/unrolled.d
Normal file
13
test/unrolled.d
Normal file
@@ -0,0 +1,13 @@
|
||||
module unrolled;
|
||||
|
||||
void test(T...)(T t) {
|
||||
foreach (value; t) {
|
||||
printf("%d\n", value);
|
||||
if (value == 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
test(1,4,3);
|
||||
}
|
||||
Reference in New Issue
Block a user