forked from OSchip/llvm-project
[codeview] Check for a DIExpression offset for local variables
Fixes inalloca parameters, which previously all pointed to the same offset. Extend the test to use llvm-readobj so that we can test the offset in a readable way. llvm-svn: 302578
This commit is contained in:
parent
dfa7f613ed
commit
b5fced7324
|
@ -2276,6 +2276,10 @@ public:
|
|||
/// Append \p Ops with operations to apply the \p Offset.
|
||||
static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
|
||||
|
||||
/// If this is a constant offset, extract it. If there is no expression,
|
||||
/// return true with an offset of zero.
|
||||
bool extractIfOffset(int64_t &Offset) const;
|
||||
|
||||
/// Constants for DIExpression::prepend.
|
||||
enum { NoDeref = false, WithDeref = true, WithStackValue = true };
|
||||
|
||||
|
|
|
@ -888,13 +888,21 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
|
|||
if (!Scope)
|
||||
continue;
|
||||
|
||||
// If the variable has an attached offset expression, extract it.
|
||||
// FIXME: Try to handle DW_OP_deref as well.
|
||||
int64_t ExprOffset = 0;
|
||||
if (VI.Expr)
|
||||
if (!VI.Expr->extractIfOffset(ExprOffset))
|
||||
continue;
|
||||
|
||||
// Get the frame register used and the offset.
|
||||
unsigned FrameReg = 0;
|
||||
int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);
|
||||
uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);
|
||||
|
||||
// Calculate the label ranges.
|
||||
LocalVarDefRange DefRange = createDefRangeMem(CVReg, FrameOffset);
|
||||
LocalVarDefRange DefRange =
|
||||
createDefRangeMem(CVReg, FrameOffset + ExprOffset);
|
||||
for (const InsnRange &Range : Scope->getRanges()) {
|
||||
const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
|
||||
const MCSymbol *End = getLabelAfterInsn(Range.second);
|
||||
|
|
|
@ -672,6 +672,24 @@ void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops,
|
|||
}
|
||||
}
|
||||
|
||||
bool DIExpression::extractIfOffset(int64_t &Offset) const {
|
||||
if (getNumElements() == 0) {
|
||||
Offset = 0;
|
||||
return true;
|
||||
}
|
||||
if (getNumElements() != 2)
|
||||
return false;
|
||||
if (Elements[0] == dwarf::DW_OP_plus) {
|
||||
Offset = Elements[1];
|
||||
return true;
|
||||
}
|
||||
if (Elements[0] == dwarf::DW_OP_minus) {
|
||||
Offset = -Elements[1];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DIExpression *DIExpression::prepend(const DIExpression *Expr, bool Deref,
|
||||
int64_t Offset, bool StackValue) {
|
||||
SmallVector<uint64_t, 8> Ops;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
; RUN: llc -O0 < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DEBUG
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
; RUN: llc -filetype=obj -O0 < %s | llvm-readobj -codeview - | FileCheck %s --check-prefix=OBJ
|
||||
|
||||
; IR generated by the following source:
|
||||
; struct NonTrivial {
|
||||
|
@ -54,6 +55,46 @@
|
|||
; CHECK: .asciz "c"
|
||||
; CHECK: .cv_def_range [[start]] [[end]]
|
||||
|
||||
; OBJ-LABEL: ProcStart {
|
||||
; OBJ: Kind: S_GPROC32_ID (0x1147)
|
||||
; OBJ: DisplayName: f
|
||||
; OBJ: }
|
||||
; OBJ: Local {
|
||||
; OBJ: Type: NonTrivial (0x1007)
|
||||
; OBJ: Flags [ (0x1)
|
||||
; OBJ: IsParameter (0x1)
|
||||
; OBJ: ]
|
||||
; OBJ: VarName: a
|
||||
; OBJ: }
|
||||
; OBJ: DefRangeRegisterRel {
|
||||
; OBJ: BaseRegister: 21
|
||||
; OBJ: BasePointerOffset: 12
|
||||
; OBJ: }
|
||||
; OBJ: Local {
|
||||
; OBJ: Type: int (0x74)
|
||||
; OBJ: Flags [ (0x1)
|
||||
; OBJ: IsParameter (0x1)
|
||||
; OBJ: ]
|
||||
; OBJ: VarName: b
|
||||
; OBJ: }
|
||||
; OBJ: DefRangeRegisterRel {
|
||||
; OBJ: BaseRegister: 21
|
||||
; OBJ: BasePointerOffset: 16
|
||||
; OBJ: }
|
||||
; FIXME: Retain unused.
|
||||
; OBJ: Local {
|
||||
; OBJ: Type: int (0x74)
|
||||
; OBJ: Flags [ (0x1)
|
||||
; OBJ: IsParameter (0x1)
|
||||
; OBJ: ]
|
||||
; OBJ: VarName: c
|
||||
; OBJ: }
|
||||
; OBJ: DefRangeRegisterRel {
|
||||
; OBJ: BaseRegister: 21
|
||||
; OBJ: BasePointerOffset: 24
|
||||
; OBJ: }
|
||||
; OBJ-LABEL: ProcEnd {
|
||||
; OBJ: }
|
||||
|
||||
|
||||
; ModuleID = 't.cpp'
|
||||
|
|
Loading…
Reference in New Issue