namespace llvm {
class AsmPrinter;
+/// A single location or constant.
+class DbgValueLoc {
+ /// Any complex address location expression for this DbgValueLoc.
+ const DIExpression *Expression;
+
+ /// Type of entry that this represents.
+ enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
+ enum EntryType EntryKind;
+
+ /// Either a constant,
+ union {
+ int64_t Int;
+ const ConstantFP *CFP;
+ const ConstantInt *CIP;
+ } Constant;
+
+ /// Or a location in the machine frame.
+ MachineLocation Loc;
+
+public:
+ DbgValueLoc(const DIExpression *Expr, int64_t i)
+ : Expression(Expr), EntryKind(E_Integer) {
+ Constant.Int = i;
+ }
+ DbgValueLoc(const DIExpression *Expr, const ConstantFP *CFP)
+ : Expression(Expr), EntryKind(E_ConstantFP) {
+ Constant.CFP = CFP;
+ }
+ DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP)
+ : Expression(Expr), EntryKind(E_ConstantInt) {
+ Constant.CIP = CIP;
+ }
+ DbgValueLoc(const DIExpression *Expr, MachineLocation Loc)
+ : Expression(Expr), EntryKind(E_Location), Loc(Loc) {
+ assert(cast<DIExpression>(Expr)->isValid());
+ }
+
+ bool isLocation() const { return EntryKind == E_Location; }
+ bool isInt() const { return EntryKind == E_Integer; }
+ bool isConstantFP() const { return EntryKind == E_ConstantFP; }
+ bool isConstantInt() const { return EntryKind == E_ConstantInt; }
+ int64_t getInt() const { return Constant.Int; }
+ const ConstantFP *getConstantFP() const { return Constant.CFP; }
+ const ConstantInt *getConstantInt() const { return Constant.CIP; }
+ MachineLocation getLoc() const { return Loc; }
+ bool isFragment() const { return getExpression()->isFragment(); }
+ const DIExpression *getExpression() const { return Expression; }
+ friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
+ friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const {
+ if (isLocation()) {
+ llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
+ if (Loc.isIndirect())
+ llvm::dbgs() << "+0";
+ llvm::dbgs() << "} ";
+ } else if (isConstantInt())
+ Constant.CIP->dump();
+ else if (isConstantFP())
+ Constant.CFP->dump();
+ if (Expression)
+ Expression->dump();
+ }
+#endif
+};
+
/// This struct describes location entries emitted in the .debug_loc
/// section.
class DebugLocEntry {
const MCSymbol *Begin;
const MCSymbol *End;
-public:
- /// A single location or constant.
- struct Value {
- Value(const DIExpression *Expr, int64_t i)
- : Expression(Expr), EntryKind(E_Integer) {
- Constant.Int = i;
- }
- Value(const DIExpression *Expr, const ConstantFP *CFP)
- : Expression(Expr), EntryKind(E_ConstantFP) {
- Constant.CFP = CFP;
- }
- Value(const DIExpression *Expr, const ConstantInt *CIP)
- : Expression(Expr), EntryKind(E_ConstantInt) {
- Constant.CIP = CIP;
- }
- Value(const DIExpression *Expr, MachineLocation Loc)
- : Expression(Expr), EntryKind(E_Location), Loc(Loc) {
- assert(cast<DIExpression>(Expr)->isValid());
- }
-
- /// Any complex address location expression for this Value.
- const DIExpression *Expression;
-
- /// Type of entry that this represents.
- enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
- enum EntryType EntryKind;
-
- /// Either a constant,
- union {
- int64_t Int;
- const ConstantFP *CFP;
- const ConstantInt *CIP;
- } Constant;
-
- // Or a location in the machine frame.
- MachineLocation Loc;
-
- bool isLocation() const { return EntryKind == E_Location; }
- bool isInt() const { return EntryKind == E_Integer; }
- bool isConstantFP() const { return EntryKind == E_ConstantFP; }
- bool isConstantInt() const { return EntryKind == E_ConstantInt; }
- int64_t getInt() const { return Constant.Int; }
- const ConstantFP *getConstantFP() const { return Constant.CFP; }
- const ConstantInt *getConstantInt() const { return Constant.CIP; }
- MachineLocation getLoc() const { return Loc; }
- bool isFragment() const { return getExpression()->isFragment(); }
- const DIExpression *getExpression() const { return Expression; }
- friend bool operator==(const Value &, const Value &);
- friend bool operator<(const Value &, const Value &);
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const {
- if (isLocation()) {
- llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
- if (Loc.isIndirect())
- llvm::dbgs() << "+0";
- llvm::dbgs() << "} ";
- }
- else if (isConstantInt())
- Constant.CIP->dump();
- else if (isConstantFP())
- Constant.CFP->dump();
- if (Expression)
- Expression->dump();
- }
-#endif
- };
-
-private:
/// A nonempty list of locations/constants belonging to this entry,
/// sorted by offset.
- SmallVector<Value, 1> Values;
+ SmallVector<DbgValueLoc, 1> Values;
public:
/// Create a location list entry for the range [\p Begin, \p End).
///
/// \param Vals One or more values describing (parts of) the variable.
DebugLocEntry(const MCSymbol *Begin, const MCSymbol *End,
- ArrayRef<Value> Vals)
+ ArrayRef<DbgValueLoc> Vals)
: Begin(Begin), End(End) {
addValues(Vals);
}
const MCSymbol *getBeginSym() const { return Begin; }
const MCSymbol *getEndSym() const { return End; }
- ArrayRef<Value> getValues() const { return Values; }
- void addValues(ArrayRef<DebugLocEntry::Value> Vals) {
+ ArrayRef<DbgValueLoc> getValues() const { return Values; }
+ void addValues(ArrayRef<DbgValueLoc> Vals) {
Values.append(Vals.begin(), Vals.end());
sortUniqueValues();
- assert((Values.size() == 1 ||
- all_of(Values,
- [](DebugLocEntry::Value V) { return V.isFragment(); })) &&
- "must either have a single value or multiple pieces");
+ assert((Values.size() == 1 || all_of(Values, [](DbgValueLoc V) {
+ return V.isFragment();
+ })) && "must either have a single value or multiple pieces");
}
// Sort the pieces by offset.
// Remove any duplicate entries by dropping all but the first.
void sortUniqueValues() {
llvm::sort(Values);
- Values.erase(
- std::unique(
- Values.begin(), Values.end(), [](const Value &A, const Value &B) {
- return A.getExpression() == B.getExpression();
- }),
- Values.end());
+ Values.erase(std::unique(Values.begin(), Values.end(),
+ [](const DbgValueLoc &A, const DbgValueLoc &B) {
+ return A.getExpression() == B.getExpression();
+ }),
+ Values.end());
}
/// Lower this entry into a DWARF expression.
DwarfCompileUnit &TheCU);
};
-/// Compare two Values for equality.
-inline bool operator==(const DebugLocEntry::Value &A,
- const DebugLocEntry::Value &B) {
+/// Compare two DbgValueLocs for equality.
+inline bool operator==(const DbgValueLoc &A,
+ const DbgValueLoc &B) {
if (A.EntryKind != B.EntryKind)
return false;
return false;
switch (A.EntryKind) {
- case DebugLocEntry::Value::E_Location:
+ case DbgValueLoc::E_Location:
return A.Loc == B.Loc;
- case DebugLocEntry::Value::E_Integer:
+ case DbgValueLoc::E_Integer:
return A.Constant.Int == B.Constant.Int;
- case DebugLocEntry::Value::E_ConstantFP:
+ case DbgValueLoc::E_ConstantFP:
return A.Constant.CFP == B.Constant.CFP;
- case DebugLocEntry::Value::E_ConstantInt:
+ case DbgValueLoc::E_ConstantInt:
return A.Constant.CIP == B.Constant.CIP;
}
llvm_unreachable("unhandled EntryKind");
}
/// Compare two fragments based on their offset.
-inline bool operator<(const DebugLocEntry::Value &A,
- const DebugLocEntry::Value &B) {
+inline bool operator<(const DbgValueLoc &A,
+ const DbgValueLoc &B) {
return A.getExpression()->getFragmentInfo()->OffsetInBits <
B.getExpression()->getFragmentInfo()->OffsetInBits;
}
}
/// Get .debug_loc entry for the instruction range starting at MI.
-static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
+static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
const DIExpression *Expr = MI->getDebugExpression();
assert(MI->getNumOperands() == 4);
if (MI->getOperand(0).isReg()) {
// register-indirect address.
assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
- return DebugLocEntry::Value(Expr, MLoc);
+ return DbgValueLoc(Expr, MLoc);
}
if (MI->getOperand(0).isImm())
- return DebugLocEntry::Value(Expr, MI->getOperand(0).getImm());
+ return DbgValueLoc(Expr, MI->getOperand(0).getImm());
if (MI->getOperand(0).isFPImm())
- return DebugLocEntry::Value(Expr, MI->getOperand(0).getFPImm());
+ return DbgValueLoc(Expr, MI->getOperand(0).getFPImm());
if (MI->getOperand(0).isCImm())
- return DebugLocEntry::Value(Expr, MI->getOperand(0).getCImm());
+ return DbgValueLoc(Expr, MI->getOperand(0).getCImm());
llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
}
assert(getInlinedAt() == DbgValue->getDebugLoc()->getInlinedAt() &&
"Wrong inlined-at");
- ValueLoc = llvm::make_unique<DebugLocEntry::Value>(getDebugLocValue(DbgValue));
+ ValueLoc = llvm::make_unique<DbgValueLoc>(getDebugLocValue(DbgValue));
if (auto *E = DbgValue->getDebugExpression())
if (E->getNumElements())
FrameIndexExprs.push_back({0, E});
bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
const DbgValueHistoryMap::Entries &Entries) {
using OpenRange =
- std::pair<DbgValueHistoryMap::EntryIndex, DebugLocEntry::Value>;
+ std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
SmallVector<OpenRange, 4> OpenRanges;
bool isSafeForSingleLocation = true;
const MachineInstr *StartDebugMI = nullptr;
continue;
}
- SmallVector<DebugLocEntry::Value, 4> Values;
+ SmallVector<DbgValueLoc, 4> Values;
for (auto &R : OpenRanges)
Values.push_back(R.second);
DebugLoc.emplace_back(StartLabel, EndLabel, Values);
}
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
- const DebugLocEntry::Value &Value,
+ const DbgValueLoc &Value,
DwarfExpression &DwarfExpr) {
auto *DIExpr = Value.getExpression();
DIExpressionCursor ExprCursor(DIExpr);
DebugLocStream::EntryBuilder Entry(List, Begin, End);
BufferByteStreamer Streamer = Entry.getStreamer();
DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU);
- const DebugLocEntry::Value &Value = Values[0];
+ const DbgValueLoc &Value = Values[0];
if (Value.isFragment()) {
// Emit all fragments that belong to the same variable and range.
- assert(llvm::all_of(Values, [](DebugLocEntry::Value P) {
+ assert(llvm::all_of(Values, [](DbgValueLoc P) {
return P.isFragment();
}) && "all values are expected to be fragments");
assert(std::is_sorted(Values.begin(), Values.end()) &&