changeset 686:363bb6c0cc80

Emit stub debug info for generated functions to work around LLVM bug 2172.
author Christian Kamm <kamm incasoftware de>
date Sun, 12 Oct 2008 14:38:55 +0200
parents 8d7e58801c82
children 0a682c7805d2
files gen/todebug.cpp gen/todebug.h gen/toobj.cpp
diffstat 3 files changed, 103 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/gen/todebug.cpp	Sun Oct 12 11:23:27 2008 +0200
+++ b/gen/todebug.cpp	Sun Oct 12 14:38:55 2008 +0200
@@ -149,6 +149,28 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
+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 @@
     Logger::println("emitting subprogram global");
 
     return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram");
-}
+}*/
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -648,7 +670,28 @@
     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);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/todebug.h	Sun Oct 12 11:23:27 2008 +0200
+++ b/gen/todebug.h	Sun Oct 12 14:38:55 2008 +0200
@@ -17,6 +17,14 @@
  */
 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);
 
--- a/gen/toobj.cpp	Sun Oct 12 11:23:27 2008 +0200
+++ b/gen/toobj.cpp	Sun Oct 12 14:38:55 2008 +0200
@@ -449,6 +449,12 @@
 
 
 /* ================================================================== */
+
+// 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::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 @@
     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 @@
     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 @@
     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 @@
     // 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();