const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
DwarfExpr.addFragmentOffset(Fragment.Expr);
- DwarfExpr.addMachineRegIndirect(*Asm->MF->getSubtarget().getRegisterInfo(),
- FrameReg, Offset);
- DwarfExpr.addExpression(Fragment.Expr);
+ SmallVector<uint64_t, 8> Ops;
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(Offset);
+ Ops.push_back(dwarf::DW_OP_deref);
+ Ops.append(Fragment.Expr->elements_begin(), Fragment.Expr->elements_end());
+ DIExpressionCursor Expr(Ops);
+ DwarfExpr.addMachineRegExpression(
+ *Asm->MF->getSubtarget().getRegisterInfo(), Expr, FrameReg);
+ DwarfExpr.addExpression(std::move(Expr));
}
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
const MachineLocation &Location) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression Expr(*Asm, *this, *Loc);
-
- bool validReg;
- if (Location.isReg())
- validReg = Expr.addMachineReg(*Asm->MF->getSubtarget().getRegisterInfo(),
- Location.getReg());
- else
- validReg =
- Expr.addMachineRegIndirect(*Asm->MF->getSubtarget().getRegisterInfo(),
- Location.getReg(), Location.getOffset());
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
- if (!validReg)
+ SmallVector<uint64_t, 8> Ops;
+ if (Location.isIndirect()) {
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(Location.getOffset());
+ Ops.push_back(dwarf::DW_OP_deref);
+ }
+ DIExpressionCursor Cursor(Ops);
+ const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
+ if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
return;
+ DwarfExpr.addExpression(std::move(Cursor));
// Now attach the location information to the DIE.
- addBlock(Die, Attribute, Expr.finalize());
+ addBlock(Die, Attribute, DwarfExpr.finalize());
}
/// Start with the address based on the location provided, and generate the
const MachineLocation &Location) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
- const DIExpression *Expr = DV.getSingleExpression();
- DIExpressionCursor ExprCursor(Expr);
+ const DIExpression *DIExpr = DV.getSingleExpression();
+ DwarfExpr.addFragmentOffset(DIExpr);
+
+ SmallVector<uint64_t, 8> Ops;
+ if (Location.isIndirect()) {
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(Location.getOffset());
+ Ops.push_back(dwarf::DW_OP_deref);
+ }
+ Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
+ DIExpressionCursor Cursor(Ops);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
- auto Reg = Location.getReg();
- DwarfExpr.addFragmentOffset(Expr);
- bool ValidReg =
- Location.getOffset()
- ? DwarfExpr.addMachineRegIndirect(TRI, Reg, Location.getOffset())
- : DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Reg);
-
- if (!ValidReg)
+ if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
return;
-
- DwarfExpr.addExpression(std::move(ExprCursor));
+ DwarfExpr.addExpression(std::move(Cursor));
// Now attach the location information to the DIE.
- addBlock(Die, Attribute, Loc);
+ addBlock(Die, Attribute, DwarfExpr.finalize());
}
/// Add a Dwarf loclistptr attribute data and value.
ByteStreamer &Streamer,
const DebugLocEntry::Value &Value,
DwarfExpression &DwarfExpr) {
- DIExpressionCursor ExprCursor(Value.getExpression());
- DwarfExpr.addFragmentOffset(Value.getExpression());
+ auto *DIExpr = Value.getExpression();
+ DIExpressionCursor ExprCursor(DIExpr);
+ DwarfExpr.addFragmentOffset(DIExpr);
// Regular entry.
if (Value.isInt()) {
if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
else
DwarfExpr.addUnsignedConstant(Value.getInt());
} else if (Value.isLocation()) {
- MachineLocation Loc = Value.getLoc();
+ MachineLocation Location = Value.getLoc();
+
+ SmallVector<uint64_t, 8> Ops;
+ // FIXME: Should this condition be Location.isIndirect() instead?
+ if (Location.getOffset()) {
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(Location.getOffset());
+ Ops.push_back(dwarf::DW_OP_deref);
+ }
+ Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
+ DIExpressionCursor Cursor(Ops);
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (Loc.getOffset())
- DwarfExpr.addMachineRegIndirect(TRI, Loc.getReg(), Loc.getOffset());
- else
- DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Loc.getReg());
+ if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ return;
+ return DwarfExpr.addExpression(std::move(Cursor));
} else if (Value.isConstantFP()) {
APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
DwarfExpr.addUnsignedConstant(RawBytes);
/// Emit an (double-)indirect dwarf register operation.
void addRegIndirect(int DwarfReg, int Offset);
+ /// Emit an indirect dwarf register operation for the given machine register.
+ /// \return false if no DWARF register exists for MachineReg.
+ bool addMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg,
+ int Offset = 0);
+
+ /// Emit a partial DWARF register operation.
+ ///
+ /// \param MachineReg The register number.
+ /// \param MaxSize If the register must be composed from
+ /// sub-registers this is an upper bound
+ /// for how many bits the emitted DW_OP_piece
+ /// may cover.
+ ///
+ /// If size and offset is zero an operation for the entire register is
+ /// emitted: Some targets do not provide a DWARF register number for every
+ /// register. If this is the case, this function will attempt to emit a DWARF
+ /// register by emitting a fragment of a super-register or by piecing together
+ /// multiple subregisters that alias the register.
+ ///
+ /// \return false if no DWARF register exists for MachineReg.
+ bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
+ unsigned MaxSize = ~1U);
+
+
/// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
/// \param OffsetInBits This is an optional offset into the location that
/// is at the top of the DWARF stack.
/// This needs to be called last to commit any pending changes.
void finalize();
- /// Emit an indirect dwarf register operation for the given machine register.
- /// \return false if no DWARF register exists for MachineReg.
- bool addMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg,
- int Offset = 0);
-
- /// Emit a partial DWARF register operation.
- ///
- /// \param MachineReg The register number.
- /// \param MaxSize If the register must be composed from
- /// sub-registers this is an upper bound
- /// for how many bits the emitted DW_OP_piece
- /// may cover.
- ///
- /// If size and offset is zero an operation for the entire register is
- /// emitted: Some targets do not provide a DWARF register number for every
- /// register. If this is the case, this function will attempt to emit a DWARF
- /// register by emitting a fragment of a super-register or by piecing together
- /// multiple subregisters that alias the register.
- ///
- /// \return false if no DWARF register exists for MachineReg.
- bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
- unsigned MaxSize = ~1U);
-
/// Emit a signed constant.
void addSignedConstant(int64_t Value);
/// Emit an unsigned constant.
// Decode the original location, and use that as the start of the byref
// variable's location.
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- SmallVector<uint64_t, 6> DIExpr;
- DIEDwarfExpression Expr(*Asm, *this, *Loc);
-
- bool validReg;
- if (Location.isReg())
- validReg = Expr.addMachineReg(*Asm->MF->getSubtarget().getRegisterInfo(),
- Location.getReg());
- else
- validReg =
- Expr.addMachineRegIndirect(*Asm->MF->getSubtarget().getRegisterInfo(),
- Location.getReg(), Location.getOffset());
-
- if (!validReg)
- return;
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ SmallVector<uint64_t, 9> Ops;
+ if (Location.isIndirect()) {
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(Location.getOffset());
+ Ops.push_back(dwarf::DW_OP_deref);
+ }
// If we started with a pointer to the __Block_byref... struct, then
// the first thing we need to do is dereference the pointer (DW_OP_deref).
if (isPointer)
- DIExpr.push_back(dwarf::DW_OP_deref);
+ Ops.push_back(dwarf::DW_OP_deref);
// Next add the offset for the '__forwarding' field:
// DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
// adding the offset if it's 0.
if (forwardingFieldOffset > 0) {
- DIExpr.push_back(dwarf::DW_OP_plus);
- DIExpr.push_back(forwardingFieldOffset);
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(forwardingFieldOffset);
}
// Now dereference the __forwarding field to get to the real __Block_byref
// struct: DW_OP_deref.
- DIExpr.push_back(dwarf::DW_OP_deref);
+ Ops.push_back(dwarf::DW_OP_deref);
// Now that we've got the real __Block_byref... struct, add the offset
// for the variable's field to get to the location of the actual variable:
// DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
if (varFieldOffset > 0) {
- DIExpr.push_back(dwarf::DW_OP_plus);
- DIExpr.push_back(varFieldOffset);
+ Ops.push_back(dwarf::DW_OP_plus);
+ Ops.push_back(varFieldOffset);
}
- Expr.addExpression(makeArrayRef(DIExpr));
- Expr.finalize();
+
+ DIExpressionCursor Cursor(Ops);
+ const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
+ if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+ return;
+ DwarfExpr.addExpression(std::move(Cursor));
// Now attach the location information to the DIE.
- addBlock(Die, Attribute, Loc);
+ addBlock(Die, Attribute, DwarfExpr.finalize());
}
/// Return true if type encoding is unsigned.