diff options
| author | 2018-04-06 14:26:03 +0000 | |
|---|---|---|
| committer | 2018-04-06 14:26:03 +0000 | |
| commit | bdabc2f19ffb9e20600dad6e8a300842a7bda50e (patch) | |
| tree | c50e7b2e5449b074651bb82a58517a8ebc4a8cf7 /gnu/llvm/lib/IR/DebugInfoMetadata.cpp | |
| parent | Print a 'p' flag for file descriptors that were opened after pledge(2). (diff) | |
| download | wireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.tar.xz wireguard-openbsd-bdabc2f19ffb9e20600dad6e8a300842a7bda50e.zip | |
Import LLVM 6.0.1 release including clang, lld and lldb.
"where is the kaboom?" deraadt@
Diffstat (limited to 'gnu/llvm/lib/IR/DebugInfoMetadata.cpp')
| -rw-r--r-- | gnu/llvm/lib/IR/DebugInfoMetadata.cpp | 113 |
1 files changed, 104 insertions, 9 deletions
diff --git a/gnu/llvm/lib/IR/DebugInfoMetadata.cpp b/gnu/llvm/lib/IR/DebugInfoMetadata.cpp index c14940bad45..75ddd47b259 100644 --- a/gnu/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/gnu/llvm/lib/IR/DebugInfoMetadata.cpp @@ -14,9 +14,11 @@ #include "llvm/IR/DebugInfoMetadata.h" #include "LLVMContextImpl.h" #include "MetadataImpl.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/IR/DIBuilder.h" #include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" using namespace llvm; @@ -66,6 +68,31 @@ DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line, Storage, Context.pImpl->DILocations); } +const DILocation * +DILocation::getMergedLocation(const DILocation *LocA, const DILocation *LocB, + const Instruction *ForInst) { + if (!LocA || !LocB) + return nullptr; + + if (LocA == LocB || !LocA->canDiscriminate(*LocB)) + return LocA; + + if (!dyn_cast_or_null<CallInst>(ForInst)) + return nullptr; + + SmallPtrSet<DILocation *, 5> InlinedLocationsA; + for (DILocation *L = LocA->getInlinedAt(); L; L = L->getInlinedAt()) + InlinedLocationsA.insert(L); + const DILocation *Result = LocB; + for (DILocation *L = LocB->getInlinedAt(); L; L = L->getInlinedAt()) { + Result = L; + if (InlinedLocationsA.count(L)) + break; + } + return DILocation::get(Result->getContext(), 0, 0, Result->getScope(), + Result->getInlinedAt()); +} + DINode::DIFlags DINode::getFlag(StringRef Flag) { return StringSwitch<DIFlags>(Flag) #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME) @@ -354,6 +381,8 @@ DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags, DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops); } +// FIXME: Implement this string-enum correspondence with a .def file and macros, +// so that the association is explicit rather than implied. static const char *ChecksumKindName[DIFile::CSK_Last + 1] = { "CSK_None", "CSK_MD5", @@ -391,7 +420,7 @@ DICompileUnit *DICompileUnit::getImpl( unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, - StorageType Storage, bool ShouldCreate) { + bool GnuPubnames, StorageType Storage, bool ShouldCreate) { assert(Storage != Uniqued && "Cannot unique DICompileUnit"); assert(isCanonical(Producer) && "Expected canonical MDString"); assert(isCanonical(Flags) && "Expected canonical MDString"); @@ -401,11 +430,10 @@ DICompileUnit *DICompileUnit::getImpl( File, Producer, Flags, SplitDebugFilename, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros}; - return storeImpl(new (array_lengthof(Ops)) - DICompileUnit(Context, Storage, SourceLanguage, - IsOptimized, RuntimeVersion, EmissionKind, - DWOId, SplitDebugInlining, - DebugInfoForProfiling, Ops), + return storeImpl(new (array_lengthof(Ops)) DICompileUnit( + Context, Storage, SourceLanguage, IsOptimized, + RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining, + DebugInfoForProfiling, GnuPubnames, Ops), Storage); } @@ -586,6 +614,29 @@ DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops); } +Optional<uint64_t> DIVariable::getSizeInBits() const { + // This is used by the Verifier so be mindful of broken types. + const Metadata *RawType = getRawType(); + while (RawType) { + // Try to get the size directly. + if (auto *T = dyn_cast<DIType>(RawType)) + if (uint64_t Size = T->getSizeInBits()) + return Size; + + if (auto *DT = dyn_cast<DIDerivedType>(RawType)) { + // Look at the base type. + RawType = DT->getRawBaseType(); + continue; + } + + // Missing type or size. + break; + } + + // Fail gracefully. + return None; +} + DIExpression *DIExpression::getImpl(LLVMContext &Context, ArrayRef<uint64_t> Elements, StorageType Storage, bool ShouldCreate) { @@ -643,6 +694,7 @@ bool DIExpression::isValid() const { case dwarf::DW_OP_plus_uconst: case dwarf::DW_OP_plus: case dwarf::DW_OP_minus: + case dwarf::DW_OP_mul: case dwarf::DW_OP_deref: case dwarf::DW_OP_xderef: break; @@ -698,12 +750,17 @@ bool DIExpression::extractIfOffset(int64_t &Offset) const { return false; } -DIExpression *DIExpression::prepend(const DIExpression *Expr, bool Deref, - int64_t Offset, bool StackValue) { +DIExpression *DIExpression::prepend(const DIExpression *Expr, bool DerefBefore, + int64_t Offset, bool DerefAfter, + bool StackValue) { SmallVector<uint64_t, 8> Ops; + if (DerefBefore) + Ops.push_back(dwarf::DW_OP_deref); + appendOffset(Ops, Offset); - if (Deref) + if (DerefAfter) Ops.push_back(dwarf::DW_OP_deref); + if (Expr) for (auto Op : Expr->expr_ops()) { // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment. @@ -724,6 +781,44 @@ DIExpression *DIExpression::prepend(const DIExpression *Expr, bool Deref, return DIExpression::get(Expr->getContext(), Ops); } +Optional<DIExpression *> DIExpression::createFragmentExpression( + const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) { + SmallVector<uint64_t, 8> Ops; + // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment. + if (Expr) { + for (auto Op : Expr->expr_ops()) { + switch (Op.getOp()) { + default: break; + case dwarf::DW_OP_plus: + case dwarf::DW_OP_minus: + // We can't safely split arithmetic into multiple fragments because we + // can't express carry-over between fragments. + // + // FIXME: We *could* preserve the lowest fragment of a constant offset + // operation if the offset fits into SizeInBits. + return None; + case dwarf::DW_OP_LLVM_fragment: { + // Make the new offset point into the existing fragment. + uint64_t FragmentOffsetInBits = Op.getArg(0); + // Op.getArg(0) is FragmentOffsetInBits. + // Op.getArg(1) is FragmentSizeInBits. + assert((OffsetInBits + SizeInBits <= Op.getArg(0) + Op.getArg(1)) && + "new fragment outside of original fragment"); + OffsetInBits += FragmentOffsetInBits; + continue; + } + } + Ops.push_back(Op.getOp()); + for (unsigned I = 0; I < Op.getNumArgs(); ++I) + Ops.push_back(Op.getArg(I)); + } + } + Ops.push_back(dwarf::DW_OP_LLVM_fragment); + Ops.push_back(OffsetInBits); + Ops.push_back(SizeInBits); + return DIExpression::get(Expr->getContext(), Ops); +} + bool DIExpression::isConstant() const { // Recognize DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment Len Ofs)?. if (getNumElements() != 3 && getNumElements() != 6) |
