Refactor DebugLocDWARFExpression so it doesn't require access to the

TargetRegisterInfo. DebugLocEntry now holds a buffer with the raw bytes
of the pre-calculated DWARF expression.

Ought to be NFC, but it does slightly alter the output format of the
textual assembly.

This reapplies 230930 without the assertion in DebugLocEntry::finalize()
because not all Machine registers can be lowered into DWARF register
numbers and floating point constants cannot be expressed.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231023 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adrian Prantl 2015-03-02 22:02:33 +00:00
parent fd78a7dd5c
commit 994176ad7c
11 changed files with 180 additions and 165 deletions

View File

@ -434,29 +434,6 @@ public:
/// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
virtual unsigned getISAEncoding(const Function *) { return 0; }
/// Emit a dwarf register operation for describing
/// - a small value occupying only part of a register or
/// - a register representing only part of a value.
void EmitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits,
unsigned OffsetInBits = 0) const;
/// \brief Emit a partial DWARF register operation.
/// \param MLoc the register
/// \param PieceSize size and
/// \param PieceOffset offset of the piece in bits, if this is one
/// piece of an aggregate value.
///
/// 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
/// piece of a super-register or by piecing together multiple
/// subregisters that alias the register.
void EmitDwarfRegOpPiece(ByteStreamer &BS, const MachineLocation &MLoc,
unsigned PieceSize = 0,
unsigned PieceOffset = 0) const;
/// EmitDwarfRegOp - Emit a dwarf register operation.
virtual void EmitDwarfRegOp(ByteStreamer &BS,
const MachineLocation &MLoc) const;

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ByteStreamer.h"
#include "DwarfDebug.h"
#include "DwarfExpression.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
@ -27,29 +28,11 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
void DebugLocDwarfExpression::EmitOp(uint8_t Op, const char *Comment) {
BS.EmitInt8(
Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op)
: dwarf::OperationEncodingString(Op));
}
void DebugLocDwarfExpression::EmitSigned(int Value) {
BS.EmitSLEB128(Value, Twine(Value));
}
void DebugLocDwarfExpression::EmitUnsigned(unsigned Value) {
BS.EmitULEB128(Value, Twine(Value));
}
bool DebugLocDwarfExpression::isFrameRegister(unsigned MachineReg) {
// This information is not available while emitting .debug_loc entries.
return false;
}
//===----------------------------------------------------------------------===//
// Dwarf Emission Helper Routines
//===----------------------------------------------------------------------===//
@ -205,30 +188,11 @@ void AsmPrinter::EmitSectionOffset(const MCSymbol *Label,
EmitLabelDifference(Label, SectionLabel, 4);
}
// Some targets do not provide a DWARF register number for every
// register. This function attempts to emit a DWARF register by
// emitting a piece of a super-register or by piecing together
// multiple subregisters that alias the register.
void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer,
const MachineLocation &MLoc,
unsigned PieceSizeInBits,
unsigned PieceOffsetInBits) const {
assert(MLoc.isReg() && "MLoc must be a register");
DebugLocDwarfExpression Expr(*this, Streamer);
Expr.AddMachineRegPiece(MLoc.getReg(), PieceSizeInBits, PieceOffsetInBits);
}
void AsmPrinter::EmitDwarfOpPiece(ByteStreamer &Streamer,
unsigned PieceSizeInBits,
unsigned PieceOffsetInBits) const {
DebugLocDwarfExpression Expr(*this, Streamer);
Expr.AddOpPiece(PieceSizeInBits, PieceOffsetInBits);
}
/// EmitDwarfRegOp - Emit dwarf register operation.
void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
const MachineLocation &MLoc) const {
DebugLocDwarfExpression Expr(*this, Streamer);
DebugLocDwarfExpression Expr(*TM.getSubtargetImpl()->getRegisterInfo(),
getDwarfDebug()->getDwarfVersion(), Streamer);
const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo();
int Reg = MRI->getDwarfRegNum(MLoc.getReg(), false);
if (Reg < 0) {

View File

@ -19,6 +19,8 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/LEB128.h"
#include <string>
namespace llvm {
class ByteStreamer {
@ -66,6 +68,33 @@ class HashingByteStreamer : public ByteStreamer {
Hash.addULEB128(DWord);
}
};
class BufferByteStreamer : public ByteStreamer {
private:
SmallVectorImpl<char> &Buffer;
// FIXME: This is actually only needed for textual asm output.
SmallVectorImpl<std::string> &Comments;
public:
BufferByteStreamer(SmallVectorImpl<char> &Buffer,
SmallVectorImpl<std::string> &Comments)
: Buffer(Buffer), Comments(Comments) {}
void EmitInt8(uint8_t Byte, const Twine &Comment) override {
Buffer.push_back(Byte);
Comments.push_back(Comment.str());
}
void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
raw_svector_ostream OSE(Buffer);
encodeSLEB128(DWord, OSE);
Comments.push_back(Comment.str());
}
void EmitULEB128(uint64_t DWord, const Twine &Comment) override {
raw_svector_ostream OSE(Buffer);
encodeULEB128(DWord, OSE);
Comments.push_back(Comment.str());
}
};
}
#endif

View File

@ -9,22 +9,24 @@
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
#include "llvm/ADT/SmallString.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MachineLocation.h"
namespace llvm {
class AsmPrinter;
class MDNode;
/// \brief This struct describes location entries emitted in the .debug_loc
/// section.
class DebugLocEntry {
// Begin and end symbols for the address range that this location is valid.
/// Begin and end symbols for the address range that this location is valid.
const MCSymbol *Begin;
const MCSymbol *End;
public:
/// A single location or constant.
/// \brief A single location or constant.
struct Value {
Value(const MDNode *Var, const MDNode *Expr, int64_t i)
: Variable(Var), Expression(Expr), EntryKind(E_Integer) {
@ -44,17 +46,17 @@ public:
assert(DIExpression(Expr).Verify());
}
// The variable to which this location entry corresponds.
/// The variable to which this location entry corresponds.
const MDNode *Variable;
// Any complex address location expression for this Value.
/// Any complex address location expression for this Value.
const MDNode *Expression;
// Type of entry that this represents.
/// Type of entry that this represents.
enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
enum EntryType EntryKind;
// Either a constant,
/// Either a constant,
union {
int64_t Int;
const ConstantFP *CFP;
@ -84,6 +86,8 @@ private:
/// A nonempty list of locations/constants belonging to this entry,
/// sorted by offset.
SmallVector<Value, 1> Values;
SmallString<8> DWARFBytes;
SmallVector<std::string, 1> Comments;
public:
DebugLocEntry(const MCSymbol *B, const MCSymbol *E, Value Val)
@ -92,9 +96,9 @@ public:
}
/// \brief If this and Next are describing different pieces of the same
// variable, merge them by appending Next's values to the current
// list of values.
// Return true if the merge was successful.
/// variable, merge them by appending Next's values to the current
/// list of values.
/// Return true if the merge was successful.
bool MergeValues(const DebugLocEntry &Next) {
if (Begin == Next.Begin) {
DIExpression Expr(Values[0].Expression);
@ -135,7 +139,7 @@ public:
}) && "value must be a piece");
}
// Sort the pieces by offset.
// \brief Sort the pieces by offset.
// Remove any duplicate entries by dropping all but the first.
void sortUniqueValues() {
std::sort(Values.begin(), Values.end());
@ -146,9 +150,18 @@ public:
}),
Values.end());
}
/// \brief Lower this entry into a DWARF expression.
void finalize(const AsmPrinter &AP,
const DITypeIdentifierMap &TypeIdentifierMap);
/// \brief Return the lowered DWARF expression.
StringRef getDWARFBytes() const { return DWARFBytes; }
/// \brief Return the assembler comments for the lowered DWARF expression.
const SmallVectorImpl<std::string> &getComments() const { return Comments; }
};
/// Compare two Values for equality.
/// \brief Compare two Values for equality.
inline bool operator==(const DebugLocEntry::Value &A,
const DebugLocEntry::Value &B) {
if (A.EntryKind != B.EntryKind)
@ -173,7 +186,7 @@ inline bool operator==(const DebugLocEntry::Value &A,
llvm_unreachable("unhandled EntryKind");
}
/// Compare two pieces based on their offset.
/// \brief Compare two pieces based on their offset.
inline bool operator<(const DebugLocEntry::Value &A,
const DebugLocEntry::Value &B) {
return A.getExpression().getBitPieceOffset() <

View File

@ -105,6 +105,25 @@ DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden,
static const char *const DWARFGroupName = "DWARF Emission";
static const char *const DbgTimerName = "DWARF Debug Writer";
void DebugLocDwarfExpression::EmitOp(uint8_t Op, const char *Comment) {
BS.EmitInt8(
Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op)
: dwarf::OperationEncodingString(Op));
}
void DebugLocDwarfExpression::EmitSigned(int Value) {
BS.EmitSLEB128(Value, Twine(Value));
}
void DebugLocDwarfExpression::EmitUnsigned(unsigned Value) {
BS.EmitULEB128(Value, Twine(Value));
}
bool DebugLocDwarfExpression::isFrameRegister(unsigned MachineReg) {
// This information is not available while emitting .debug_loc entries.
return false;
}
//===----------------------------------------------------------------------===//
/// resolve - Look in the DwarfDebug map for the MDNode that
@ -927,6 +946,9 @@ DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,
// Build the location list for this variable.
buildLocationList(LocList.List, Ranges);
// Finalize the entry by lowering it into a DWARF bytestream.
for (auto &Entry : LocList.List)
Entry.finalize(*Asm, TypeIdentifierMap);
}
// Collect info for variables that were optimized out.
@ -1600,62 +1622,27 @@ void DwarfDebug::emitDebugStr() {
Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection());
}
/// Emits an optimal (=sorted) sequence of DW_OP_pieces.
void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,
const DITypeIdentifierMap &Map,
ArrayRef<DebugLocEntry::Value> Values) {
assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) {
return P.isBitPiece();
}) && "all values are expected to be pieces");
assert(std::is_sorted(Values.begin(), Values.end()) &&
"pieces are expected to be sorted");
unsigned Offset = 0;
for (auto Piece : Values) {
DIExpression Expr = Piece.getExpression();
unsigned PieceOffset = Expr.getBitPieceOffset();
unsigned PieceSize = Expr.getBitPieceSize();
assert(Offset <= PieceOffset && "overlapping or duplicate pieces");
if (Offset < PieceOffset) {
// The DWARF spec seriously mandates pieces with no locations for gaps.
Asm->EmitDwarfOpPiece(Streamer, PieceOffset-Offset);
Offset += PieceOffset-Offset;
}
Offset += PieceSize;
#ifndef NDEBUG
DIVariable Var = Piece.getVariable();
unsigned VarSize = Var.getSizeInBits(Map);
assert(PieceSize+PieceOffset <= VarSize
&& "piece is larger than or outside of variable");
assert(PieceSize != VarSize
&& "piece covers entire variable");
#endif
emitDebugLocValue(Streamer, Piece, PieceOffset);
}
}
void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
const DebugLocEntry &Entry) {
const DebugLocEntry::Value Value = Entry.getValues()[0];
if (Value.isBitPiece())
// Emit all pieces that belong to the same variable and range.
return emitLocPieces(Streamer, TypeIdentifierMap, Entry.getValues());
assert(Entry.getValues().size() == 1 && "only pieces may have >1 value");
emitDebugLocValue(Streamer, Value);
auto Comment = Entry.getComments().begin();
auto End = Entry.getComments().end();
for (uint8_t Byte : Entry.getDWARFBytes())
Streamer.EmitInt8(Byte, Comment != End ? *(Comment++) : "");
}
void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,
const DebugLocEntry::Value &Value,
unsigned PieceOffsetInBits) {
static void emitDebugLocValue(const AsmPrinter &AP,
const DITypeIdentifierMap &TypeIdentifierMap,
ByteStreamer &Streamer,
const DebugLocEntry::Value &Value,
unsigned PieceOffsetInBits) {
DIVariable DV = Value.getVariable();
DebugLocDwarfExpression DwarfExpr(*Asm, Streamer);
DebugLocDwarfExpression DwarfExpr(
*AP.TM.getSubtargetImpl()->getRegisterInfo(),
AP.getDwarfDebug()->getDwarfVersion(), Streamer);
// Regular entry.
if (Value.isInt()) {
DIBasicType BTy(resolve(DV.getType()));
DIBasicType BTy(DV.getType().resolve(TypeIdentifierMap));
if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed ||
BTy.getEncoding() == dwarf::DW_ATE_signed_char))
DwarfExpr.AddSignedConstant(Value.getInt());
@ -1666,7 +1653,7 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,
DIExpression Expr = Value.getExpression();
if (!Expr || (Expr.getNumElements() == 0))
// Regular entry.
Asm->EmitDwarfRegOp(Streamer, Loc);
AP.EmitDwarfRegOp(Streamer, Loc);
else {
// Complex address entry.
if (Loc.getOffset()) {
@ -1682,6 +1669,52 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,
// FIXME: ^
}
void DebugLocEntry::finalize(const AsmPrinter &AP,
const DITypeIdentifierMap &TypeIdentifierMap) {
BufferByteStreamer Streamer(DWARFBytes, Comments);
const DebugLocEntry::Value Value = Values[0];
if (Value.isBitPiece()) {
// Emit all pieces that belong to the same variable and range.
assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) {
return P.isBitPiece();
}) && "all values are expected to be pieces");
assert(std::is_sorted(Values.begin(), Values.end()) &&
"pieces are expected to be sorted");
unsigned Offset = 0;
for (auto Piece : Values) {
DIExpression Expr = Piece.getExpression();
unsigned PieceOffset = Expr.getBitPieceOffset();
unsigned PieceSize = Expr.getBitPieceSize();
assert(Offset <= PieceOffset && "overlapping or duplicate pieces");
if (Offset < PieceOffset) {
// The DWARF spec seriously mandates pieces with no locations for gaps.
DebugLocDwarfExpression Expr(
*AP.TM.getSubtargetImpl()->getRegisterInfo(),
AP.getDwarfDebug()->getDwarfVersion(), Streamer);
Expr.AddOpPiece(PieceOffset-Offset, 0);
Offset += PieceOffset-Offset;
}
Offset += PieceSize;
#ifndef NDEBUG
DIVariable Var = Piece.getVariable();
unsigned VarSize = Var.getSizeInBits(TypeIdentifierMap);
assert(PieceSize+PieceOffset <= VarSize
&& "piece is larger than or outside of variable");
assert(PieceSize != VarSize
&& "piece covers entire variable");
#endif
emitDebugLocValue(AP, TypeIdentifierMap, Streamer, Piece, PieceOffset);
}
} else {
assert(Values.size() == 1 && "only pieces may have >1 value");
emitDebugLocValue(AP, TypeIdentifierMap, Streamer, Value, 0);
}
}
void DwarfDebug::emitDebugLocEntryLocation(const DebugLocEntry &Entry) {
Asm->OutStreamer.AddComment("Loc expr size");
MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol();

View File

@ -577,7 +577,8 @@ public:
/// \brief Emit an entry for the debug loc section. This can be used to
/// handle an entry that's going to be emitted into the debug loc section.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocEntry &Entry);
void emitDebugLocEntry(ByteStreamer &Streamer,
const DebugLocEntry &Entry);
/// \brief emit a single value for the debug loc section.
void emitDebugLocValue(ByteStreamer &Streamer,
const DebugLocEntry::Value &Value,

View File

@ -22,14 +22,6 @@
using namespace llvm;
const TargetRegisterInfo *DwarfExpression::getTRI() const {
return AP.TM.getSubtargetImpl()->getRegisterInfo();
}
unsigned DwarfExpression::getDwarfVersion() const {
return AP.getDwarfDebug()->getDwarfVersion();
}
void DwarfExpression::AddReg(int DwarfReg, const char *Comment) {
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
if (DwarfReg < 32) {
@ -74,7 +66,7 @@ void DwarfExpression::AddShr(unsigned ShiftBy) {
}
bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) {
int DwarfReg = getTRI()->getDwarfRegNum(MachineReg, false);
int DwarfReg = TRI.getDwarfRegNum(MachineReg, false);
if (DwarfReg < 0)
return false;
@ -91,11 +83,10 @@ bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) {
bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
unsigned PieceSizeInBits,
unsigned PieceOffsetInBits) {
const TargetRegisterInfo *TRI = getTRI();
if (!TRI->isPhysicalRegister(MachineReg))
if (!TRI.isPhysicalRegister(MachineReg))
return false;
int Reg = TRI->getDwarfRegNum(MachineReg, false);
int Reg = TRI.getDwarfRegNum(MachineReg, false);
// If this is a valid register number, emit it.
if (Reg >= 0) {
@ -107,12 +98,12 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
// Walk up the super-register chain until we find a valid number.
// For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
for (MCSuperRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) {
Reg = TRI->getDwarfRegNum(*SR, false);
for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
Reg = TRI.getDwarfRegNum(*SR, false);
if (Reg >= 0) {
unsigned Idx = TRI->getSubRegIndex(*SR, MachineReg);
unsigned Size = TRI->getSubRegIdxSize(Idx);
unsigned RegOffset = TRI->getSubRegIdxOffset(Idx);
unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
unsigned Size = TRI.getSubRegIdxSize(Idx);
unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
AddReg(Reg, "super-register");
if (PieceOffsetInBits == RegOffset) {
AddOpPiece(Size, RegOffset);
@ -136,15 +127,15 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
// efficient DW_OP_piece.
unsigned CurPos = PieceOffsetInBits;
// The size of the register in bits, assuming 8 bits per byte.
unsigned RegSize = TRI->getMinimalPhysRegClass(MachineReg)->getSize() * 8;
unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8;
// Keep track of the bits in the register we already emitted, so we
// can avoid emitting redundant aliasing subregs.
SmallBitVector Coverage(RegSize, false);
for (MCSubRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) {
unsigned Idx = TRI->getSubRegIndex(MachineReg, *SR);
unsigned Size = TRI->getSubRegIdxSize(Idx);
unsigned Offset = TRI->getSubRegIdxOffset(Idx);
Reg = TRI->getDwarfRegNum(*SR, false);
for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
unsigned Size = TRI.getSubRegIdxSize(Idx);
unsigned Offset = TRI.getSubRegIdxOffset(Idx);
Reg = TRI.getDwarfRegNum(*SR, false);
// Intersection between the bits we already emitted and the bits
// covered by this subregister.
@ -180,7 +171,7 @@ void DwarfExpression::AddSignedConstant(int Value) {
// value, so the producers and consumers started to rely on heuristics
// to disambiguate the value vs. location status of the expression.
// See PR21176 for more details.
if (getDwarfVersion() >= 4)
if (DwarfVersion >= 4)
EmitOp(dwarf::DW_OP_stack_value);
}
@ -188,7 +179,7 @@ void DwarfExpression::AddUnsignedConstant(unsigned Value) {
EmitOp(dwarf::DW_OP_constu);
EmitUnsigned(Value);
// cf. comment in DwarfExpression::AddSignedConstant().
if (getDwarfVersion() >= 4)
if (DwarfVersion >= 4)
EmitOp(dwarf::DW_OP_stack_value);
}

View File

@ -30,13 +30,14 @@ class DIELoc;
/// entry.
class DwarfExpression {
protected:
const AsmPrinter &AP;
// Various convenience accessors that extract things out of AsmPrinter.
const TargetRegisterInfo *getTRI() const;
unsigned getDwarfVersion() const;
const TargetRegisterInfo &TRI;
unsigned DwarfVersion;
public:
DwarfExpression(const AsmPrinter &AP) : AP(AP) {}
DwarfExpression(const TargetRegisterInfo &TRI,
unsigned DwarfVersion)
: TRI(TRI), DwarfVersion(DwarfVersion) {}
virtual ~DwarfExpression() {}
/// Output a dwarf operand and an optional assembler comment.
@ -105,8 +106,9 @@ class DebugLocDwarfExpression : public DwarfExpression {
ByteStreamer &BS;
public:
DebugLocDwarfExpression(const AsmPrinter &AP, ByteStreamer &BS)
: DwarfExpression(AP), BS(BS) {}
DebugLocDwarfExpression(const TargetRegisterInfo &TRI,
unsigned DwarfVersion, ByteStreamer &BS)
: DwarfExpression(TRI, DwarfVersion), BS(BS) {}
void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
void EmitSigned(int Value) override;
@ -116,13 +118,12 @@ public:
/// DwarfExpression implementation for singular DW_AT_location.
class DIEDwarfExpression : public DwarfExpression {
const AsmPrinter &AP;
DwarfUnit &DU;
DIELoc &DIE;
public:
DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE)
: DwarfExpression(AP), DU(DU), DIE(DIE) {}
DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
void EmitSigned(int Value) override;
void EmitUnsigned(unsigned Value) override;

View File

@ -43,6 +43,12 @@ GenerateDwarfTypeUnits("generate-type-units", cl::Hidden,
cl::desc("Generate DWARF4 type units."),
cl::init(false));
DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP,
DwarfUnit &DU, DIELoc &DIE)
: DwarfExpression(*AP.TM.getSubtargetImpl()->getRegisterInfo(),
AP.getDwarfDebug()->getDwarfVersion()),
AP(AP), DU(DU), DIE(DIE) {}
void DIEDwarfExpression::EmitOp(uint8_t Op, const char* Comment) {
DU.addUInt(DIE, dwarf::DW_FORM_data1, Op);
}
@ -53,7 +59,7 @@ void DIEDwarfExpression::EmitUnsigned(unsigned Value) {
DU.addUInt(DIE, dwarf::DW_FORM_udata, Value);
}
bool DIEDwarfExpression::isFrameRegister(unsigned MachineReg) {
return MachineReg == getTRI()->getFrameRegister(*AP.MF);
return MachineReg == TRI.getFrameRegister(*AP.MF);
}

View File

@ -3,13 +3,13 @@ target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-
target triple = "thumbv7-apple-macosx10.6.7"
;CHECK: sub-register DW_OP_regx
;CHECK-NEXT: ascii
;CHECK-NEXT: 256
;CHECK-NEXT: DW_OP_piece
;CHECK-NEXT: byte 8
;CHECK-NEXT: 8
;CHECK-NEXT: sub-register DW_OP_regx
;CHECK-NEXT: ascii
;CHECK-NEXT: 257
;CHECK-NEXT: DW_OP_piece
;CHECK-NEXT: byte 8
;CHECK-NEXT: 8
@.str = external constant [13 x i8]

View File

@ -2,7 +2,7 @@
; Radar 9309221
; Test dwarf reg no for s16
;CHECK: super-register DW_OP_regx
;CHECK-NEXT: ascii
;CHECK-NEXT: 264
;CHECK-NEXT: DW_OP_piece
;CHECK-NEXT: 4