diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp
index 9003fff707128c3e2cfa06767c52a45d25b8bd06..5dff50d362f68388ed00828eecefcc3e13c9a061 100644 (file)
--- a/lib/IR/DebugInfo.cpp
+++ b/lib/IR/DebugInfo.cpp
}
bool DIExpression::isVariablePiece() const {
- return getNumElements() && getElement(0) == dwarf::DW_OP_piece;
+ unsigned N = getNumElements();
+ return N >=3 && getElement(N-3) == dwarf::DW_OP_piece;
}
uint64_t DIExpression::getPieceOffset() const {
- assert(isVariablePiece());
- return getElement(1);
+ assert(isVariablePiece() && "not a piece");
+ return getElement(getNumElements()-2);
}
uint64_t DIExpression::getPieceSize() const {
- assert(isVariablePiece());
- return getElement(2);
+ assert(isVariablePiece() && "not a piece");
+ return getElement(getNumElements()-1);
}
//===----------------------------------------------------------------------===//
if (!DbgNode)
return true;
+ unsigned N = getNumElements();
+ for (unsigned I = 0; I < N; ++I)
+ switch (getElement(I)) {
+ case DW_OP_piece:
+ // DW_OP_piece has to be the last element in the expression and take two
+ // arguments.
+ if (getElement(I) == DW_OP_piece && !isVariablePiece())
+ return false;
+ I += 2;
+ break;
+ case DW_OP_plus:
+ // Takes one argument.
+ if (I+1 == N)
+ return false;
+ I += 1;
+ break;
+ default: break;
+ }
return isExpression() && DbgNode->getNumOperands() == 1;
}