diff --git a/gen/aa.cpp b/gen/aa.cpp index b6303f1c..bb31940a 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -111,7 +111,8 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) std::vector args; // file param - args.push_back(DtoLoad(gIR->dmodule->ir.irModule->fileName)); + IrModule* irmod = getIrModule(NULL); + args.push_back(DtoLoad(irmod->fileName)); // line param LLConstant* c = DtoConstUint(loc.linnum); diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 3ba220be..81accf2d 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -978,7 +978,8 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to) void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice) { Type* arrty = arr->getType()->toBasetype(); - assert((arrty->ty == Tsarray || arrty->ty == Tarray) && "Can only array bounds check for static or dynamic arrays"); + assert((arrty->ty == Tsarray || arrty->ty == Tarray) && + "Can only array bounds check for static or dynamic arrays"); // static arrays could get static checks for static indices // but shouldn't since it might be generic code that's never executed @@ -1000,7 +1001,10 @@ void DtoArrayBoundsCheck(Loc& loc, DValue* arr, DValue* index, bool isslice) std::vector args; // file param - args.push_back(DtoLoad(gIR->dmodule->ir.irModule->fileName)); + // get the filename from the function symbol instead of the current module + // it's wrong for instantiations of imported templates. Fixes LDC bug #271 + Module* funcmodule = gIR->func()->decl->getModule(); + args.push_back(DtoLoad(getIrModule(NULL)->fileName)); // line param LLConstant* c = DtoConstUint(loc.linnum); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index cf6cce53..0861196a 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -128,10 +128,9 @@ void DtoAssert(Module* M, Loc loc, DValue* msg) // file param // we might be generating for an imported template function - if (!M->ir.irModule) - M->ir.irModule = new IrModule(M, M->srcfile->toChars()); + IrModule* irmod = getIrModule(M); - args.push_back(DtoLoad(M->ir.irModule->fileName)); + args.push_back(DtoLoad(irmod->fileName)); // line param LLConstant* c = DtoConstUint(loc.linnum); @@ -1399,3 +1398,17 @@ bool hasUnalignedFields(Type* t) ts->unaligned = 1; return false; } + +////////////////////////////////////////////////////////////////////////////////////////// + +IrModule * getIrModule(Module * M) +{ + if (M == NULL) + M = gIR->func()->decl->getModule(); + assert(M && "null module"); + if (!M->ir.irModule) + M->ir.irModule = new IrModule(M, M->srcfile->toChars()); + return M->ir.irModule; +} + +////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 083970dd..2d49e75c 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -137,6 +137,9 @@ bool hasUnalignedFields(Type* t); /// DValue* DtoInlineAsmExpr(Loc loc, FuncDeclaration* fd, Expressions* arguments); +/// Create the IrModule if necessary and returns it. +IrModule* getIrModule(Module* M); + //////////////////////////////////////////// // gen/tocall.cpp stuff below //////////////////////////////////////////// diff --git a/gen/statements.cpp b/gen/statements.cpp index dcd1485b..6986501b 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -1466,7 +1466,8 @@ void SwitchErrorStatement::toIR(IRState* p) std::vector args; // file param - args.push_back(DtoLoad(gIR->dmodule->ir.irModule->fileName)); + IrModule* irmod = getIrModule(NULL); + args.push_back(DtoLoad(irmod->fileName)); // line param LLConstant* c = DtoConstUint(loc.linnum); diff --git a/gen/todebug.cpp b/gen/todebug.cpp index 6b5a0bb3..47616097 100644 --- a/gen/todebug.cpp +++ b/gen/todebug.cpp @@ -476,13 +476,13 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m) LOG_SCOPE; // we might be generating for an import - if (!m->ir.irModule) - m->ir.irModule = new IrModule(m, m->srcfile->toChars()); - else if (!m->ir.irModule->diCompileUnit.isNull()) + IrModule* irmod = getIrModule(m); + + if (!irmod->diCompileUnit.isNull()) { - assert (m->ir.irModule->diCompileUnit.getGV()->getParent() == gIR->module + assert (irmod->diCompileUnit.getGV()->getParent() == gIR->module && "debug info compile unit belongs to incorrect llvm module!"); - return m->ir.irModule->diCompileUnit; + return irmod->diCompileUnit; } // prepare srcpath @@ -496,7 +496,7 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m) } // make compile unit - m->ir.irModule->diCompileUnit = gIR->difactory.CreateCompileUnit( + irmod->diCompileUnit = gIR->difactory.CreateCompileUnit( global.params.symdebug == 2 ? DW_LANG_C : DW_LANG_D, m->srcfile->name->toChars(), srcpath, @@ -509,10 +509,10 @@ llvm::DICompileUnit DtoDwarfCompileUnit(Module* m) // if the linkage stays internal, we can't llvm-link the generated modules together: // llvm's DwarfWriter uses path and filename to determine the symbol name and we'd // end up with duplicate symbols - m->ir.irModule->diCompileUnit.getGV()->setLinkage(DEBUGINFO_LINKONCE_LINKAGE_TYPE); - m->ir.irModule->diCompileUnit.getGV()->setName(std::string("llvm.dbg.compile_unit_") + srcpath + m->srcfile->name->toChars()); + irmod->diCompileUnit.getGV()->setLinkage(DEBUGINFO_LINKONCE_LINKAGE_TYPE); + irmod->diCompileUnit.getGV()->setName(std::string("llvm.dbg.compile_unit_") + srcpath + m->srcfile->name->toChars()); - return m->ir.irModule->diCompileUnit; + return irmod->diCompileUnit; } ////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/toir.cpp b/gen/toir.cpp index d2afc2e4..3ee174c3 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1165,17 +1165,8 @@ DValue* ThisExp::toElem(IRState* p) Logger::print("ThisExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; - // this seems to happen for dmd generated assert statements like: - // assert(this, "null this"); - // FIXME: check for TOKthis in AssertExp instead - if (!var) - { - LLValue* v = p->func()->thisArg; - assert(v); - return new DVarValue(type, v); - } // regular this expr - else if (VarDeclaration* vd = var->isVarDeclaration()) { + if (VarDeclaration* vd = var->isVarDeclaration()) { LLValue* v; if (vd->toParent2() != p->func()->decl) { Logger::println("nested this exp"); @@ -1189,7 +1180,7 @@ DValue* ThisExp::toElem(IRState* p) } // anything we're not yet handling ? - assert(0); + assert(0 && "no var in ThisExp"); return 0; } @@ -1753,8 +1744,24 @@ DValue* AssertExp::toElem(IRState* p) return NULL; // condition - DValue* cond = e1->toElem(p); - Type* condty = e1->type->toBasetype(); + DValue* cond; + Type* condty; + + // special case assert(this); + if (e1->op == TOKthis) + { + LLValue* thisarg = p->func()->thisArg; + assert(thisarg && "null thisarg, but we're in assert(this) exp;"); + LLValue* thisptr = DtoLoad(p->func()->thisArg); + LLValue* thisnotnull = p->ir->CreateIsNotNull(thisptr); + cond = new DImValue(Type::tbool, thisnotnull); + condty = Type::tbool; + } + else + { + cond = e1->toElem(p); + condty = e1->type->toBasetype(); + } InvariantDeclaration* invdecl; diff --git a/gen/toobj.cpp b/gen/toobj.cpp index e1a1f1a2..4036c820 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -99,12 +99,6 @@ llvm::Module* Module::genLLVMModule(Ir* sir) sir->setState(&ir); - // module ir state - // might already exist via import, just overwrite since - // the global created for the filename must belong to the right llvm module - // FIXME: but shouldn't this always get reset between modules? like other IrSymbols - this->ir.irModule = new IrModule(this, srcfile->toChars()); - // set target triple ir.module->setTargetTriple(global.params.targetTriple);