aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h119
1 files changed, 85 insertions, 34 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 36278f2e9e2d..62ebadaf3cbe 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -34,10 +34,10 @@ struct TargetIndexLocation {
}
};
-/// A single location or constant.
-class DbgValueLoc {
- /// Any complex address location expression for this DbgValueLoc.
- const DIExpression *Expression;
+/// A single location or constant within a variable location description, with
+/// either a single entry (with an optional DIExpression) used for a DBG_VALUE,
+/// or a list of entries used for a DBG_VALUE_LIST.
+class DbgValueLocEntry {
/// Type of entry that this represents.
enum EntryType {
@@ -64,24 +64,16 @@ class DbgValueLoc {
};
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) {
+ DbgValueLocEntry(int64_t i) : EntryKind(E_Integer) { Constant.Int = i; }
+ DbgValueLocEntry(const ConstantFP *CFP) : EntryKind(E_ConstantFP) {
Constant.CFP = CFP;
}
- DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP)
- : Expression(Expr), EntryKind(E_ConstantInt) {
+ DbgValueLocEntry(const ConstantInt *CIP) : EntryKind(E_ConstantInt) {
Constant.CIP = CIP;
}
- DbgValueLoc(const DIExpression *Expr, MachineLocation Loc)
- : Expression(Expr), EntryKind(E_Location), Loc(Loc) {
- assert(cast<DIExpression>(Expr)->isValid());
- }
- DbgValueLoc(const DIExpression *Expr, TargetIndexLocation Loc)
- : Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {}
+ DbgValueLocEntry(MachineLocation Loc) : EntryKind(E_Location), Loc(Loc) {}
+ DbgValueLocEntry(TargetIndexLocation Loc)
+ : EntryKind(E_TargetIndexLocation), TIL(Loc) {}
bool isLocation() const { return EntryKind == E_Location; }
bool isTargetIndexLocation() const {
@@ -95,11 +87,7 @@ public:
const ConstantInt *getConstantInt() const { return Constant.CIP; }
MachineLocation getLoc() const { return Loc; }
TargetIndexLocation getTargetIndexLocation() const { return TIL; }
- bool isFragment() const { return getExpression()->isFragment(); }
- bool isEntryVal() const { return getExpression()->isEntryValue(); }
- const DIExpression *getExpression() const { return Expression; }
- friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
- friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
+ friend bool operator==(const DbgValueLocEntry &, const DbgValueLocEntry &);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void dump() const {
if (isLocation()) {
@@ -111,6 +99,67 @@ public:
Constant.CIP->dump();
else if (isConstantFP())
Constant.CFP->dump();
+ }
+#endif
+};
+
+/// The location of a single variable, composed of an expression and 0 or more
+/// DbgValueLocEntries.
+class DbgValueLoc {
+ /// Any complex address location expression for this DbgValueLoc.
+ const DIExpression *Expression;
+
+ SmallVector<DbgValueLocEntry, 2> ValueLocEntries;
+
+ bool IsVariadic;
+
+public:
+ DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs)
+ : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
+ IsVariadic(true) {
+#ifndef NDEBUG
+ // Currently, DBG_VALUE_VAR expressions must use stack_value.
+ assert(Expr && Expr->isValid() &&
+ is_contained(Locs, dwarf::DW_OP_stack_value));
+#endif
+ }
+
+ DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
+ bool IsVariadic)
+ : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
+ IsVariadic(IsVariadic) {
+#ifndef NDEBUG
+ assert(cast<DIExpression>(Expr)->isValid() ||
+ !any_of(Locs, [](auto LE) { return LE.isLocation(); }));
+ if (!IsVariadic) {
+ assert(ValueLocEntries.size() == 1);
+ } else {
+ // Currently, DBG_VALUE_VAR expressions must use stack_value.
+ assert(Expr && Expr->isValid() &&
+ is_contained(Expr->getElements(), dwarf::DW_OP_stack_value));
+ }
+#endif
+ }
+
+ DbgValueLoc(const DIExpression *Expr, DbgValueLocEntry Loc)
+ : Expression(Expr), ValueLocEntries(1, Loc), IsVariadic(false) {
+ assert(((Expr && Expr->isValid()) || !Loc.isLocation()) &&
+ "DBG_VALUE with a machine location must have a valid expression.");
+ }
+
+ bool isFragment() const { return getExpression()->isFragment(); }
+ bool isEntryVal() const { return getExpression()->isEntryValue(); }
+ bool isVariadic() const { return IsVariadic; }
+ const DIExpression *getExpression() const { return Expression; }
+ const ArrayRef<DbgValueLocEntry> getLocEntries() const {
+ return ValueLocEntries;
+ }
+ 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 {
+ for (DbgValueLocEntry DV : ValueLocEntries)
+ DV.dump();
if (Expression)
Expression->dump();
}
@@ -180,30 +229,32 @@ public:
DwarfCompileUnit &TheCU);
};
-/// Compare two DbgValueLocs for equality.
-inline bool operator==(const DbgValueLoc &A,
- const DbgValueLoc &B) {
+/// Compare two DbgValueLocEntries for equality.
+inline bool operator==(const DbgValueLocEntry &A, const DbgValueLocEntry &B) {
if (A.EntryKind != B.EntryKind)
return false;
- if (A.Expression != B.Expression)
- return false;
-
switch (A.EntryKind) {
- case DbgValueLoc::E_Location:
+ case DbgValueLocEntry::E_Location:
return A.Loc == B.Loc;
- case DbgValueLoc::E_TargetIndexLocation:
+ case DbgValueLocEntry::E_TargetIndexLocation:
return A.TIL == B.TIL;
- case DbgValueLoc::E_Integer:
+ case DbgValueLocEntry::E_Integer:
return A.Constant.Int == B.Constant.Int;
- case DbgValueLoc::E_ConstantFP:
+ case DbgValueLocEntry::E_ConstantFP:
return A.Constant.CFP == B.Constant.CFP;
- case DbgValueLoc::E_ConstantInt:
+ case DbgValueLocEntry::E_ConstantInt:
return A.Constant.CIP == B.Constant.CIP;
}
llvm_unreachable("unhandled EntryKind");
}
+/// Compare two DbgValueLocs for equality.
+inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) {
+ return A.ValueLocEntries == B.ValueLocEntries &&
+ A.Expression == B.Expression && A.IsVariadic == B.IsVariadic;
+}
+
/// Compare two fragments based on their offset.
inline bool operator<(const DbgValueLoc &A,
const DbgValueLoc &B) {