mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 19:06:02 +03:00
Emit stub debug info for generated functions to work around LLVM bug 2172.
This commit is contained in:
parent
c2f17bda87
commit
b413b9aa54
3 changed files with 103 additions and 2 deletions
|
@ -149,6 +149,28 @@ static LLGlobalVariable* dwarfCompileUnit(Module* m)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static LLGlobalVariable* dwarfSubProgram(llvm::GlobalVariable* emitUnit, llvm::GlobalVariable* defineUnit, const char* prettyname, const char* mangledname, uint linenum, bool isprivate)
|
||||
{
|
||||
std::vector<LLConstant*> vals(11);
|
||||
vals[0] = DBG_TAG(DW_TAG_subprogram);
|
||||
vals[1] = DBG_CAST(getDwarfAnchor(DW_TAG_subprogram));
|
||||
|
||||
vals[2] = DBG_CAST(emitUnit);
|
||||
vals[3] = DtoConstStringPtr(prettyname, "llvm.metadata");
|
||||
vals[4] = vals[3];
|
||||
vals[5] = DtoConstStringPtr(mangledname, "llvm.metadata");
|
||||
vals[6] = DBG_CAST(defineUnit);
|
||||
vals[7] = DtoConstUint(linenum);
|
||||
vals[8] = DBG_NULL;
|
||||
vals[9] = DtoConstBool(isprivate);
|
||||
vals[10] = DtoConstBool(emitUnit == defineUnit);
|
||||
|
||||
Logger::println("emitting subprogram global");
|
||||
|
||||
return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram");
|
||||
}
|
||||
|
||||
/*
|
||||
static LLGlobalVariable* dwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit)
|
||||
{
|
||||
std::vector<LLConstant*> vals(11);
|
||||
|
@ -168,7 +190,7 @@ static LLGlobalVariable* dwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariab
|
|||
Logger::println("emitting subprogram global");
|
||||
|
||||
return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram");
|
||||
}
|
||||
}*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -648,7 +670,28 @@ LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
|
|||
LOG_SCOPE;
|
||||
|
||||
// FIXME: duplicates ?
|
||||
return dwarfSubProgram(fd, DtoDwarfCompileUnit(gIR->dmodule));
|
||||
return dwarfSubProgram(
|
||||
DtoDwarfCompileUnit(gIR->dmodule),
|
||||
DtoDwarfCompileUnit(fd->getModule()),
|
||||
fd->toPrettyChars(), fd->mangle(),
|
||||
fd->loc.linnum,
|
||||
fd->protection == PROTprivate);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLGlobalVariable* DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname)
|
||||
{
|
||||
Logger::println("D to dwarf subprogram");
|
||||
LOG_SCOPE;
|
||||
|
||||
// FIXME: duplicates ?
|
||||
return dwarfSubProgram(
|
||||
DtoDwarfCompileUnit(gIR->dmodule),
|
||||
DtoDwarfCompileUnit(gIR->dmodule),
|
||||
prettyname, mangledname,
|
||||
0,
|
||||
true);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -17,6 +17,14 @@ llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m);
|
|||
*/
|
||||
llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd);
|
||||
|
||||
/**
|
||||
* Emit the Dwarf subprogram global for a internal function.
|
||||
* This is used for generated functions like moduleinfoctors,
|
||||
* module ctors/dtors and unittests.
|
||||
* @return the Dwarf subprogram global.
|
||||
*/
|
||||
llvm::GlobalVariable* DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname);
|
||||
|
||||
void DtoDwarfFuncStart(FuncDeclaration* fd);
|
||||
void DtoDwarfFuncEnd(FuncDeclaration* fd);
|
||||
|
||||
|
|
|
@ -449,6 +449,12 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath, ch
|
|||
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
// the following code generates functions and needs to output
|
||||
// debug info. these macros are useful for that
|
||||
#define DBG_TYPE ( getPtrToType(llvm::StructType::get(NULL,NULL)) )
|
||||
#define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) )
|
||||
|
||||
// build module ctor
|
||||
|
||||
llvm::Function* build_module_ctor()
|
||||
|
@ -473,12 +479,23 @@ llvm::Function* build_module_ctor()
|
|||
llvm::BasicBlock* bb = llvm::BasicBlock::Create("entry", fn);
|
||||
IRBuilder<> builder(bb);
|
||||
|
||||
// debug info
|
||||
LLGlobalVariable* subprog;
|
||||
if(global.params.symdebug) {
|
||||
subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str());
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
|
||||
}
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
llvm::Function* f = gIR->ctors[i]->ir.irFunc->func;
|
||||
llvm::CallInst* call = builder.CreateCall(f,"");
|
||||
call->setCallingConv(llvm::CallingConv::Fast);
|
||||
}
|
||||
|
||||
// debug info end
|
||||
if(global.params.symdebug)
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
|
||||
|
||||
builder.CreateRetVoid();
|
||||
return fn;
|
||||
}
|
||||
|
@ -507,12 +524,23 @@ static llvm::Function* build_module_dtor()
|
|||
llvm::BasicBlock* bb = llvm::BasicBlock::Create("entry", fn);
|
||||
IRBuilder<> builder(bb);
|
||||
|
||||
// debug info
|
||||
LLGlobalVariable* subprog;
|
||||
if(global.params.symdebug) {
|
||||
subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str());
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
|
||||
}
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
llvm::Function* f = gIR->dtors[i]->ir.irFunc->func;
|
||||
llvm::CallInst* call = builder.CreateCall(f,"");
|
||||
call->setCallingConv(llvm::CallingConv::Fast);
|
||||
}
|
||||
|
||||
// debug info end
|
||||
if(global.params.symdebug)
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
|
||||
|
||||
builder.CreateRetVoid();
|
||||
return fn;
|
||||
}
|
||||
|
@ -541,12 +569,23 @@ static llvm::Function* build_module_unittest()
|
|||
llvm::BasicBlock* bb = llvm::BasicBlock::Create("entry", fn);
|
||||
IRBuilder<> builder(bb);
|
||||
|
||||
// debug info
|
||||
LLGlobalVariable* subprog;
|
||||
if(global.params.symdebug) {
|
||||
subprog = DtoDwarfSubProgramInternal(name.c_str(), name.c_str());
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
|
||||
}
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
llvm::Function* f = gIR->unitTests[i]->ir.irFunc->func;
|
||||
llvm::CallInst* call = builder.CreateCall(f,"");
|
||||
call->setCallingConv(llvm::CallingConv::Fast);
|
||||
}
|
||||
|
||||
// debug info end
|
||||
if(global.params.symdebug)
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
|
||||
|
||||
builder.CreateRetVoid();
|
||||
return fn;
|
||||
}
|
||||
|
@ -587,6 +626,13 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
|
|||
llvm::BasicBlock* bb = llvm::BasicBlock::Create("moduleinfoCtorEntry", ctor);
|
||||
IRBuilder<> builder(bb);
|
||||
|
||||
// debug info
|
||||
LLGlobalVariable* subprog;
|
||||
if(global.params.symdebug) {
|
||||
subprog = DtoDwarfSubProgramInternal(fname.c_str(), fname.c_str());
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(subprog));
|
||||
}
|
||||
|
||||
// get current beginning
|
||||
LLValue* curbeg = builder.CreateLoad(mref, "current");
|
||||
|
||||
|
@ -597,6 +643,10 @@ static LLFunction* build_module_reference_and_ctor(LLConstant* moduleinfo)
|
|||
// replace beginning
|
||||
builder.CreateStore(thismref, mref);
|
||||
|
||||
// debug info end
|
||||
if(global.params.symdebug)
|
||||
builder.CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(subprog));
|
||||
|
||||
// return
|
||||
builder.CreateRetVoid();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue