mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 17:11:44 +03:00
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:
parent
5c24f60cf9
commit
841146644b
6 changed files with 73 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue