mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 17:43:35 +03:00
Implement -gline-tables-only (PR #1861)
As per ldc-developers/ldc#1844 .
This commit is contained in:
parent
39a5aaecdb
commit
3b63effd3f
6 changed files with 157 additions and 23 deletions
|
@ -117,7 +117,8 @@ static cl::opt<bool, true> ignoreUnsupportedPragmas(
|
||||||
static cl::opt<ubyte, true> debugInfo(
|
static cl::opt<ubyte, true> debugInfo(
|
||||||
cl::desc("Generating debug information:"), cl::ZeroOrMore,
|
cl::desc("Generating debug information:"), cl::ZeroOrMore,
|
||||||
clEnumValues(clEnumValN(1, "g", "Generate debug information"),
|
clEnumValues(clEnumValN(1, "g", "Generate debug information"),
|
||||||
clEnumValN(2, "gc", "Same as -g, but pretend to be C")),
|
clEnumValN(2, "gc", "Same as -g, but pretend to be C"),
|
||||||
|
clEnumValN(3, "gline-tables-only", "Generate line-tables-only")),
|
||||||
cl::location(global.params.symdebug), cl::init(0));
|
cl::location(global.params.symdebug), cl::init(0));
|
||||||
|
|
||||||
static cl::opt<unsigned, true>
|
static cl::opt<unsigned, true>
|
||||||
|
|
|
@ -74,7 +74,16 @@ llvm::StringRef uniqueIdent(Type* t) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool ldc::DIBuilder::mustEmitDebugInfo() { return global.params.symdebug; }
|
|
||||||
|
bool ldc::DIBuilder::mustEmitFullDebugInfo() {
|
||||||
|
// only for -g and -gc
|
||||||
|
return global.params.symdebug == 1 || global.params.symdebug == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ldc::DIBuilder::mustEmitLocationsDebugInfo() {
|
||||||
|
// for -g -gc and -gline-tables-only
|
||||||
|
return global.params.symdebug > 0;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -613,6 +622,19 @@ ldc::DISubroutineType ldc::DIBuilder::CreateFunctionType(Type *type) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldc::DISubroutineType ldc::DIBuilder::CreateEmptyFunctionType() {
|
||||||
|
#if LDC_LLVM_VER == 305
|
||||||
|
auto paramsArray = DBuilder.getOrCreateArray(llvm::None);
|
||||||
|
#else
|
||||||
|
auto paramsArray = DBuilder.getOrCreateTypeArray(llvm::None);
|
||||||
|
#endif
|
||||||
|
#if LDC_LLVM_VER >= 308
|
||||||
|
return DBuilder.createSubroutineType(paramsArray);
|
||||||
|
#else
|
||||||
|
return DBuilder.createSubroutineType(CreateFile(), paramsArray);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
ldc::DIType ldc::DIBuilder::CreateDelegateType(Type *type) {
|
ldc::DIType ldc::DIBuilder::CreateDelegateType(Type *type) {
|
||||||
assert(type->toBasetype()->ty == Tdelegate);
|
assert(type->toBasetype()->ty == Tdelegate);
|
||||||
|
|
||||||
|
@ -699,8 +721,39 @@ ldc::DIType ldc::DIBuilder::CreateTypeDescription(Type *type, bool derefclass) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if LDC_LLVM_VER >= 309
|
||||||
|
using DebugEmissionKind = llvm::DICompileUnit::DebugEmissionKind;
|
||||||
|
#else
|
||||||
|
using DebugEmissionKind = llvm::DIBuilder::DebugEmissionKind;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DebugEmissionKind getDebugEmissionKind()
|
||||||
|
{
|
||||||
|
#if LDC_LLVM_VER >= 309
|
||||||
|
switch (global.params.symdebug)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return llvm::DICompileUnit::NoDebug;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
return llvm::DICompileUnit::FullDebug;
|
||||||
|
case 3:
|
||||||
|
return llvm::DICompileUnit::LineTablesOnly;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("unknown DebugEmissionKind");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
assert(global.params.symdebug != 0);
|
||||||
|
return global.params.symdebug == 3 ?
|
||||||
|
llvm::DIBuilder::LineTablesOnly :
|
||||||
|
llvm::DIBuilder::FullDebug;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitCompileUnit(Module *m) {
|
void ldc::DIBuilder::EmitCompileUnit(Module *m) {
|
||||||
if (!mustEmitDebugInfo()) {
|
if (!mustEmitLocationsDebugInfo()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,12 +784,20 @@ void ldc::DIBuilder::EmitCompileUnit(Module *m) {
|
||||||
"LDC (http://wiki.dlang.org/LDC)",
|
"LDC (http://wiki.dlang.org/LDC)",
|
||||||
isOptimizationEnabled(), // isOptimized
|
isOptimizationEnabled(), // isOptimized
|
||||||
llvm::StringRef(), // Flags TODO
|
llvm::StringRef(), // Flags TODO
|
||||||
1 // Runtime Version TODO
|
1, // Runtime Version TODO
|
||||||
|
llvm::StringRef(), // SplitName
|
||||||
|
getDebugEmissionKind() // DebugEmissionKind
|
||||||
|
#if LDC_LLVM_VER > 306
|
||||||
|
, 0 // DWOId
|
||||||
|
#endif
|
||||||
|
#if LDC_LLVM_VER < 309
|
||||||
|
, mustEmitFullDebugInfo() // EmitDebugInfo
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
||||||
if (!mustEmitDebugInfo()) {
|
if (!mustEmitLocationsDebugInfo()) {
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
#else
|
||||||
|
@ -754,8 +815,9 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
||||||
ldc::DIFile file = CreateFile(fd);
|
ldc::DIFile file = CreateFile(fd);
|
||||||
|
|
||||||
// Create subroutine type
|
// Create subroutine type
|
||||||
ldc::DISubroutineType DIFnType =
|
ldc::DISubroutineType DIFnType = mustEmitFullDebugInfo() ?
|
||||||
CreateFunctionType(static_cast<TypeFunction *>(fd->type));
|
CreateFunctionType(static_cast<TypeFunction *>(fd->type)) :
|
||||||
|
CreateEmptyFunctionType();
|
||||||
|
|
||||||
// FIXME: duplicates?
|
// FIXME: duplicates?
|
||||||
auto SP = DBuilder.createFunction(
|
auto SP = DBuilder.createFunction(
|
||||||
|
@ -784,7 +846,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
|
||||||
|
|
||||||
ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk,
|
ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk,
|
||||||
FuncDeclaration *fd) {
|
FuncDeclaration *fd) {
|
||||||
if (!mustEmitDebugInfo()) {
|
if (!mustEmitLocationsDebugInfo()) {
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
#else
|
||||||
|
@ -833,7 +895,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitThunk(llvm::Function *Thunk,
|
||||||
|
|
||||||
ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
|
ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
|
||||||
llvm::StringRef prettyname) {
|
llvm::StringRef prettyname) {
|
||||||
if (!mustEmitDebugInfo()) {
|
if (!mustEmitLocationsDebugInfo()) {
|
||||||
#if LDC_LLVM_VER >= 307
|
#if LDC_LLVM_VER >= 307
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#else
|
#else
|
||||||
|
@ -857,10 +919,9 @@ ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
|
||||||
auto paramsArray = DBuilder.getOrCreateArray(params);
|
auto paramsArray = DBuilder.getOrCreateArray(params);
|
||||||
#endif
|
#endif
|
||||||
#if LDC_LLVM_VER >= 308
|
#if LDC_LLVM_VER >= 308
|
||||||
ldc::DISubroutineType DIFnType = DBuilder.createSubroutineType(paramsArray);
|
auto DIFnType = DBuilder.createSubroutineType(paramsArray);
|
||||||
#else
|
#else
|
||||||
ldc::DISubroutineType DIFnType =
|
auto DIFnType = DBuilder.createSubroutineType(file, paramsArray);
|
||||||
DBuilder.createSubroutineType(file, paramsArray);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME: duplicates?
|
// FIXME: duplicates?
|
||||||
|
@ -888,7 +949,7 @@ ldc::DISubprogram ldc::DIBuilder::EmitModuleCTor(llvm::Function *Fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) {
|
void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitLocationsDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger::println("D to dwarf funcstart");
|
Logger::println("D to dwarf funcstart");
|
||||||
|
@ -899,7 +960,7 @@ void ldc::DIBuilder::EmitFuncStart(FuncDeclaration *fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) {
|
void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitLocationsDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger::println("D to dwarf funcend");
|
Logger::println("D to dwarf funcend");
|
||||||
|
@ -910,7 +971,7 @@ void ldc::DIBuilder::EmitFuncEnd(FuncDeclaration *fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitBlockStart(Loc &loc) {
|
void ldc::DIBuilder::EmitBlockStart(Loc &loc) {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitLocationsDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger::println("D to dwarf block start");
|
Logger::println("D to dwarf block start");
|
||||||
|
@ -931,7 +992,7 @@ void ldc::DIBuilder::EmitBlockStart(Loc &loc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitBlockEnd() {
|
void ldc::DIBuilder::EmitBlockEnd() {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitLocationsDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger::println("D to dwarf block end");
|
Logger::println("D to dwarf block end");
|
||||||
|
@ -943,7 +1004,7 @@ void ldc::DIBuilder::EmitBlockEnd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitStopPoint(Loc &loc) {
|
void ldc::DIBuilder::EmitStopPoint(Loc &loc) {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitLocationsDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If we already have a location set and the current loc is invalid
|
// If we already have a location set and the current loc is invalid
|
||||||
|
@ -981,7 +1042,7 @@ void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ldc::DILocalVariable debugVariable = sub->second;
|
ldc::DILocalVariable debugVariable = sub->second;
|
||||||
if (!mustEmitDebugInfo() || !debugVariable)
|
if (!mustEmitFullDebugInfo() || !debugVariable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
llvm::Instruction *instr =
|
llvm::Instruction *instr =
|
||||||
|
@ -1005,7 +1066,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
||||||
llvm::ArrayRef<llvm::Value *> addr
|
llvm::ArrayRef<llvm::Value *> addr
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitFullDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger::println("D to dwarf local variable");
|
Logger::println("D to dwarf local variable");
|
||||||
|
@ -1139,7 +1200,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
|
void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
|
||||||
VarDeclaration *vd) {
|
VarDeclaration *vd) {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitFullDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Logger::println("D to dwarf global_variable");
|
Logger::println("D to dwarf global_variable");
|
||||||
|
@ -1174,7 +1235,7 @@ void ldc::DIBuilder::EmitGlobalVariable(llvm::GlobalVariable *llVar,
|
||||||
}
|
}
|
||||||
|
|
||||||
void ldc::DIBuilder::Finalize() {
|
void ldc::DIBuilder::Finalize() {
|
||||||
if (!mustEmitDebugInfo())
|
if (!mustEmitLocationsDebugInfo())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DBuilder.finalize();
|
DBuilder.finalize();
|
||||||
|
|
|
@ -196,10 +196,12 @@ private:
|
||||||
DIType CreateSArrayType(Type *type);
|
DIType CreateSArrayType(Type *type);
|
||||||
DIType CreateAArrayType(Type *type);
|
DIType CreateAArrayType(Type *type);
|
||||||
DISubroutineType CreateFunctionType(Type *type);
|
DISubroutineType CreateFunctionType(Type *type);
|
||||||
|
DISubroutineType CreateEmptyFunctionType();
|
||||||
DIType CreateDelegateType(Type *type);
|
DIType CreateDelegateType(Type *type);
|
||||||
DIType CreateTypeDescription(Type *type, bool derefclass = false);
|
DIType CreateTypeDescription(Type *type, bool derefclass = false);
|
||||||
|
|
||||||
bool mustEmitDebugInfo();
|
bool mustEmitFullDebugInfo();
|
||||||
|
bool mustEmitLocationsDebugInfo();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
16
tests/debuginfo/gline_tables_only.d
Normal file
16
tests/debuginfo/gline_tables_only.d
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// RUN: %ldc -gline-tables-only --output-ll -of%t.ll %s && FileCheck %s < %t.ll
|
||||||
|
// checks that ldc with -gline-tables-only do not emit debug info
|
||||||
|
|
||||||
|
// REQUIRES: atleast_llvm309
|
||||||
|
// reason: different llvm version emits far different metadata in IR code
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
immutable int fact=6;
|
||||||
|
int res=1;
|
||||||
|
for(int i=1; i<=fact; i++) res *= i;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-NOT: DW_TAG
|
||||||
|
// CHECK-NOT: DW_AT
|
22
tests/debuginfo/gline_tables_only2.d
Normal file
22
tests/debuginfo/gline_tables_only2.d
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// RUN: %ldc -gline-tables-only --output-ll -of%t.ll %s && FileCheck %s < %t.ll
|
||||||
|
// Checks that ldc with "-gline-tables-only" emits metadata for
|
||||||
|
// compile unit, subprogram and file.
|
||||||
|
// Also checks that no type attributes are emitted
|
||||||
|
|
||||||
|
// REQUIRES: atleast_llvm309
|
||||||
|
// reason: different llvm version emits far different metadata in IR code
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// CHECK: ret i32 0, !dbg
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK: !llvm.dbg.cu = !{
|
||||||
|
// CHECK: !DICompileUnit(
|
||||||
|
// CHECK: !DIFile(
|
||||||
|
// CHECK: !DISubprogram(
|
||||||
|
// CHECK-NOT: !DIBasicType(
|
||||||
|
// CHECK: !DILocation
|
||||||
|
// CHECK-NOT: !DILocalVariable(
|
||||||
|
// CHECK-NOT: !DIDerivedType(
|
||||||
|
// CHECK-NOT: !DIBasicType(
|
32
tests/debuginfo/gline_tables_only3.d
Normal file
32
tests/debuginfo/gline_tables_only3.d
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// RUN: %ldc -gline-tables-only --output-ll -c %s -of%t.ll && FileCheck %s < %t.ll
|
||||||
|
// Checks that ldc with "-gline-tables-only" doesn't emit debug info
|
||||||
|
// for variables and types.
|
||||||
|
|
||||||
|
// CHECK-NOT: DW_TAG_variable
|
||||||
|
int global = 42;
|
||||||
|
|
||||||
|
// CHECK-NOT: DW_TAG_typedef
|
||||||
|
// CHECK-NOT: DW_TAG_const_type
|
||||||
|
// CHECK-NOT: DW_TAG_pointer_type
|
||||||
|
// CHECK-NOT: DW_TAG_array_type
|
||||||
|
alias constCharPtrArray = const(char)*[10];
|
||||||
|
|
||||||
|
// CHECK-NOT: DW_TAG_structure_type
|
||||||
|
struct S {
|
||||||
|
// CHECK-NOT: DW_TAG_member
|
||||||
|
char a;
|
||||||
|
double b;
|
||||||
|
constCharPtrArray c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-NOT: DW_TAG_enumerator
|
||||||
|
// CHECK-NOT: DW_TAG_enumeration_type
|
||||||
|
enum E { ZERO = 0, ONE = 1 }
|
||||||
|
|
||||||
|
// CHECK-NOT: DILocalVariable
|
||||||
|
int sum(int p, int q) {
|
||||||
|
int r = p + q;
|
||||||
|
S s;
|
||||||
|
E e;
|
||||||
|
return r;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue