mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 20:06:03 +03:00
Adapt emission of debuginfos for parameters
Emit all parameters (except for captured ones) as DI parameters.
This commit is contained in:
parent
4e5c9616e3
commit
8be1e3e719
8 changed files with 36 additions and 40 deletions
|
@ -994,7 +994,7 @@ void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd) {
|
||||||
|
|
||||||
void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
||||||
Type *type, bool isThisPtr,
|
Type *type, bool isThisPtr,
|
||||||
bool rewrittenToLocal,
|
bool forceAsLocal,
|
||||||
#if LDC_LLVM_VER >= 306
|
#if LDC_LLVM_VER >= 306
|
||||||
llvm::ArrayRef<int64_t> addr
|
llvm::ArrayRef<int64_t> addr
|
||||||
#else
|
#else
|
||||||
|
@ -1013,17 +1013,18 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
||||||
return; // ensure that the debug variable is created only once
|
return; // ensure that the debug variable is created only once
|
||||||
|
|
||||||
// get type description
|
// get type description
|
||||||
ldc::DIType TD = CreateTypeDescription(type ? type : vd->type, true);
|
if (!type)
|
||||||
|
type = vd->type;
|
||||||
|
ldc::DIType TD = CreateTypeDescription(type, true);
|
||||||
if (static_cast<llvm::MDNode *>(TD) == nullptr)
|
if (static_cast<llvm::MDNode *>(TD) == nullptr)
|
||||||
return; // unsupported
|
return; // unsupported
|
||||||
|
|
||||||
if (vd->storage_class & (STCref | STCout)) {
|
if (vd->storage_class & (STCref | STCout)) {
|
||||||
#if LDC_LLVM_VER >= 308
|
#if LDC_LLVM_VER >= 308
|
||||||
auto vt = type ? type : vd->type;
|
auto T = DtoType(type);
|
||||||
auto T = DtoType(vt);
|
|
||||||
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD,
|
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD,
|
||||||
getTypeAllocSize(T) * 8, // size (bits)
|
getTypeAllocSize(T) * 8, // size (bits)
|
||||||
DtoAlignment(vt) * 8); // align (bits)
|
DtoAlignment(type) * 8); // align (bits)
|
||||||
#else
|
#else
|
||||||
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD);
|
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1034,7 +1035,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
||||||
|
|
||||||
#if LDC_LLVM_VER < 308
|
#if LDC_LLVM_VER < 308
|
||||||
unsigned tag;
|
unsigned tag;
|
||||||
if (!rewrittenToLocal && vd->isParameter()) {
|
if (!forceAsLocal && vd->isParameter()) {
|
||||||
tag = llvm::dwarf::DW_TAG_arg_variable;
|
tag = llvm::dwarf::DW_TAG_arg_variable;
|
||||||
} else {
|
} else {
|
||||||
tag = llvm::dwarf::DW_TAG_auto_variable;
|
tag = llvm::dwarf::DW_TAG_auto_variable;
|
||||||
|
@ -1077,7 +1078,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
|
||||||
Flags // flags
|
Flags // flags
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
if (!rewrittenToLocal && vd->isParameter()) {
|
if (!forceAsLocal && vd->isParameter()) {
|
||||||
FuncDeclaration *fd = vd->parent->isFuncDeclaration();
|
FuncDeclaration *fd = vd->parent->isFuncDeclaration();
|
||||||
assert(fd);
|
assert(fd);
|
||||||
size_t argNo = 0;
|
size_t argNo = 0;
|
||||||
|
|
|
@ -136,15 +136,15 @@ public:
|
||||||
|
|
||||||
/// \brief Emits all things necessary for making debug info for a local
|
/// \brief Emits all things necessary for making debug info for a local
|
||||||
/// variable vd.
|
/// variable vd.
|
||||||
/// \param ll LLVM Value of the variable.
|
/// \param ll LL lvalue of the variable.
|
||||||
/// \param vd Variable declaration to emit debug info for.
|
/// \param vd Variable declaration to emit debug info for.
|
||||||
/// \param type Type of parameter if different from vd->type
|
/// \param type Type of variable if different from vd->type
|
||||||
/// \param isThisPtr Parameter is hidden this pointer
|
/// \param isThisPtr Variable is hidden this pointer
|
||||||
/// \param bool rewrittenToLocal Parameter is copied to local stack frame/closure
|
/// \param forceAsLocal Emit as local even if the variable is a parameter
|
||||||
/// \param addr An array of complex address operations.
|
/// \param addr An array of complex address operations.
|
||||||
void
|
void
|
||||||
EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd, Type *type = nullptr,
|
EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd, Type *type = nullptr,
|
||||||
bool isThisPtr = false, bool rewrittenToLocal = false,
|
bool isThisPtr = false, bool forceAsLocal = false,
|
||||||
#if LDC_LLVM_VER >= 306
|
#if LDC_LLVM_VER >= 306
|
||||||
llvm::ArrayRef<int64_t> addr = llvm::ArrayRef<int64_t>()
|
llvm::ArrayRef<int64_t> addr = llvm::ArrayRef<int64_t>()
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -705,7 +705,6 @@ void defineParameters(IrFuncTy &irFty, VarDeclarations ¶meters) {
|
||||||
// E.g., for a lazy parameter of type T, vd->type is T (with lazy storage
|
// E.g., for a lazy parameter of type T, vd->type is T (with lazy storage
|
||||||
// class) while irparam->arg->type is the delegate type.
|
// class) while irparam->arg->type is the delegate type.
|
||||||
Type *const paramType = (irparam ? irparam->arg->type : vd->type);
|
Type *const paramType = (irparam ? irparam->arg->type : vd->type);
|
||||||
bool rewrittenToLocal = false;
|
|
||||||
|
|
||||||
if (!irparam) {
|
if (!irparam) {
|
||||||
// This is a parameter that is not passed on the LLVM level.
|
// This is a parameter that is not passed on the LLVM level.
|
||||||
|
@ -722,10 +721,8 @@ void defineParameters(IrFuncTy &irFty, VarDeclarations ¶meters) {
|
||||||
assert(irparam->value->getType() == DtoPtrToType(paramType));
|
assert(irparam->value->getType() == DtoPtrToType(paramType));
|
||||||
} else {
|
} else {
|
||||||
// Let the ABI transform the parameter back to an lvalue.
|
// Let the ABI transform the parameter back to an lvalue.
|
||||||
auto Lvalue =
|
irparam->value =
|
||||||
irFty.getParamLVal(paramType, llArgIdx, irparam->value);
|
irFty.getParamLVal(paramType, llArgIdx, irparam->value);
|
||||||
rewrittenToLocal = Lvalue != irparam->value;
|
|
||||||
irparam->value = Lvalue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
irparam->value->setName(vd->ident->toChars());
|
irparam->value->setName(vd->ident->toChars());
|
||||||
|
@ -734,7 +731,7 @@ void defineParameters(IrFuncTy &irFty, VarDeclarations ¶meters) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.params.symdebug)
|
if (global.params.symdebug)
|
||||||
gIR->DBuilder.EmitLocalVariable(irparam->value, vd, paramType, false, rewrittenToLocal);
|
gIR->DBuilder.EmitLocalVariable(irparam->value, vd, paramType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,8 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwarfValue && global.params.symdebug) {
|
if (dwarfValue && global.params.symdebug) {
|
||||||
gIR->DBuilder.EmitLocalVariable(dwarfValue, vd, nullptr, false, /*fromNested=*/ true, dwarfAddr);
|
gIR->DBuilder.EmitLocalVariable(dwarfValue, vd, nullptr, false, true,
|
||||||
|
dwarfAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeVarDValue(astype, vd, val);
|
return makeVarDValue(astype, vd, val);
|
||||||
|
|
|
@ -28,16 +28,6 @@ int byValue(ubyte ub, ushort us, uint ui, ulong ul,
|
||||||
// CHECK: !args_cdb.byValue
|
// CHECK: !args_cdb.byValue
|
||||||
// CDB: dv /t
|
// CDB: dv /t
|
||||||
|
|
||||||
// arguments not converted to locals come first:
|
|
||||||
// x64: cdouble * c
|
|
||||||
// x64: int delegate() * dg
|
|
||||||
// "Internal implementation error for fa" with cdb on x64, ok in VS
|
|
||||||
// x64: Interface * ifc
|
|
||||||
|
|
||||||
// x86: unsigned char [16] fa
|
|
||||||
// x86: Interface ifc
|
|
||||||
|
|
||||||
// locals:
|
|
||||||
// CHECK: unsigned char ub = 0x01
|
// CHECK: unsigned char ub = 0x01
|
||||||
// CHECK: unsigned short us = 2
|
// CHECK: unsigned short us = 2
|
||||||
// CHECK: unsigned int ui = 3
|
// CHECK: unsigned int ui = 3
|
||||||
|
@ -45,15 +35,22 @@ int byValue(ubyte ub, ushort us, uint ui, ulong ul,
|
||||||
// CHECK: float f = 5
|
// CHECK: float f = 5
|
||||||
// CHECK: double d = 6
|
// CHECK: double d = 6
|
||||||
// CHECK: double r = 7
|
// CHECK: double r = 7
|
||||||
|
// x64: cdouble * c =
|
||||||
// x86: cdouble c =
|
// x86: cdouble c =
|
||||||
|
// x64: int delegate() * dg =
|
||||||
// x86: int delegate() dg =
|
// x86: int delegate() dg =
|
||||||
// CHECK: <function> * fun = {{0x[0-9a-f`]*}}
|
// CHECK: <function> * fun = {{0x[0-9a-f`]*}}
|
||||||
// CHECK: struct int[] slice =
|
// x64: struct int[] * slice =
|
||||||
|
// x86: struct int[] slice =
|
||||||
// CHECK: unsigned char * aa = {{0x[0-9a-f`]*}}
|
// CHECK: unsigned char * aa = {{0x[0-9a-f`]*}}
|
||||||
|
// "Internal implementation error for fa" with cdb on x64, ok in VS
|
||||||
|
// x86: unsigned char [16] fa
|
||||||
// CHECK: float [4] f4 = float [4]
|
// CHECK: float [4] f4 = float [4]
|
||||||
// CHECK: double [4] d4 = double [4]
|
// CHECK: double [4] d4 = double [4]
|
||||||
|
// x64: Interface * ifc
|
||||||
|
// x86: Interface ifc
|
||||||
// CHECK: struct TypeInfo_Class * ti = {{0x[0-9a-f`]*}}
|
// CHECK: struct TypeInfo_Class * ti = {{0x[0-9a-f`]*}}
|
||||||
// noCHECK: <CLR type> np = <unknown base type 80000013>
|
// CHECK: void * np = {{0x[0`]*}}
|
||||||
|
|
||||||
// check arguments with indirections
|
// check arguments with indirections
|
||||||
// CDB: ?? c
|
// CDB: ?? c
|
||||||
|
@ -68,7 +65,7 @@ int byValue(ubyte ub, ushort us, uint ui, ulong ul,
|
||||||
// CHECK-SAME: args_cdb.main.__lambda
|
// CHECK-SAME: args_cdb.main.__lambda
|
||||||
|
|
||||||
// CDB: ?? fa[1]
|
// CDB: ?? fa[1]
|
||||||
// "Internal implementation error for fa" on x64
|
// "Internal implementation error for fa" with cdb on x64, ok in VS
|
||||||
// no-x86: unsigned char 0x0e (displays 0xf6)
|
// no-x86: unsigned char 0x0e (displays 0xf6)
|
||||||
|
|
||||||
// CDB: ?? ifc
|
// CDB: ?? ifc
|
||||||
|
@ -90,7 +87,7 @@ int byPtr(ubyte* ub, ushort* us, uint* ui, ulong* ul,
|
||||||
float4* f4, double4* d4,
|
float4* f4, double4* d4,
|
||||||
Interface* ifc, TypeInfo_Class* ti, typeof(null)* np)
|
Interface* ifc, TypeInfo_Class* ti, typeof(null)* np)
|
||||||
{
|
{
|
||||||
// CDB: bp `args_cdb.d:94`
|
// CDB: bp `args_cdb.d:91`
|
||||||
// CDB: g
|
// CDB: g
|
||||||
return 3;
|
return 3;
|
||||||
// CHECK: !args_cdb.byPtr
|
// CHECK: !args_cdb.byPtr
|
||||||
|
@ -141,7 +138,7 @@ int byPtr(ubyte* ub, ushort* us, uint* ui, ulong* ul,
|
||||||
// CHECK-NEXT: m_init : byte[]
|
// CHECK-NEXT: m_init : byte[]
|
||||||
// shows bad member values
|
// shows bad member values
|
||||||
// CDB: ?? *np
|
// CDB: ?? *np
|
||||||
// noCHECK: <CLR type> np = <unknown base type 80000013>
|
// CHECK: void * {{0x[0`]*}}
|
||||||
}
|
}
|
||||||
|
|
||||||
int byRef(ref ubyte ub, ref ushort us, ref uint ui, ref ulong ul,
|
int byRef(ref ubyte ub, ref ushort us, ref uint ui, ref ulong ul,
|
||||||
|
@ -151,7 +148,7 @@ int byRef(ref ubyte ub, ref ushort us, ref uint ui, ref ulong ul,
|
||||||
ref float4 f4, ref double4 d4,
|
ref float4 f4, ref double4 d4,
|
||||||
ref Interface ifc, ref TypeInfo_Class ti, ref typeof(null) np)
|
ref Interface ifc, ref TypeInfo_Class ti, ref typeof(null) np)
|
||||||
{
|
{
|
||||||
// CDB: bp `args_cdb.d:206`
|
// CDB: bp `args_cdb.d:203`
|
||||||
// CDB: g
|
// CDB: g
|
||||||
// CHECK: !args_cdb.byRef
|
// CHECK: !args_cdb.byRef
|
||||||
|
|
||||||
|
@ -201,7 +198,7 @@ int byRef(ref ubyte ub, ref ushort us, ref uint ui, ref ulong ul,
|
||||||
// CHECK: struct TypeInfo_Class * {{0x[0-9a-f`]*}}
|
// CHECK: struct TypeInfo_Class * {{0x[0-9a-f`]*}}
|
||||||
// CHECK-NEXT: m_init : byte[]
|
// CHECK-NEXT: m_init : byte[]
|
||||||
// CDB: ?? *np
|
// CDB: ?? *np
|
||||||
// noCHECK: <CLR type> <unknown base type 80000013>
|
// CHECK: void * {{0x[0`]*}}
|
||||||
|
|
||||||
// needs access to references to actually generate debug info
|
// needs access to references to actually generate debug info
|
||||||
ub++;
|
ub++;
|
||||||
|
@ -254,4 +251,3 @@ int main()
|
||||||
}
|
}
|
||||||
// CDB: q
|
// CDB: q
|
||||||
// CHECK: quit
|
// CHECK: quit
|
||||||
|
|
||||||
|
|
|
@ -18,5 +18,5 @@ void encloser(int arg0, int arg1)
|
||||||
|
|
||||||
// CHECK: @_D{{.*}}8encloserFiiZv{{.*}}DW_TAG_subprogram
|
// CHECK: @_D{{.*}}8encloserFiiZv{{.*}}DW_TAG_subprogram
|
||||||
// CHECK: @_D{{.*}}8encloserFiiZ6nestedMFiZv{{.*}}DW_TAG_subprogram
|
// CHECK: @_D{{.*}}8encloserFiiZ6nestedMFiZv{{.*}}DW_TAG_subprogram
|
||||||
// CHECK: nes_i{{.*}}DW_TAG_auto_variable
|
// CHECK: nes_i{{.*}}DW_TAG_arg_variable
|
||||||
// CHECK: arg1{{.*}}DW_TAG_auto_variable
|
// CHECK: arg1{{.*}}DW_TAG_auto_variable
|
||||||
|
|
|
@ -19,5 +19,5 @@ void encloser(int arg0, int arg1)
|
||||||
// CHECK: !DISubprogram(name:{{.*}}"{{.*}}.encloser"
|
// CHECK: !DISubprogram(name:{{.*}}"{{.*}}.encloser"
|
||||||
// CHECK-SAME: function: void {{.*}} @_D{{.*}}8encloserFiiZv
|
// CHECK-SAME: function: void {{.*}} @_D{{.*}}8encloserFiiZv
|
||||||
// CHECK-LABEL: !DISubprogram(name:{{.*}}"{{.*}}.encloser.nested"
|
// CHECK-LABEL: !DISubprogram(name:{{.*}}"{{.*}}.encloser.nested"
|
||||||
// CHECK: !DILocalVariable{{.*}}DW_TAG_auto_variable{{.*}}nes_i
|
// CHECK: !DILocalVariable{{.*}}DW_TAG_arg_variable{{.*}}nes_i
|
||||||
// CHECK: !DILocalVariable{{.*}}DW_TAG_auto_variable{{.*}}arg1
|
// CHECK: !DILocalVariable{{.*}}DW_TAG_auto_variable{{.*}}arg1
|
||||||
|
|
|
@ -43,7 +43,8 @@ int main(string[] args)
|
||||||
// CHECK: +[[OFF]] ptr {{ *}}: [[PTR]]
|
// CHECK: +[[OFF]] ptr {{ *}}: [[PTR]]
|
||||||
|
|
||||||
// CDB: dv /t
|
// CDB: dv /t
|
||||||
// CHECK: string[] args
|
// x64: string[] * args
|
||||||
|
// x86: string[] args
|
||||||
// CHECK: string[] nargs
|
// CHECK: string[] nargs
|
||||||
// CHECK: string ns
|
// CHECK: string ns
|
||||||
// CHECK: string ws
|
// CHECK: string ws
|
||||||
|
@ -52,7 +53,7 @@ int main(string[] args)
|
||||||
// CDB: ?? ns
|
// CDB: ?? ns
|
||||||
// CHECK: +0x000 length {{ *}}: 1
|
// CHECK: +0x000 length {{ *}}: 1
|
||||||
// CHECK: +[[OFF]] ptr {{ *}}: 0x{{[0-9a-f`]* *}} "a"
|
// CHECK: +[[OFF]] ptr {{ *}}: 0x{{[0-9a-f`]* *}} "a"
|
||||||
// CDB: ?? args.ptr[0]
|
// CDB: ?? nargs.ptr[0]
|
||||||
// CHECK: +0x000 length
|
// CHECK: +0x000 length
|
||||||
// CHECK: +[[OFF]] ptr {{ *}}: 0x{{[0-9a-f`]* *".*exe.*"}}
|
// CHECK: +[[OFF]] ptr {{ *}}: 0x{{[0-9a-f`]* *".*exe.*"}}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue