diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index f33391669e..9c68808b6b 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1320,6 +1320,46 @@ DValue* DtoDeclarationExp(Dsymbol* declaration) return NULL; } +// does pretty much the same as DtoDeclarationExp, except it doesn't initialize, and only handles var declarations +LLValue* DtoRawVarDeclaration(VarDeclaration* var) +{ + // we don't handle globals with this one + assert(!var->isDataseg()); + + // we don't handle aliases either + assert(!var->aliassym); + + // referenced by nested function? + if (var->nestedref) + { + assert(var->ir.irLocal); + assert(!var->ir.irLocal->value); + + // alloca + var->ir.irLocal->value = DtoAlloca(DtoType(var->type), var->toChars()); + + // store the address into the nested vars array + assert(var->ir.irLocal->nestedIndex >= 0); + LLValue* gep = DtoGEPi(gIR->func()->decl->ir.irFunc->nestedVar, 0, var->ir.irLocal->nestedIndex); + assert(isaPointer(var->ir.irLocal->value)); + LLValue* val = DtoBitCast(var->ir.irLocal->value, getVoidPtrType()); + DtoStore(val, gep); + } + // normal local variable + else + { + assert(!var->ir.isSet()); + var->ir.irLocal = new IrLocal(var); + var->ir.irLocal->value = DtoAlloca(DtoType(var->type), var->toChars()); + } + + // add debug info + if (global.params.symdebug) + DtoDwarfLocalVariable(var->ir.irLocal->value, var); + + // return the alloca + return var->ir.irLocal->value; +} /****************************************************************************************/ /*//////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 26044ec374..fa1406d401 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -83,6 +83,7 @@ void DtoForceDefineDsymbol(Dsymbol* dsym); // declaration inside a declarationexp DValue* DtoDeclarationExp(Dsymbol* declaration); +LLValue* DtoRawVarDeclaration(VarDeclaration* var); // initializer helpers LLConstant* DtoConstInitializer(Type* type, Initializer* init); diff --git a/gen/statements.cpp b/gen/statements.cpp index 3f6ed7a910..d635b850f7 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -154,7 +154,7 @@ void IfStatement::toIR(IRState* p) DtoDwarfStopPoint(loc.linnum); if (match) - DtoDeclarationExp(match); + DtoRawVarDeclaration(match); DValue* cond_e = condition->toElem(p); LLValue* cond_val = cond_e->getRVal(); @@ -926,17 +926,14 @@ void ForeachStatement::toIR(IRState* p) const LLType* keytype = key ? DtoType(key->type) : DtoSize_t(); LLValue* keyvar; if (key) - { - DtoDeclarationExp(key); - keyvar = key->ir.irLocal->value; - } + keyvar = DtoRawVarDeclaration(key); else keyvar = DtoAlloca(keytype, "foreachkey"); LLValue* zerokey = llvm::ConstantInt::get(keytype,0,false); // value Logger::println("value = %s", value->toPrettyChars()); - DtoDeclarationExp(value); + DtoRawVarDeclaration(value); const LLType* valtype = DtoType(value->type); LLValue* valvar = NULL; if (!value->isRef() && !value->isOut()) @@ -1149,30 +1146,8 @@ void WithStatement::toIR(IRState* p) assert(body); DValue* e = exp->toElem(p); - - // DtoDeclarationExp(wthis); or preferably equivalent without initialization... - if (wthis->ir.isSet()) - { - assert(wthis->nestedref); - assert(wthis->ir.irLocal); - assert(!wthis->ir.irLocal->value); - wthis->ir.irLocal->value = DtoAlloca(DtoType(wthis->type), wthis->toChars()); - - // store the address into the nested vars array - assert(wthis->ir.irLocal->nestedIndex >= 0); - LLValue* gep = DtoGEPi(gIR->func()->decl->ir.irFunc->nestedVar, 0, wthis->ir.irLocal->nestedIndex); - assert(isaPointer(wthis->ir.irLocal->value)); - LLValue* val = DtoBitCast(wthis->ir.irLocal->value, getVoidPtrType()); - DtoStore(val, gep); - } - else - { - assert(!wthis->nestedref); - wthis->ir.irLocal = new IrLocal(wthis); - wthis->ir.irLocal->value = DtoAlloca(DtoType(wthis->type), wthis->toChars()); - } - - DtoStore(e->getRVal(), wthis->ir.irLocal->value); + LLValue* mem = DtoRawVarDeclaration(wthis); + DtoStore(e->getRVal(), mem); body->toIR(p); }