IR: Take advantage of -verify checks for MDExpression

Now that we check `MDExpression` during `-verify` (r232299), make
the `DIExpression` wrapper more strict:

  - remove redundant checks in `DebugInfoVerifier`,
  - overload `get()` to `cast_or_null<MDExpression>` (superseding
    `getRaw()`),
  - stop checking for null in any accessor, and
  - remove `DIExpression::Verify()` entirely in favour of
    `MDExpression::isValid()`.

There is still some logic in this class, mostly to do with high-level
iterators; I'll defer cleaning up those until the rest of the wrappers
are similarly strict.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232412 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2015-03-16 21:03:55 +00:00
parent 83c42e65fb
commit 3d5527fb43
7 changed files with 19 additions and 27 deletions

View File

@ -257,9 +257,7 @@ public:
/// this DBG_VALUE instruction. /// this DBG_VALUE instruction.
DIExpression getDebugExpression() const { DIExpression getDebugExpression() const {
assert(isDebugValue() && "not a DBG_VALUE"); assert(isDebugValue() && "not a DBG_VALUE");
DIExpression Expr(getOperand(3).getMetadata()); return cast<MDExpression>(getOperand(3).getMetadata());
assert(Expr.Verify() && "not a DIExpression");
return Expr;
} }
/// emitError - Emit an error referring to the source location of this /// emitError - Emit an error referring to the source location of this

View File

@ -356,7 +356,7 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL,
unsigned Reg, unsigned Offset, unsigned Reg, unsigned Offset,
const MDNode *Variable, const MDNode *Expr) { const MDNode *Variable, const MDNode *Expr) {
assert(DIVariable(Variable).Verify() && "not a DIVariable"); assert(DIVariable(Variable).Verify() && "not a DIVariable");
assert(DIExpression(Expr).Verify() && "not a DIExpression"); assert(DIExpression(Expr)->isValid() && "not a DIExpression");
if (IsIndirect) if (IsIndirect)
return BuildMI(MF, DL, MCID) return BuildMI(MF, DL, MCID)
.addReg(Reg, RegState::Debug) .addReg(Reg, RegState::Debug)
@ -383,7 +383,7 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
unsigned Reg, unsigned Offset, unsigned Reg, unsigned Offset,
const MDNode *Variable, const MDNode *Expr) { const MDNode *Variable, const MDNode *Expr) {
assert(DIVariable(Variable).Verify() && "not a DIVariable"); assert(DIVariable(Variable).Verify() && "not a DIVariable");
assert(DIExpression(Expr).Verify() && "not a DIExpression"); assert(DIExpression(Expr)->isValid() && "not a DIExpression");
MachineFunction &MF = *BB.getParent(); MachineFunction &MF = *BB.getParent();
MachineInstr *MI = MachineInstr *MI =
BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr);

View File

@ -989,21 +989,24 @@ public:
/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const /// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
/// and have DW_OP_plus consume the topmost elements on the stack. /// and have DW_OP_plus consume the topmost elements on the stack.
class DIExpression : public DIDescriptor { class DIExpression : public DIDescriptor {
MDExpression *getRaw() const { return dyn_cast_or_null<MDExpression>(get()); }
public: public:
explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {} explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {}
DIExpression(const MDExpression *N) : DIDescriptor(N) {} DIExpression(const MDExpression *N) : DIDescriptor(N) {}
bool Verify() const; MDExpression *get() const {
return cast_or_null<MDExpression>(DIDescriptor::get());
}
operator MDExpression *() const { return get(); }
MDExpression *operator->() const { return get(); }
// Don't call this. Call isValid() directly.
bool Verify() const = delete;
/// \brief Return the number of elements in the complex expression. /// \brief Return the number of elements in the complex expression.
unsigned getNumElements() const { RETURN_FROM_RAW(N->getNumElements(), 0); } unsigned getNumElements() const { return get()->getNumElements(); }
/// \brief return the Idx'th complex address element. /// \brief return the Idx'th complex address element.
uint64_t getElement(unsigned I) const { uint64_t getElement(unsigned I) const { return get()->getElement(I); }
return cast<MDExpression>(get())->getElement(I);
}
/// \brief Return whether this is a piece of an aggregate variable. /// \brief Return whether this is a piece of an aggregate variable.
bool isBitPiece() const; bool isBitPiece() const;
@ -1069,8 +1072,8 @@ public:
} }
}; };
iterator begin() const { return cast<MDExpression>(get())->elements_begin(); } iterator begin() const { return get()->elements_begin(); }
iterator end() const { return cast<MDExpression>(get())->elements_end(); } iterator end() const { return get()->elements_end(); }
}; };
/// \brief This object holds location information. /// \brief This object holds location information.

View File

@ -43,7 +43,7 @@ public:
Value(const MDNode *Var, const MDNode *Expr, MachineLocation Loc) Value(const MDNode *Var, const MDNode *Expr, MachineLocation Loc)
: Variable(Var), Expression(Expr), EntryKind(E_Location), Loc(Loc) { : Variable(Var), Expression(Expr), EntryKind(E_Location), Loc(Loc) {
assert(DIVariable(Var).Verify()); assert(DIVariable(Var).Verify());
assert(DIExpression(Expr).Verify()); assert(DIExpression(Expr)->isValid());
} }
/// The variable to which this location entry corresponds. /// The variable to which this location entry corresponds.

View File

@ -88,7 +88,8 @@ public:
: Var(V), Expr(1, E), TheDIE(nullptr), DotDebugLocOffset(~0U), : Var(V), Expr(1, E), TheDIE(nullptr), DotDebugLocOffset(~0U),
MInsn(nullptr), DD(DD) { MInsn(nullptr), DD(DD) {
FrameIndex.push_back(FI); FrameIndex.push_back(FI);
assert(Var.Verify() && E.Verify()); assert(Var.Verify());
assert(!E || E->isValid());
} }
/// Construct a DbgVariable from a DEBUG_VALUE. /// Construct a DbgVariable from a DEBUG_VALUE.

View File

@ -92,7 +92,7 @@ bool DIDescriptor::Verify() const {
DIObjCProperty(DbgNode).Verify() || DIObjCProperty(DbgNode).Verify() ||
DITemplateTypeParameter(DbgNode).Verify() || DITemplateTypeParameter(DbgNode).Verify() ||
DITemplateValueParameter(DbgNode).Verify() || DITemplateValueParameter(DbgNode).Verify() ||
DIImportedEntity(DbgNode).Verify() || DIExpression(DbgNode).Verify()); DIImportedEntity(DbgNode).Verify());
} }
static Metadata *getField(const MDNode *DbgNode, unsigned Elt) { static Metadata *getField(const MDNode *DbgNode, unsigned Elt) {
@ -402,12 +402,6 @@ bool DIVariable::Verify() const {
return isTypeRef(N->getType()); return isTypeRef(N->getType());
} }
bool DIExpression::Verify() const {
// FIXME: This should return false if it's null!
auto *N = getRaw();
return !N || N->isValid();
}
bool DILocation::Verify() const { return getRaw(); } bool DILocation::Verify() const { return getRaw(); }
bool DINameSpace::Verify() const { return getRaw(); } bool DINameSpace::Verify() const { return getRaw(); }
bool DIFile::Verify() const { return getRaw(); } bool DIFile::Verify() const { return getRaw(); }

View File

@ -3078,15 +3078,11 @@ void DebugInfoVerifier::processCallInst(DebugInfoFinder &Finder,
case Intrinsic::dbg_declare: { case Intrinsic::dbg_declare: {
auto *DDI = cast<DbgDeclareInst>(&CI); auto *DDI = cast<DbgDeclareInst>(&CI);
Finder.processDeclare(*M, DDI); Finder.processDeclare(*M, DDI);
if (auto E = DDI->getExpression())
Assert(DIExpression(E).Verify(), "DIExpression does not Verify!", E);
break; break;
} }
case Intrinsic::dbg_value: { case Intrinsic::dbg_value: {
auto *DVI = cast<DbgValueInst>(&CI); auto *DVI = cast<DbgValueInst>(&CI);
Finder.processValue(*M, DVI); Finder.processValue(*M, DVI);
if (auto E = DVI->getExpression())
Assert(DIExpression(E).Verify(), "DIExpression does not Verify!", E);
break; break;
} }
default: default: