changeset 252:e3355ce5444b trunk

[svn r269] Fixed dwarf debug info for structs.
author lindquist
date Thu, 12 Jun 2008 16:58:26 +0200
parents 2f2d7c843e5d
children c6f25edd6ef3
files gen/irstate.cpp gen/irstate.h gen/todebug.cpp ir/irmodule.cpp ir/irmodule.h ir/irstruct.cpp ir/irstruct.h llvmdc.kdevelop.filelist
diffstat 8 files changed, 149 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/gen/irstate.cpp	Wed Jun 11 21:03:55 2008 +0200
+++ b/gen/irstate.cpp	Thu Jun 12 16:58:26 2008 +0200
@@ -54,6 +54,10 @@
     mainFunc = 0;
     ir.state = this;
     asmBlock = NULL;
+
+    dwarfCUs = NULL;
+    dwarfSPs = NULL;
+    dwarfGVs = NULL;
 }
 
 IrFunction* IRState::func()
--- a/gen/irstate.h	Wed Jun 11 21:03:55 2008 +0200
+++ b/gen/irstate.h	Thu Jun 12 16:58:26 2008 +0200
@@ -159,8 +159,12 @@
     // for inline asm
     IRAsmBlock* asmBlock;
 
-    // used array solely for keeping a reference to globals
+    // dwarf dbg stuff
+    // 'used' array solely for keeping a reference to globals
     std::vector<LLConstant*> usedArray;
+    LLGlobalVariable* dwarfCUs;
+    LLGlobalVariable* dwarfSPs;
+    LLGlobalVariable* dwarfGVs;
 };
 
 #endif // LLVMDC_GEN_IRSTATE_H
--- a/gen/todebug.cpp	Wed Jun 11 21:03:55 2008 +0200
+++ b/gen/todebug.cpp	Thu Jun 12 16:58:26 2008 +0200
@@ -34,17 +34,27 @@
 {
     LLConstant* c = llvm::ConstantStruct::get(type, values);
     LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage;
-    LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, linkage, c, name, gIR->module);
+    LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, c, name, gIR->module);
+    gv->setSection("llvm.metadata");
+    return gv;
+}
+
+/**
+ * Emits a global variable, LLVM Dwarf style, only declares.
+ * @param type Type of variable.
+ * @param name Name.
+ * @return The global variable.
+ */
+static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const char* name, bool linkonce=false)
+{
+    LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage;
+    LLGlobalVariable* gv = new LLGlobalVariable(type, true, linkage, NULL, name, gIR->module);
     gv->setSection("llvm.metadata");
     return gv;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-static llvm::GlobalVariable* dbg_compile_units = 0;
-static llvm::GlobalVariable* dbg_global_variables = 0;
-static llvm::GlobalVariable* dbg_subprograms = 0;
-
 /**
  * Emits the Dwarf anchors that are used repeatedly by LLVM debug info.
  */
@@ -53,34 +63,33 @@
     const llvm::StructType* anchorTy = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type"));
     std::vector<LLConstant*> vals(2);
 
-    if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) {
-        vals[0] = DtoConstUint(llvm::LLVMDebugVersion);
-        vals[1] = DtoConstUint(DW_TAG_compile_unit);
-        dbg_compile_units = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.compile_units", true);
-    }
-    if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) {
-        vals[0] = DtoConstUint(llvm::LLVMDebugVersion);
-        vals[1] = DtoConstUint(DW_TAG_variable);
-        dbg_global_variables = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.global_variables", true);
-    }
-    if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) {
-        vals[0] = DtoConstUint(llvm::LLVMDebugVersion);
-        vals[1] = DtoConstUint(DW_TAG_subprogram);
-        dbg_subprograms = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.subprograms", true);
-    }
+    vals[0] = DtoConstUint(llvm::LLVMDebugVersion);
+    vals[1] = DtoConstUint(DW_TAG_compile_unit);
+    gIR->dwarfCUs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.compile_units", true);
+
+    vals[0] = DtoConstUint(llvm::LLVMDebugVersion);
+    vals[1] = DtoConstUint(DW_TAG_variable);
+    gIR->dwarfGVs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.global_variables", true);
+
+    vals[0] = DtoConstUint(llvm::LLVMDebugVersion);
+    vals[1] = DtoConstUint(DW_TAG_subprogram);
+    gIR->dwarfSPs = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.subprograms", true);
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
 static LLConstant* getDwarfAnchor(dwarf_constants c)
 {
-    emitDwarfAnchors();
+    if (!gIR->dwarfCUs)
+        emitDwarfAnchors();
     switch (c)
     {
     case DW_TAG_compile_unit:
-        return dbg_compile_units;
+        return gIR->dwarfCUs;
     case DW_TAG_variable:
-        return dbg_global_variables;
+        return gIR->dwarfGVs;
     case DW_TAG_subprogram:
-        return dbg_subprograms;
+        return gIR->dwarfSPs;
     default:
         assert(0);
     }
@@ -163,7 +172,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-static LLGlobalVariable* dwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu, const char* c_name);
+static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name);
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -226,7 +235,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-static LLGlobalVariable* dwarfDerivedType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit)
+static LLGlobalVariable* dwarfDerivedType(Type* type, llvm::GlobalVariable* compileUnit)
 {
     const LLType* T = DtoType(type);
     Type* t = DtoDType(type);
@@ -276,7 +285,7 @@
 
     // base type
     Type* nt = t->nextOf();
-    LLGlobalVariable* nTD = dwarfTypeDescription(loc, nt, compileUnit, NULL);
+    LLGlobalVariable* nTD = dwarfTypeDescription(nt, compileUnit, NULL);
     if (nt->ty == Tvoid || !nTD)
         vals.push_back(DBG_NULL);
     else
@@ -287,7 +296,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-static LLGlobalVariable* dwarfMemberType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit, const char* c_name, unsigned offset)
+static LLGlobalVariable* dwarfMemberType(unsigned linnum, Type* type, LLGlobalVariable* compileUnit, LLGlobalVariable* definedCU, const char* c_name, unsigned offset)
 {
     const LLType* T = DtoType(type);
     Type* t = DtoDType(type);
@@ -311,10 +320,13 @@
     vals.push_back(name);
 
     // compile unit where defined
-    vals.push_back(DBG_NULL);
+    if (definedCU)
+        vals.push_back(DBG_CAST(definedCU));
+    else
+        vals.push_back(DBG_NULL);
 
     // line number where defined
-    vals.push_back(DtoConstInt(0));
+    vals.push_back(DtoConstInt(linnum));
 
     // size in bits
     vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
@@ -329,7 +341,7 @@
     vals.push_back(DtoConstUint(0));
 
     // base type
-    LLGlobalVariable* nTD = dwarfTypeDescription(loc, t, compileUnit, NULL);
+    LLGlobalVariable* nTD = dwarfTypeDescription(t, compileUnit, NULL);
     if (t->ty == Tvoid || !nTD)
         vals.push_back(DBG_NULL);
     else
@@ -340,7 +352,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-static LLGlobalVariable* dwarfCompositeType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit)
+static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* compileUnit)
 {
     const LLType* T = DtoType(type);
     Type* t = DtoDType(type);
@@ -348,16 +360,23 @@
     // defaults
     LLConstant* name = getNullPtr(getVoidPtrType());
     LLGlobalVariable* members = NULL;
+    unsigned linnum = 0;
+    LLGlobalVariable* definedCU = NULL;
 
     // prepare tag and members
     unsigned tag;
+
+    // declare final global variable
+    LLGlobalVariable* gv = NULL;
+
+    // dynamic array
     if (t->ty == Tarray)
     {
         tag = DW_TAG_structure_type;
 
-        LLGlobalVariable* len = dwarfMemberType(loc, Type::tsize_t, compileUnit, "length", 0);
+        LLGlobalVariable* len = dwarfMemberType(0, Type::tsize_t, compileUnit, NULL, "length", 0);
         assert(len);
-        LLGlobalVariable* ptr = dwarfMemberType(loc, t->nextOf()->pointerTo(), compileUnit, "ptr", global.params.is64bit?8:4);
+        LLGlobalVariable* ptr = dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, NULL, "ptr", global.params.is64bit?8:4);
         assert(ptr);
 
         const LLArrayType* at = LLArrayType::get(DBG_TYPE, 2);
@@ -366,14 +385,52 @@
         elems.push_back(DBG_CAST(len));
         elems.push_back(DBG_CAST(ptr));
 
-//         elems[0]->dump();
-//         elems[1]->dump();
-//         at->dump();
+        LLConstant* ca = LLConstantArray::get(at, elems);
+        members = new LLGlobalVariable(ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array", gIR->module);
+        members->setSection("llvm.metadata");
+
+        name = DtoConstStringPtr(t->toChars(), "llvm.metadata");
+    }
+
+    // struct
+    else if (t->ty == Tstruct)
+    {
+        TypeStruct* ts = (TypeStruct*)t;
+        StructDeclaration* sd = ts->sym;
+        assert(sd);
+
+        IrStruct* ir = sd->ir.irStruct;
+        assert(ir);
+        if (ir->dwarfComposite)
+            return ir->dwarfComposite;
 
+        // set to handle recursive types properly
+        gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype");
+        ir->dwarfComposite = gv;
+
+        tag = DW_TAG_structure_type;
+
+        name = DtoConstStringPtr(sd->toChars(), "llvm.metadata");
+        linnum = sd->loc.linnum;
+        definedCU = DtoDwarfCompileUnit(sd->getModule());
+
+        std::vector<LLConstant*> elems;
+        for (IrStruct::OffsetMap::iterator i=ir->offsets.begin(); i!=ir->offsets.end(); ++i)
+        {
+            unsigned offset = i->first;
+            IrStruct::Offset& o = i->second;
+
+            LLGlobalVariable* ptr = dwarfMemberType(o.var->loc.linnum, o.var->type, compileUnit, definedCU, o.var->toChars(), offset);
+            elems.push_back(DBG_CAST(ptr));
+        }
+
+        const LLArrayType* at = LLArrayType::get(DBG_TYPE, elems.size());
         LLConstant* ca = LLConstantArray::get(at, elems);
         members = new LLGlobalVariable(ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array", gIR->module);
         members->setSection("llvm.metadata");
     }
+
+    // unsupported composite type
     else
     {
         assert(0 && "unsupported compositetype for debug info");
@@ -391,10 +448,13 @@
     vals.push_back(name);
 
     // compile unit where defined
-    vals.push_back(DBG_NULL);
+    if (definedCU)
+        vals.push_back(DBG_CAST(definedCU));
+    else
+        vals.push_back(DBG_NULL);
 
     // line number where defined
-    vals.push_back(DtoConstInt(0));
+    vals.push_back(DtoConstInt(linnum));
 
     // size in bits
     vals.push_back(LLConstantInt::get(LLType::Int64Ty, getTypeBitSize(T), false));
@@ -417,7 +477,13 @@
     else
         vals.push_back(DBG_NULL);
 
-    return emitDwarfGlobal(getDwarfCompositeTypeType(), vals, "llvm.dbg.compositetype");
+    // set initializer
+    if (!gv)
+        gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype");
+    LLConstant* initia = LLConstantStruct::get(getDwarfCompositeTypeType(), vals);
+    gv->setInitializer(initia);
+
+    return gv;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -440,7 +506,7 @@
     vals.push_back(DBG_CAST(DtoDwarfCompileUnit(vd->getModule())));
     vals.push_back(DtoConstUint(vd->loc.linnum));
 
-    LLGlobalVariable* TY = dwarfTypeDescription(vd->loc, vd->type, compileUnit, NULL);
+    LLGlobalVariable* TY = dwarfTypeDescription(vd->type, compileUnit, NULL);
     vals.push_back(TY ? DBG_CAST(TY) : DBG_NULL);
     vals.push_back(DtoConstBool(vd->protection == PROTprivate));
     vals.push_back(DtoConstBool(vd->getModule() == gIR->dmodule));
@@ -450,6 +516,8 @@
     return emitDwarfGlobal(getDwarfGlobalVariableType(), vals, "llvm.dbg.global_variable");
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
 static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr)
 {
     assert(!vd->isDataseg() && "static variable");
@@ -489,7 +557,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
-static LLGlobalVariable* dwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu, const char* c_name)
+static LLGlobalVariable* dwarfTypeDescription(Type* type, LLGlobalVariable* cu, const char* c_name)
 {
     Type* t = type->toBasetype();
     if (t->ty == Tvoid)
@@ -497,12 +565,10 @@
     else if (t->isintegral() || t->isfloating())
         return dwarfBasicType(type, cu);
     else if (t->ty == Tpointer)
-        return dwarfDerivedType(loc, type, cu);
-    else if (t->ty == Tarray)
-        return dwarfCompositeType(loc, type, cu);
+        return dwarfDerivedType(type, cu);
+    else if (t->ty == Tarray || t->ty == Tstruct)
+        return dwarfCompositeType(type, cu);
 
-    if (global.params.warnings)
-        warning("%s: unsupported type for debug info: %s", loc.toChars(), type->toChars());
     return NULL;
 }
 
@@ -518,7 +584,7 @@
 
     // get type description
     Type* t = vd->type->toBasetype();
-    LLGlobalVariable* TD = dwarfTypeDescription(vd->loc, vd->type, thisCU, NULL);
+    LLGlobalVariable* TD = dwarfTypeDescription(vd->type, thisCU, NULL);
     if (TD == NULL)
         return; // unsupported
 
--- a/ir/irmodule.cpp	Wed Jun 11 21:03:55 2008 +0200
+++ b/ir/irmodule.cpp	Thu Jun 12 16:58:26 2008 +0200
@@ -1,3 +1,4 @@
+#include "gen/llvm.h"
 #include "ir/irmodule.h"
 
 IrModule::IrModule(Module* module)
--- a/ir/irmodule.h	Wed Jun 11 21:03:55 2008 +0200
+++ b/ir/irmodule.h	Thu Jun 12 16:58:26 2008 +0200
@@ -12,7 +12,7 @@
 
     Module* M;
 
-    llvm::GlobalVariable* dwarfCompileUnit;
+    LLGlobalVariable* dwarfCompileUnit;
 };
 
 #endif
--- a/ir/irstruct.cpp	Wed Jun 11 21:03:55 2008 +0200
+++ b/ir/irstruct.cpp	Thu Jun 12 16:58:26 2008 +0200
@@ -50,6 +50,8 @@
 
     classDeclared = false;
     classDefined = false;
+
+    dwarfComposite = NULL;
 }
 
 IrStruct::~IrStruct()
--- a/ir/irstruct.h	Wed Jun 11 21:03:55 2008 +0200
+++ b/ir/irstruct.h	Thu Jun 12 16:58:26 2008 +0200
@@ -12,24 +12,24 @@
     ClassDeclaration* decl;
 
 #if OPAQUE_VTBLS
-    const llvm::ArrayType* vtblTy;
-    llvm::ConstantArray* vtblInit;
+    const LLArrayType* vtblTy;
+    LLConstantArray* vtblInit;
 #else
-    const llvm::StructType* vtblTy;
-    llvm::ConstantStruct* vtblInit;
+    const LLStructType* vtblTy;
+    LLConstantStruct* vtblInit;
 #endif
-    llvm::GlobalVariable* vtbl;
+    LLGlobalVariable* vtbl;
 
-    const llvm::StructType* infoTy;
-    llvm::ConstantStruct* infoInit;
-    llvm::Constant* info;
+    const LLStructType* infoTy;
+    LLConstantStruct* infoInit;
+    LLConstant* info;
 
     int index;
 
 #if OPAQUE_VTBLS
-    IrInterface(BaseClass* b, const llvm::ArrayType* vt);
+    IrInterface(BaseClass* b, const LLArrayType* vt);
 #else
-    IrInterface(BaseClass* b, const llvm::StructType* vt);
+    IrInterface(BaseClass* b, const LLStructType* vt);
 #endif
     ~IrInterface();
 };
@@ -45,7 +45,7 @@
     {
         VarDeclaration* var;
         const LLType* type;
-        llvm::Constant* init;
+        LLConstant* init;
 
         Offset(VarDeclaration* v, const LLType* ty)
         : var(v), type(ty), init(NULL) {}
@@ -70,25 +70,27 @@
     InterfaceMap interfaceMap;
     InterfaceVector interfaceVec;
     const llvm::ArrayType* interfaceInfosTy;
-    llvm::GlobalVariable* interfaceInfos;
+    LLGlobalVariable* interfaceInfos;
 
     bool defined;
     bool constinited;
 
-    llvm::GlobalVariable* vtbl;
+    LLGlobalVariable* vtbl;
 #if OPAQUE_VTBLS
-    llvm::Constant* constVtbl;
+    LLConstant* constVtbl;
 #else
-    llvm::ConstantStruct* constVtbl;
+    LLConstantStruct* constVtbl;
 #endif
-    llvm::GlobalVariable* init;
-    llvm::Constant* constInit;
-    llvm::GlobalVariable* classInfo;
-    llvm::Constant* constClassInfo;
+    LLGlobalVariable* init;
+    LLConstant* constInit;
+    LLGlobalVariable* classInfo;
+    LLConstant* constClassInfo;
     bool hasUnions;
     DUnion* dunion;
     bool classDeclared;
     bool classDefined;
+
+    LLGlobalVariable* dwarfComposite;
 };
 
 #endif
--- a/llvmdc.kdevelop.filelist	Wed Jun 11 21:03:55 2008 +0200
+++ b/llvmdc.kdevelop.filelist	Thu Jun 12 16:58:26 2008 +0200
@@ -771,6 +771,7 @@
 tangotests/debug5.d
 tangotests/debug6.d
 tangotests/debug7.d
+tangotests/debug8.d
 tangotests/e.d
 tangotests/f.d
 tangotests/files1.d