diff gen/statements.cpp @ 758:f04dde6e882c

Added initial D2 support, D2 frontend and changes to codegen to make things compile.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:38:48 +0100
parents 46d0755451a4
children 9688da40cd4d
line wrap: on
line diff
--- a/gen/statements.cpp	Mon Nov 10 20:55:24 2008 +0100
+++ b/gen/statements.cpp	Tue Nov 11 01:38:48 2008 +0100
@@ -353,9 +353,17 @@
     gIR->scope() = IRScope(forbb,forbodybb);
 
     // create the condition
-    DValue* cond_e = condition->toElem(p);
-    LLValue* cond_val = DtoBoolean(loc, cond_e);
-    delete cond_e;
+    LLValue* cond_val;
+    if (condition)
+    {
+        DValue* cond_e = condition->toElem(p);
+        cond_val = DtoBoolean(loc, cond_e);
+        delete cond_e;
+    }
+    else
+    {
+        cond_val = DtoConstBool(true);
+    }
 
     // conditional branch
     assert(!gIR->scopereturned());
@@ -675,7 +683,7 @@
 static LLValue* call_string_switch_runtime(llvm::Value* table, Expression* e)
 {
     Type* dt = e->type->toBasetype();
-    Type* dtnext = dt->next->toBasetype();
+    Type* dtnext = dt->nextOf()->toBasetype();
     TY ty = dtnext->ty;
     const char* fname;
     if (ty == Tchar) {
@@ -1029,6 +1037,111 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+#if DMDV2
+
+void ForeachRangeStatement::toIR(IRState* p)
+{
+    Logger::println("ForeachRangeStatement::toIR(): %s", loc.toChars());
+    LOG_SCOPE;
+
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
+
+    // evaluate lwr/upr
+    assert(lwr->type->isintegral());
+    LLValue* lower = lwr->toElem(p)->getRVal();
+    assert(upr->type->isintegral());
+    LLValue* upper = upr->toElem(p)->getRVal();
+
+    // handle key
+    assert(key->type->isintegral());
+    LLValue* keyval = DtoRawVarDeclaration(key);
+
+    // store initial value in key
+    if (op == TOKforeach)
+        DtoStore(lower, keyval);
+    else
+        DtoStore(upper, keyval);
+
+    // set up the block we'll need
+    llvm::BasicBlock* oldend = gIR->scopeend();
+    llvm::BasicBlock* condbb = llvm::BasicBlock::Create("foreachrange_cond", p->topfunc(), oldend);
+    llvm::BasicBlock* bodybb = llvm::BasicBlock::Create("foreachrange_body", p->topfunc(), oldend);
+    llvm::BasicBlock* nextbb = llvm::BasicBlock::Create("foreachrange_next", p->topfunc(), oldend);
+    llvm::BasicBlock* endbb = llvm::BasicBlock::Create("foreachrange_end", p->topfunc(), oldend);
+
+    // jump to condition
+    llvm::BranchInst::Create(condbb, p->scopebb());
+
+    // CONDITION
+    p->scope() = IRScope(condbb,bodybb);
+
+    // first we test that lwr < upr
+    lower = DtoLoad(keyval);
+    assert(lower->getType() == upper->getType());
+    llvm::ICmpInst::Predicate cmpop;
+    if (key->type->isunsigned())
+    {
+        cmpop = (op == TOKforeach)
+        ? llvm::ICmpInst::ICMP_ULT
+        : llvm::ICmpInst::ICMP_UGT;
+    }
+    else
+    {
+        cmpop = (op == TOKforeach)
+        ? llvm::ICmpInst::ICMP_SLT
+        : llvm::ICmpInst::ICMP_SGT;
+    }
+    LLValue* cond = p->ir->CreateICmp(cmpop, lower, upper);
+
+    // jump to the body if range is ok, to the end if not
+    llvm::BranchInst::Create(bodybb, endbb, cond, p->scopebb());
+
+    // BODY
+    p->scope() = IRScope(bodybb,nextbb);
+
+    // reverse foreach decrements here
+    if (op == TOKforeach_reverse)
+    {
+        LLValue* v = DtoLoad(keyval);
+        LLValue* one = LLConstantInt::get(v->getType(), 1, false);
+        v = p->ir->CreateSub(v, one);
+        DtoStore(v, keyval);
+    }
+
+    // emit body
+    p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,nextbb,endbb));
+    if (body)
+        body->toIR(p);
+    p->loopbbs.pop_back();
+
+    // jump to next iteration
+    if (!p->scopereturned())
+        llvm::BranchInst::Create(nextbb, p->scopebb());
+
+    // NEXT
+    p->scope() = IRScope(nextbb,endbb);
+
+    // forward foreach increments here
+    if (op == TOKforeach)
+    {
+        LLValue* v = DtoLoad(keyval);
+        LLValue* one = LLConstantInt::get(v->getType(), 1, false);
+        v = p->ir->CreateAdd(v, one);
+        DtoStore(v, keyval);
+    }
+
+    // jump to condition
+    llvm::BranchInst::Create(condbb, p->scopebb());
+
+    // END
+    p->scope() = IRScope(endbb,oldend);
+}
+
+#endif // D2
+
+//////////////////////////////////////////////////////////////////////////////
+
 void LabelStatement::toIR(IRState* p)
 {
     Logger::println("LabelStatement::toIR(): %s", loc.toChars());
@@ -1291,3 +1404,7 @@
 //STUBST(GotoStatement);
 //STUBST(UnrolledLoopStatement);
 //STUBST(OnScopeStatement);
+
+#if DMDV2
+STUBST(PragmaStatement);
+#endif