Debug info: emit llvm::DIModule and llvm::DIImportedEntity for modules and imports

Matches GDC's DWARF output and enables access to global and imported symbols from GDB.
This commit is contained in:
Elie Morisse 2018-08-19 14:07:50 -03:00 committed by Martin Kinkelin
parent 5c24f60cf9
commit 841146644b
6 changed files with 73 additions and 1 deletions

View file

@ -11,6 +11,7 @@
#include "declaration.h"
#include "enum.h"
#include "id.h"
#include "import.h"
#include "init.h"
#include "nspace.h"
#include "rmem.h"
@ -50,6 +51,15 @@ public:
//////////////////////////////////////////////////////////////////////////
void visit(Import *im) override {
IF_LOG Logger::println("Import::codegen for %s", im->toPrettyChars());
LOG_SCOPE
irs->DBuilder.EmitImport(im);
}
//////////////////////////////////////////////////////////////////////////
void visit(Nspace *ns) override {
IF_LOG Logger::println("Nspace::codegen for %s", ns->toPrettyChars());
LOG_SCOPE

View file

@ -18,12 +18,14 @@
#include "gen/tollvm.h"
#include "gen/optimizer.h"
#include "ir/irfunction.h"
#include "ir/irmodule.h"
#include "ir/irtypeaggr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "enum.h"
#include "ldcbindings.h"
#include "import.h"
#include "module.h"
#include "mtype.h"
@ -97,6 +99,8 @@ ldc::DIBuilder::DIBuilder(IRState *const IR)
llvm::LLVMContext &ldc::DIBuilder::getContext() { return IR->context(); }
ldc::DIScope ldc::DIBuilder::GetCurrentScope() {
if (IR->funcGenStates.empty())
return getIrModule(IR->dmodule)->diModule;
IrFunction *fn = IR->func();
if (fn->diLexicalBlocks.empty()) {
assert(static_cast<llvm::MDNode *>(fn->diSubprogram) != 0);
@ -775,6 +779,45 @@ void ldc::DIBuilder::EmitCompileUnit(Module *m) {
);
}
ldc::DIModule ldc::DIBuilder::EmitModule(Module *m)
{
if (!mustEmitFullDebugInfo()) {
return nullptr;
}
IrModule *irm = getIrModule(m);
if (irm->diModule)
return irm->diModule;
irm->diModule = DBuilder.createModule(
CUNode,
m->toPrettyChars(true), // qualified module name
llvm::StringRef(), // (clang modules specific) ConfigurationMacros
llvm::StringRef(), // (clang modules specific) IncludePath
llvm::StringRef() // (clang modules specific) ISysRoot
);
return irm->diModule;
}
void ldc::DIBuilder::EmitImport(Import *im)
{
if (!mustEmitFullDebugInfo()) {
return;
}
auto diModule = EmitModule(im->mod);
DBuilder.createImportedModule(
GetCurrentScope(),
diModule, // imported module
#if LDC_LLVM_VER >= 500
CreateFile(im), // file
#endif
im->loc.linnum // line num
);
}
ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
if (!mustEmitLocationsDebugInfo()) {
return nullptr;

View file

@ -24,6 +24,7 @@ struct IRState;
class ClassDeclaration;
class Dsymbol;
class FuncDeclaration;
class Import;
class Module;
class Type;
class VarDeclaration;
@ -52,6 +53,7 @@ typedef llvm::DILexicalBlock *DILexicalBlock;
typedef llvm::DIScope *DIScope;
typedef llvm::DISubroutineType *DISubroutineType;
typedef llvm::DISubprogram *DISubprogram;
typedef llvm::DIModule *DIModule;
typedef llvm::DICompileUnit *DICompileUnit;
class DIBuilder {
@ -75,6 +77,14 @@ public:
/// \param m Module to emit as compile unit.
void EmitCompileUnit(Module *m);
/// \brief Emit the Dwarf module global for a Module m.
/// \param m Module to emit (either as definition or declaration).
DIModule EmitModule(Module *m);
/// \brief Emit the Dwarf imported entity and module global for an Import im.
/// \param im Import to emit.
void EmitImport(Import *im);
/// \brief Emit the Dwarf subprogram global for a function declaration fd.
/// \param fd Function declaration to emit as subprogram.
/// \returns the Dwarf subprogram global.

View file

@ -656,6 +656,8 @@ void codegenModule(IRState *irs, Module *m) {
assert(!gIR && "gIR not null, codegen already in progress?!");
gIR = irs;
irs->DBuilder.EmitModule(m);
initRuntime();
// Skip pseudo-modules for coverage analysis

View file

@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "import.h"
#include "init.h"
#include "mars.h"
#include "module.h"
@ -1590,7 +1591,10 @@ public:
//////////////////////////////////////////////////////////////////////////
void visit(ImportStatement *stmt) override {
// Empty.
for (auto s: *stmt->imports) {
assert(s->isImport());
irs->DBuilder.EmitImport(static_cast<Import*>(s));
}
}
//////////////////////////////////////////////////////////////////////////

View file

@ -22,6 +22,7 @@ class Module;
namespace llvm {
class GlobalVariable;
class Function;
class DIModule;
}
struct IrModule {
@ -44,6 +45,8 @@ struct IrModule {
FuncDeclList unitTests;
llvm::Function *coverageCtor = nullptr;
llvm::DIModule *diModule = nullptr;
private:
llvm::GlobalVariable *moduleInfoVar = nullptr;
};