return getHeaderFieldAs<int64_t>(I);
}
-bool DIExpression::isVariablePiece() const {
- return getNumElements() && getElement(0) == dwarf::DW_OP_piece;
+bool DIExpression::isBitPiece() const {
+ unsigned N = getNumElements();
+ return N >=3 && getElement(N-3) == dwarf::DW_OP_bit_piece;
}
-uint64_t DIExpression::getPieceOffset() const {
- assert(isVariablePiece());
- return getElement(1);
+uint64_t DIExpression::getBitPieceOffset() const {
+ assert(isBitPiece() && "not a piece");
+ return getElement(getNumElements()-2);
}
-uint64_t DIExpression::getPieceSize() const {
- assert(isVariablePiece());
- return getElement(2);
+uint64_t DIExpression::getBitPieceSize() const {
+ assert(isBitPiece() && "not a piece");
+ return getElement(getNumElements()-1);
+}
+
+DIExpression::iterator DIExpression::begin() const {
+ return DIExpression::iterator(*this);
+}
+
+DIExpression::iterator DIExpression::end() const {
+ return DIExpression::iterator();
+}
+
+DIExpression::Operand DIExpression::Operand::getNext() const {
+ iterator it(I);
+ return *(++it);
}
//===----------------------------------------------------------------------===//
}
bool DIDescriptor::isGlobalVariable() const {
- return DbgNode && (getTag() == dwarf::DW_TAG_variable ||
- getTag() == dwarf::DW_TAG_constant);
+ return DbgNode && getTag() == dwarf::DW_TAG_variable;
}
bool DIDescriptor::isScope() const {
while ((IA = DL.getInlinedAt()))
DL = DebugLoc::getFromDILocation(IA);
DL.getScopeAndInlinedAt(Scope, IA);
+ if (!Scope)
+ return false;
assert(!IA);
while (!DIDescriptor(Scope).isSubprogram()) {
DILexicalBlockFile D(Scope);
Scope = D.isLexicalBlockFile()
? D.getScope()
: DebugLoc::getFromDILexicalBlock(Scope).getScope();
+ if (!Scope)
+ return false;
}
if (!DISubprogram(Scope).describes(F))
return false;
if (!DbgNode)
return true;
- return isExpression() && DbgNode->getNumOperands() == 1;
+ if (!(isExpression() && DbgNode->getNumOperands() == 1))
+ return false;
+
+ for (auto Op : *this)
+ switch (Op) {
+ case DW_OP_bit_piece:
+ // Must be the last element of the expression.
+ return std::distance(Op.getBase(), DIHeaderFieldIterator()) == 3;
+ case DW_OP_plus:
+ if (std::distance(Op.getBase(), DIHeaderFieldIterator()) < 2)
+ return false;
+ break;
+ case DW_OP_deref:
+ break;
+ default:
+ // Other operators are not yet supported by the backend.
+ return false;
+ }
+ return true;
}
bool DILocation::Verify() const {
}
void DIExpression::printInternal(raw_ostream &OS) const {
- for (unsigned I = 0; I < getNumElements(); ++I) {
- uint64_t OpCode = getElement(I);
- OS << " [" << OperationEncodingString(OpCode);
- switch (OpCode) {
+ for (auto Op : *this) {
+ OS << " [" << OperationEncodingString(Op);
+ switch (Op) {
case DW_OP_plus: {
- OS << " " << getElement(++I);
+ OS << " " << Op.getArg(1);
break;
}
- case DW_OP_piece: {
- unsigned Offset = getElement(++I);
- unsigned Size = getElement(++I);
- OS << " offset=" << Offset << ", size=" << Size;
+ case DW_OP_bit_piece: {
+ OS << " offset=" << Op.getArg(1) << ", size=" << Op.getArg(2);
break;
}
case DW_OP_deref:
// No arguments.
break;
default:
- // Else bail out early. This may be a line table entry.
- OS << "Unknown]";
- return;
+ llvm_unreachable("unhandled operation");
}
OS << "]";
}
}
unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
- if (auto *Val = mdconst::extract_or_null<ConstantInt>(
+ if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
M.getModuleFlag("Debug Info Version")))
return Val->getZExtValue();
return 0;