diff options
Diffstat (limited to 'lib/IR/DebugInfo.cpp')
-rw-r--r-- | lib/IR/DebugInfo.cpp | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index db9e56defa..5e39b242db 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -138,8 +138,14 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) { } } -unsigned DIVariable::getNumAddrElements() const { - return DbgNode->getNumOperands() - 8; +uint64_t DIVariable::getAddrElement(unsigned Idx) const { + DIDescriptor ComplexExpr = getDescriptorField(8); + if (Idx < ComplexExpr->getNumOperands()) + if (auto *CI = dyn_cast_or_null<ConstantInt>(ComplexExpr->getOperand(Idx))) + return CI->getZExtValue(); + + assert(false && "non-existing complex address element requested"); + return 0; } /// getInlinedAt - If this variable is inlined then return inline location. @@ -566,7 +572,13 @@ bool DIVariable::Verify() const { // Make sure that type @ field 5 is a DITypeRef. if (!fieldIsTypeRef(DbgNode, 5)) return false; - return DbgNode->getNumOperands() >= 8; + + // Variable without a complex expression. + if (DbgNode->getNumOperands() == 8) + return true; + + // Make sure the complex expression is an MDNode. + return (DbgNode->getNumOperands() == 9 && fieldIsMDNode(DbgNode, 8)); } /// Verify - Verify that a location descriptor is well formed. @@ -1514,3 +1526,23 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) { return 0; return cast<ConstantInt>(Val)->getZExtValue(); } + +llvm::DenseMap<const llvm::Function *, llvm::DISubprogram> +llvm::makeSubprogramMap(const Module &M) { + DenseMap<const Function *, DISubprogram> R; + + NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); + if (!CU_Nodes) + return R; + + for (MDNode *N : CU_Nodes->operands()) { + DICompileUnit CUNode(N); + DIArray SPs = CUNode.getSubprograms(); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { + DISubprogram SP(SPs.getElement(i)); + if (Function *F = SP.getFunction()) + R.insert(std::make_pair(F, SP)); + } + } + return R; +} |