diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/IR/DebugInfoMetadata.cpp | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Diffstat (limited to 'lib/IR/DebugInfoMetadata.cpp')
-rw-r--r-- | lib/IR/DebugInfoMetadata.cpp | 121 |
1 files changed, 107 insertions, 14 deletions
diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index 92f3f21f754c..900df27d1d33 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -1,9 +1,8 @@ //===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -89,7 +88,7 @@ const DILocation *DILocation::getMergedLocation(const DILocation *LocA, DILocation *L = LocA->getInlinedAt(); while (S) { Locations.insert(std::make_pair(S, L)); - S = S->getScope().resolve(); + S = S->getScope(); if (!S && L) { S = L->getScope(); L = L->getInlinedAt(); @@ -101,7 +100,7 @@ const DILocation *DILocation::getMergedLocation(const DILocation *LocA, while (S) { if (Locations.count(std::make_pair(S, L))) break; - S = S->getScope().resolve(); + S = S->getScope(); if (!S && L) { S = L->getScope(); L = L->getInlinedAt(); @@ -210,7 +209,7 @@ DINode::DIFlags DINode::splitFlags(DIFlags Flags, return Flags; } -DIScopeRef DIScope::getScope() const { +DIScope *DIScope::getScope() const { if (auto *T = dyn_cast<DIType>(this)) return T->getScope(); @@ -223,6 +222,9 @@ DIScopeRef DIScope::getScope() const { if (auto *NS = dyn_cast<DINamespace>(this)) return NS->getScope(); + if (auto *CB = dyn_cast<DICommonBlock>(this)) + return CB->getScope(); + if (auto *M = dyn_cast<DIModule>(this)) return M->getScope(); @@ -238,6 +240,8 @@ StringRef DIScope::getName() const { return SP->getName(); if (auto *NS = dyn_cast<DINamespace>(this)) return NS->getName(); + if (auto *CB = dyn_cast<DICommonBlock>(this)) + return CB->getName(); if (auto *M = dyn_cast<DIModule>(this)) return M->getName(); assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) || @@ -695,6 +699,17 @@ DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope, DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops); } +DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope, + Metadata *Decl, MDString *Name, + Metadata *File, unsigned LineNo, + StorageType Storage, bool ShouldCreate) { + assert(isCanonical(Name) && "Expected canonical MDString"); + DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo)); + // The nullptr is for DIScope's File operand. This should be refactored. + Metadata *Ops[] = {Scope, Decl, Name, File}; + DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops); +} + DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, MDString *ISysRoot, @@ -814,10 +829,14 @@ DIExpression *DIExpression::getImpl(LLVMContext &Context, unsigned DIExpression::ExprOperand::getSize() const { switch (getOp()) { + case dwarf::DW_OP_LLVM_convert: case dwarf::DW_OP_LLVM_fragment: return 3; case dwarf::DW_OP_constu: + case dwarf::DW_OP_deref_size: case dwarf::DW_OP_plus_uconst: + case dwarf::DW_OP_LLVM_tag_offset: + case dwarf::DW_OP_entry_value: return 2; default: return 1; @@ -858,6 +877,15 @@ bool DIExpression::isValid() const { return false; break; } + case dwarf::DW_OP_entry_value: { + // An entry value operator must appear at the begin and the size + // of following expression should be 1, because we support only + // entry values of a simple register location. + return I->get() == expr_op_begin()->get() && I->getArg(0) == 1 && + getNumElements() == 2; + } + case dwarf::DW_OP_LLVM_convert: + case dwarf::DW_OP_LLVM_tag_offset: case dwarf::DW_OP_constu: case dwarf::DW_OP_plus_uconst: case dwarf::DW_OP_plus: @@ -872,6 +900,7 @@ bool DIExpression::isValid() const { case dwarf::DW_OP_shr: case dwarf::DW_OP_shra: case dwarf::DW_OP_deref: + case dwarf::DW_OP_deref_size: case dwarf::DW_OP_xderef: case dwarf::DW_OP_lit0: case dwarf::DW_OP_not: @@ -882,6 +911,42 @@ bool DIExpression::isValid() const { return true; } +bool DIExpression::isImplicit() const { + unsigned N = getNumElements(); + if (isValid() && N > 0) { + switch (getElement(N-1)) { + case dwarf::DW_OP_stack_value: + case dwarf::DW_OP_LLVM_tag_offset: + return true; + case dwarf::DW_OP_LLVM_fragment: + return N > 1 && getElement(N-2) == dwarf::DW_OP_stack_value; + default: break; + } + } + return false; +} + +bool DIExpression::isComplex() const { + if (!isValid()) + return false; + + if (getNumElements() == 0) + return false; + + // If there are any elements other than fragment or tag_offset, then some + // kind of complex computation occurs. + for (const auto &It : expr_ops()) { + switch (It.getOp()) { + case dwarf::DW_OP_LLVM_tag_offset: + case dwarf::DW_OP_LLVM_fragment: + continue; + default: return true; + } + } + + return false; +} + Optional<DIExpression::FragmentInfo> DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) { for (auto I = Start; I != End; ++I) @@ -929,25 +994,53 @@ bool DIExpression::extractIfOffset(int64_t &Offset) const { return false; } -DIExpression *DIExpression::prepend(const DIExpression *Expr, bool DerefBefore, - int64_t Offset, bool DerefAfter, - bool StackValue) { +const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr, + unsigned &AddrClass) { + const unsigned PatternSize = 4; + if (Expr->Elements.size() >= PatternSize && + Expr->Elements[PatternSize - 4] == dwarf::DW_OP_constu && + Expr->Elements[PatternSize - 2] == dwarf::DW_OP_swap && + Expr->Elements[PatternSize - 1] == dwarf::DW_OP_xderef) { + AddrClass = Expr->Elements[PatternSize - 3]; + + if (Expr->Elements.size() == PatternSize) + return nullptr; + return DIExpression::get(Expr->getContext(), + makeArrayRef(&*Expr->Elements.begin(), + Expr->Elements.size() - PatternSize)); + } + return Expr; +} + +DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags, + int64_t Offset) { SmallVector<uint64_t, 8> Ops; - if (DerefBefore) + if (Flags & DIExpression::DerefBefore) Ops.push_back(dwarf::DW_OP_deref); appendOffset(Ops, Offset); - if (DerefAfter) + if (Flags & DIExpression::DerefAfter) Ops.push_back(dwarf::DW_OP_deref); - return prependOpcodes(Expr, Ops, StackValue); + bool StackValue = Flags & DIExpression::StackValue; + bool EntryValue = Flags & DIExpression::EntryValue; + + return prependOpcodes(Expr, Ops, StackValue, EntryValue); } DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr, SmallVectorImpl<uint64_t> &Ops, - bool StackValue) { + bool StackValue, + bool EntryValue) { assert(Expr && "Can't prepend ops to this expression"); + if (EntryValue) { + Ops.push_back(dwarf::DW_OP_entry_value); + // Add size info needed for entry value expression. + // Add plus one for target register operand. + Ops.push_back(Expr->getNumElements() + 1); + } + // If there are no ops to prepend, do not even add the DW_OP_stack_value. if (Ops.empty()) StackValue = false; |