llvm-mirror/lib/Bitcode/Reader/MetadataLoader.cpp
Mehdi Amini e855efa296 MetadataLoader: replace the tracking of ForwardReferences and UnresolvedNodes with a set-based solution (NFC)
This makes it explicit what is the exact list to handle, and it
looks much more easy to manipulate and understand that the
previous custom tracking of min/max to express the range where
to look for.

Differential Revision: https://reviews.llvm.org/D28089

llvm-svn: 290507
2016-12-25 04:22:54 +00:00

1395 lines
47 KiB
C++

//===- MetadataLoader.cpp - Internal BitcodeReader implementation ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MetadataLoader.h"
#include "ValueList.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Comdat.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/TrackingMDRef.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <limits>
#include <map>
#include <memory>
#include <string>
#include <system_error>
#include <tuple>
#include <utility>
#include <vector>
using namespace llvm;
/// Flag whether we need to import full type definitions for ThinLTO.
/// Currently needed for Darwin and LLDB.
static cl::opt<bool> ImportFullTypeDefinitions(
"import-full-type-definitions", cl::init(false), cl::Hidden,
cl::desc("Import full type definitions for ThinLTO."));
namespace {
static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
class BitcodeReaderMetadataList {
/// Array of metadata references.
///
/// Don't use std::vector here. Some versions of libc++ copy (instead of
/// move) on resize, and TrackingMDRef is very expensive to copy.
SmallVector<TrackingMDRef, 1> MetadataPtrs;
/// The set of indices in MetadataPtrs above of forward references that were
/// generated.
SmallDenseSet<unsigned, 1> ForwardReference;
/// The set of indices in MetadataPtrs above of Metadata that need to be
/// resolved.
SmallDenseSet<unsigned, 1> UnresolvedNodes;
/// Structures for resolving old type refs.
struct {
SmallDenseMap<MDString *, TempMDTuple, 1> Unknown;
SmallDenseMap<MDString *, DICompositeType *, 1> Final;
SmallDenseMap<MDString *, DICompositeType *, 1> FwdDecls;
SmallVector<std::pair<TrackingMDRef, TempMDTuple>, 1> Arrays;
} OldTypeRefs;
LLVMContext &Context;
public:
BitcodeReaderMetadataList(LLVMContext &C) : Context(C) {}
// vector compatibility methods
unsigned size() const { return MetadataPtrs.size(); }
void resize(unsigned N) { MetadataPtrs.resize(N); }
void push_back(Metadata *MD) { MetadataPtrs.emplace_back(MD); }
void clear() { MetadataPtrs.clear(); }
Metadata *back() const { return MetadataPtrs.back(); }
void pop_back() { MetadataPtrs.pop_back(); }
bool empty() const { return MetadataPtrs.empty(); }
Metadata *operator[](unsigned i) const {
assert(i < MetadataPtrs.size());
return MetadataPtrs[i];
}
Metadata *lookup(unsigned I) const {
if (I < MetadataPtrs.size())
return MetadataPtrs[I];
return nullptr;
}
void shrinkTo(unsigned N) {
assert(N <= size() && "Invalid shrinkTo request!");
assert(ForwardReference.empty() && "Unexpected forward refs");
assert(UnresolvedNodes.empty() && "Unexpected unresolved node");
MetadataPtrs.resize(N);
}
/// Return the given metadata, creating a replaceable forward reference if
/// necessary.
Metadata *getMetadataFwdRef(unsigned Idx);
/// Return the the given metadata only if it is fully resolved.
///
/// Gives the same result as \a lookup(), unless \a MDNode::isResolved()
/// would give \c false.
Metadata *getMetadataIfResolved(unsigned Idx);
MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
void assignValue(Metadata *MD, unsigned Idx);
void tryToResolveCycles();
bool hasFwdRefs() const { return !ForwardReference.empty(); }
/// Upgrade a type that had an MDString reference.
void addTypeRef(MDString &UUID, DICompositeType &CT);
/// Upgrade a type that had an MDString reference.
Metadata *upgradeTypeRef(Metadata *MaybeUUID);
/// Upgrade a type ref array that may have MDString references.
Metadata *upgradeTypeRefArray(Metadata *MaybeTuple);
private:
Metadata *resolveTypeRefArray(Metadata *MaybeTuple);
};
void BitcodeReaderMetadataList::assignValue(Metadata *MD, unsigned Idx) {
if (auto *MDN = dyn_cast<MDNode>(MD))
if (!MDN->isResolved())
UnresolvedNodes.insert(Idx);
if (Idx == size()) {
push_back(MD);
return;
}
if (Idx >= size())
resize(Idx + 1);
TrackingMDRef &OldMD = MetadataPtrs[Idx];
if (!OldMD) {
OldMD.reset(MD);
return;
}
// If there was a forward reference to this value, replace it.
TempMDTuple PrevMD(cast<MDTuple>(OldMD.get()));
PrevMD->replaceAllUsesWith(MD);
ForwardReference.erase(Idx);
}
Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) {
if (Idx >= size())
resize(Idx + 1);
if (Metadata *MD = MetadataPtrs[Idx])
return MD;
// Track forward refs to be resolved later.
ForwardReference.insert(Idx);
// Create and return a placeholder, which will later be RAUW'd.
Metadata *MD = MDNode::getTemporary(Context, None).release();
MetadataPtrs[Idx].reset(MD);
return MD;
}
Metadata *BitcodeReaderMetadataList::getMetadataIfResolved(unsigned Idx) {
Metadata *MD = lookup(Idx);
if (auto *N = dyn_cast_or_null<MDNode>(MD))
if (!N->isResolved())
return nullptr;
return MD;
}
MDNode *BitcodeReaderMetadataList::getMDNodeFwdRefOrNull(unsigned Idx) {
return dyn_cast_or_null<MDNode>(getMetadataFwdRef(Idx));
}
void BitcodeReaderMetadataList::tryToResolveCycles() {
if (!ForwardReference.empty())
// Still forward references... can't resolve cycles.
return;
// Give up on finding a full definition for any forward decls that remain.
for (const auto &Ref : OldTypeRefs.FwdDecls)
OldTypeRefs.Final.insert(Ref);
OldTypeRefs.FwdDecls.clear();
// Upgrade from old type ref arrays. In strange cases, this could add to
// OldTypeRefs.Unknown.
for (const auto &Array : OldTypeRefs.Arrays)
Array.second->replaceAllUsesWith(resolveTypeRefArray(Array.first.get()));
OldTypeRefs.Arrays.clear();
// Replace old string-based type refs with the resolved node, if possible.
// If we haven't seen the node, leave it to the verifier to complain about
// the invalid string reference.
for (const auto &Ref : OldTypeRefs.Unknown) {
if (DICompositeType *CT = OldTypeRefs.Final.lookup(Ref.first))
Ref.second->replaceAllUsesWith(CT);
else
Ref.second->replaceAllUsesWith(Ref.first);
}
OldTypeRefs.Unknown.clear();
if (UnresolvedNodes.empty())
// Nothing to do.
return;
// Resolve any cycles.
for (unsigned I : UnresolvedNodes) {
auto &MD = MetadataPtrs[I];
auto *N = dyn_cast_or_null<MDNode>(MD);
if (!N)
continue;
assert(!N->isTemporary() && "Unexpected forward reference");
N->resolveCycles();
}
// Make sure we return early again until there's another unresolved ref.
UnresolvedNodes.clear();
}
void BitcodeReaderMetadataList::addTypeRef(MDString &UUID,
DICompositeType &CT) {
assert(CT.getRawIdentifier() == &UUID && "Mismatched UUID");
if (CT.isForwardDecl())
OldTypeRefs.FwdDecls.insert(std::make_pair(&UUID, &CT));
else
OldTypeRefs.Final.insert(std::make_pair(&UUID, &CT));
}
Metadata *BitcodeReaderMetadataList::upgradeTypeRef(Metadata *MaybeUUID) {
auto *UUID = dyn_cast_or_null<MDString>(MaybeUUID);
if (LLVM_LIKELY(!UUID))
return MaybeUUID;
if (auto *CT = OldTypeRefs.Final.lookup(UUID))
return CT;
auto &Ref = OldTypeRefs.Unknown[UUID];
if (!Ref)
Ref = MDNode::getTemporary(Context, None);
return Ref.get();
}
Metadata *BitcodeReaderMetadataList::upgradeTypeRefArray(Metadata *MaybeTuple) {
auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
if (!Tuple || Tuple->isDistinct())
return MaybeTuple;
// Look through the array immediately if possible.
if (!Tuple->isTemporary())
return resolveTypeRefArray(Tuple);
// Create and return a placeholder to use for now. Eventually
// resolveTypeRefArrays() will be resolve this forward reference.
OldTypeRefs.Arrays.emplace_back(
std::piecewise_construct, std::forward_as_tuple(Tuple),
std::forward_as_tuple(MDTuple::getTemporary(Context, None)));
return OldTypeRefs.Arrays.back().second.get();
}
Metadata *BitcodeReaderMetadataList::resolveTypeRefArray(Metadata *MaybeTuple) {
auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
if (!Tuple || Tuple->isDistinct())
return MaybeTuple;
// Look through the DITypeRefArray, upgrading each DITypeRef.
SmallVector<Metadata *, 32> Ops;
Ops.reserve(Tuple->getNumOperands());
for (Metadata *MD : Tuple->operands())
Ops.push_back(upgradeTypeRef(MD));
return MDTuple::get(Context, Ops);
}
namespace {
class PlaceholderQueue {
// Placeholders would thrash around when moved, so store in a std::deque
// instead of some sort of vector.
std::deque<DistinctMDOperandPlaceholder> PHs;
public:
DistinctMDOperandPlaceholder &getPlaceholderOp(unsigned ID);
void flush(BitcodeReaderMetadataList &MetadataList);
};
} // end anonymous namespace
DistinctMDOperandPlaceholder &PlaceholderQueue::getPlaceholderOp(unsigned ID) {
PHs.emplace_back(ID);
return PHs.back();
}
void PlaceholderQueue::flush(BitcodeReaderMetadataList &MetadataList) {
while (!PHs.empty()) {
auto *MD = MetadataList.lookup(PHs.front().getID());
assert(MD && "Flushing placeholder on unassigned MD");
#ifndef NDEBUG
if (auto *MDN = dyn_cast<MDNode>(MD))
assert(MDN->isResolved() &&
"Flushing Placeholder while cycles aren't resolved");
#endif
PHs.front().replaceUseWith(MD);
PHs.pop_front();
}
}
} // anonynous namespace
class MetadataLoader::MetadataLoaderImpl {
BitcodeReaderMetadataList MetadataList;
BitcodeReaderValueList &ValueList;
BitstreamCursor &Stream;
LLVMContext &Context;
Module &TheModule;
std::function<Type *(unsigned)> getTypeByID;
// Keep mapping of seens pair of old-style CU <-> SP, and update pointers to
// point from SP to CU after a block is completly parsed.
std::vector<std::pair<DICompileUnit *, Metadata *>> CUSubprograms;
/// Functions that need to be matched with subprograms when upgrading old
/// metadata.
SmallDenseMap<Function *, DISubprogram *, 16> FunctionsWithSPs;
// Map the bitcode's custom MDKind ID to the Module's MDKind ID.
DenseMap<unsigned, unsigned> MDKindMap;
bool StripTBAA = false;
bool HasSeenOldLoopTags = false;
/// True if metadata is being parsed for a module being ThinLTO imported.
bool IsImporting = false;
Error parseOneMetadata(SmallVectorImpl<uint64_t> &Record, unsigned Code,
PlaceholderQueue &Placeholders, StringRef Blob,
bool ModuleLevel, unsigned &NextMetadataNo);
Error parseMetadataStrings(ArrayRef<uint64_t> Record, StringRef Blob,
unsigned &NextMetadataNo);
Error parseGlobalObjectAttachment(GlobalObject &GO,
ArrayRef<uint64_t> Record);
Error parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
public:
MetadataLoaderImpl(BitstreamCursor &Stream, Module &TheModule,
BitcodeReaderValueList &ValueList,
std::function<Type *(unsigned)> getTypeByID,
bool IsImporting)
: MetadataList(TheModule.getContext()), ValueList(ValueList),
Stream(Stream), Context(TheModule.getContext()), TheModule(TheModule),
getTypeByID(getTypeByID), IsImporting(IsImporting) {}
Error parseMetadata(bool ModuleLevel);
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
Metadata *getMetadataFwdRef(unsigned Idx) {
return MetadataList.getMetadataFwdRef(Idx);
}
MDNode *getMDNodeFwdRefOrNull(unsigned Idx) {
return MetadataList.getMDNodeFwdRefOrNull(Idx);
}
DISubprogram *lookupSubprogramForFunction(Function *F) {
return FunctionsWithSPs.lookup(F);
}
bool hasSeenOldLoopTags() { return HasSeenOldLoopTags; }
Error parseMetadataAttachment(
Function &F, const SmallVectorImpl<Instruction *> &InstructionList);
Error parseMetadataKinds();
void setStripTBAA(bool Value) { StripTBAA = Value; }
bool isStrippingTBAA() { return StripTBAA; }
unsigned size() const { return MetadataList.size(); }
void shrinkTo(unsigned N) { MetadataList.shrinkTo(N); }
};
Error error(const Twine &Message) {
return make_error<StringError>(
Message, make_error_code(BitcodeError::CorruptedBitcode));
}
/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
/// module level metadata.
Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
if (!ModuleLevel && MetadataList.hasFwdRefs())
return error("Invalid metadata: fwd refs into function blocks");
if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
return error("Invalid record");
unsigned NextMetadataNo = MetadataList.size();
SmallVector<uint64_t, 64> Record;
PlaceholderQueue Placeholders;
// Read all the records.
while (true) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
return error("Malformed block");
case BitstreamEntry::EndBlock:
// Upgrade old-style CU <-> SP pointers to point from SP to CU.
for (auto CU_SP : CUSubprograms)
if (auto *SPs = dyn_cast_or_null<MDTuple>(CU_SP.second))
for (auto &Op : SPs->operands())
if (auto *SP = dyn_cast_or_null<MDNode>(Op))
SP->replaceOperandWith(7, CU_SP.first);
CUSubprograms.clear();
MetadataList.tryToResolveCycles();
Placeholders.flush(MetadataList);
return Error::success();
case BitstreamEntry::Record:
// The interesting case.
break;
}
// Read a record.
Record.clear();
StringRef Blob;
unsigned Code = Stream.readRecord(Entry.ID, Record, &Blob);
if (Error Err = parseOneMetadata(Record, Code, Placeholders, Blob,
ModuleLevel, NextMetadataNo))
return Err;
}
}
Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
SmallVectorImpl<uint64_t> &Record, unsigned Code,
PlaceholderQueue &Placeholders, StringRef Blob, bool ModuleLevel,
unsigned &NextMetadataNo) {
bool IsDistinct = false;
auto getMD = [&](unsigned ID) -> Metadata * {
if (!IsDistinct)
return MetadataList.getMetadataFwdRef(ID);
if (auto *MD = MetadataList.getMetadataIfResolved(ID))
return MD;
return &Placeholders.getPlaceholderOp(ID);
};
auto getMDOrNull = [&](unsigned ID) -> Metadata * {
if (ID)
return getMD(ID - 1);
return nullptr;
};
auto getMDOrNullWithoutPlaceholders = [&](unsigned ID) -> Metadata * {
if (ID)
return MetadataList.getMetadataFwdRef(ID - 1);
return nullptr;
};
auto getMDString = [&](unsigned ID) -> MDString * {
// This requires that the ID is not really a forward reference. In
// particular, the MDString must already have been resolved.
return cast_or_null<MDString>(getMDOrNull(ID));
};
// Support for old type refs.
auto getDITypeRefOrNull = [&](unsigned ID) {
return MetadataList.upgradeTypeRef(getMDOrNull(ID));
};
#define GET_OR_DISTINCT(CLASS, ARGS) \
(IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
switch (Code) {
default: // Default behavior: ignore.
break;
case bitc::METADATA_NAME: {
// Read name of the named metadata.
SmallString<8> Name(Record.begin(), Record.end());
Record.clear();
Code = Stream.ReadCode();
unsigned NextBitCode = Stream.readRecord(Code, Record);
if (NextBitCode != bitc::METADATA_NAMED_NODE)
return error("METADATA_NAME not followed by METADATA_NAMED_NODE");
// Read named metadata elements.
unsigned Size = Record.size();
NamedMDNode *NMD = TheModule.getOrInsertNamedMetadata(Name);
for (unsigned i = 0; i != Size; ++i) {
MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[i]);
if (!MD)
return error("Invalid record");
NMD->addOperand(MD);
}
break;
}
case bitc::METADATA_OLD_FN_NODE: {
// FIXME: Remove in 4.0.
// This is a LocalAsMetadata record, the only type of function-local
// metadata.
if (Record.size() % 2 == 1)
return error("Invalid record");
// If this isn't a LocalAsMetadata record, we're dropping it. This used
// to be legal, but there's no upgrade path.
auto dropRecord = [&] {
MetadataList.assignValue(MDNode::get(Context, None), NextMetadataNo++);
};
if (Record.size() != 2) {
dropRecord();
break;
}
Type *Ty = getTypeByID(Record[0]);
if (Ty->isMetadataTy() || Ty->isVoidTy()) {
dropRecord();
break;
}
MetadataList.assignValue(
LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
NextMetadataNo++);
break;
}
case bitc::METADATA_OLD_NODE: {
// FIXME: Remove in 4.0.
if (Record.size() % 2 == 1)
return error("Invalid record");
unsigned Size = Record.size();
SmallVector<Metadata *, 8> Elts;
for (unsigned i = 0; i != Size; i += 2) {
Type *Ty = getTypeByID(Record[i]);
if (!Ty)
return error("Invalid record");
if (Ty->isMetadataTy())
Elts.push_back(getMD(Record[i + 1]));
else if (!Ty->isVoidTy()) {
auto *MD =
ValueAsMetadata::get(ValueList.getValueFwdRef(Record[i + 1], Ty));
assert(isa<ConstantAsMetadata>(MD) &&
"Expected non-function-local metadata");
Elts.push_back(MD);
} else
Elts.push_back(nullptr);
}
MetadataList.assignValue(MDNode::get(Context, Elts), NextMetadataNo++);
break;
}
case bitc::METADATA_VALUE: {
if (Record.size() != 2)
return error("Invalid record");
Type *Ty = getTypeByID(Record[0]);
if (Ty->isMetadataTy() || Ty->isVoidTy())
return error("Invalid record");
MetadataList.assignValue(
ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
NextMetadataNo++);
break;
}
case bitc::METADATA_DISTINCT_NODE:
IsDistinct = true;
LLVM_FALLTHROUGH;
case bitc::METADATA_NODE: {
SmallVector<Metadata *, 8> Elts;
Elts.reserve(Record.size());
for (unsigned ID : Record)
Elts.push_back(getMDOrNull(ID));
MetadataList.assignValue(IsDistinct ? MDNode::getDistinct(Context, Elts)
: MDNode::get(Context, Elts),
NextMetadataNo++);
break;
}
case bitc::METADATA_LOCATION: {
if (Record.size() != 5)
return error("Invalid record");
IsDistinct = Record[0];
unsigned Line = Record[1];
unsigned Column = Record[2];
Metadata *Scope = getMD(Record[3]);
Metadata *InlinedAt = getMDOrNull(Record[4]);
MetadataList.assignValue(
GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt)),
NextMetadataNo++);
break;
}
case bitc::METADATA_GENERIC_DEBUG: {
if (Record.size() < 4)
return error("Invalid record");
IsDistinct = Record[0];
unsigned Tag = Record[1];
unsigned Version = Record[2];
if (Tag >= 1u << 16 || Version != 0)
return error("Invalid record");
auto *Header = getMDString(Record[3]);
SmallVector<Metadata *, 8> DwarfOps;
for (unsigned I = 4, E = Record.size(); I != E; ++I)
DwarfOps.push_back(getMDOrNull(Record[I]));
MetadataList.assignValue(
GET_OR_DISTINCT(GenericDINode, (Context, Tag, Header, DwarfOps)),
NextMetadataNo++);
break;
}
case bitc::METADATA_SUBRANGE: {
if (Record.size() != 3)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DISubrange,
(Context, Record[1], unrotateSign(Record[2]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_ENUMERATOR: {
if (Record.size() != 3)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DIEnumerator, (Context, unrotateSign(Record[1]),
getMDString(Record[2]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_BASIC_TYPE: {
if (Record.size() != 6)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DIBasicType,
(Context, Record[1], getMDString(Record[2]), Record[3],
Record[4], Record[5])),
NextMetadataNo++);
break;
}
case bitc::METADATA_DERIVED_TYPE: {
if (Record.size() != 12)
return error("Invalid record");
IsDistinct = Record[0];
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
MetadataList.assignValue(
GET_OR_DISTINCT(DIDerivedType,
(Context, Record[1], getMDString(Record[2]),
getMDOrNull(Record[3]), Record[4],
getDITypeRefOrNull(Record[5]),
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
Record[9], Flags, getDITypeRefOrNull(Record[11]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_COMPOSITE_TYPE: {
if (Record.size() != 16)
return error("Invalid record");
// If we have a UUID and this is not a forward declaration, lookup the
// mapping.
IsDistinct = Record[0] & 0x1;
bool IsNotUsedInTypeRef = Record[0] >= 2;
unsigned Tag = Record[1];
MDString *Name = getMDString(Record[2]);
Metadata *File = getMDOrNull(Record[3]);
unsigned Line = Record[4];
Metadata *Scope = getDITypeRefOrNull(Record[5]);
Metadata *BaseType = nullptr;
uint64_t SizeInBits = Record[7];
if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
return error("Alignment value is too large");
uint32_t AlignInBits = Record[8];
uint64_t OffsetInBits = 0;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
Metadata *Elements = nullptr;
unsigned RuntimeLang = Record[12];
Metadata *VTableHolder = nullptr;
Metadata *TemplateParams = nullptr;
auto *Identifier = getMDString(Record[15]);
// If this module is being parsed so that it can be ThinLTO imported
// into another module, composite types only need to be imported
// as type declarations (unless full type definitions requested).
// Create type declarations up front to save memory. Also, buildODRType
// handles the case where this is type ODRed with a definition needed
// by the importing module, in which case the existing definition is
// used.
if (IsImporting && !ImportFullTypeDefinitions &&
(Tag == dwarf::DW_TAG_enumeration_type ||
Tag == dwarf::DW_TAG_class_type ||
Tag == dwarf::DW_TAG_structure_type ||
Tag == dwarf::DW_TAG_union_type)) {
Flags = Flags | DINode::FlagFwdDecl;
} else {
BaseType = getDITypeRefOrNull(Record[6]);
OffsetInBits = Record[9];
Elements = getMDOrNull(Record[11]);
VTableHolder = getDITypeRefOrNull(Record[13]);
TemplateParams = getMDOrNull(Record[14]);
}
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
VTableHolder, TemplateParams);
// Create a node if we didn't get a lazy ODR type.
if (!CT)
CT = GET_OR_DISTINCT(DICompositeType,
(Context, Tag, Name, File, Line, Scope, BaseType,
SizeInBits, AlignInBits, OffsetInBits, Flags,
Elements, RuntimeLang, VTableHolder, TemplateParams,
Identifier));
if (!IsNotUsedInTypeRef && Identifier)
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
MetadataList.assignValue(CT, NextMetadataNo++);
break;
}
case bitc::METADATA_SUBROUTINE_TYPE: {
if (Record.size() < 3 || Record.size() > 4)
return error("Invalid record");
bool IsOldTypeRefArray = Record[0] < 2;
unsigned CC = (Record.size() > 3) ? Record[3] : 0;
IsDistinct = Record[0] & 0x1;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[1]);
Metadata *Types = getMDOrNull(Record[2]);
if (LLVM_UNLIKELY(IsOldTypeRefArray))
Types = MetadataList.upgradeTypeRefArray(Types);
MetadataList.assignValue(
GET_OR_DISTINCT(DISubroutineType, (Context, Flags, CC, Types)),
NextMetadataNo++);
break;
}
case bitc::METADATA_MODULE: {
if (Record.size() != 6)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DIModule,
(Context, getMDOrNull(Record[1]),
getMDString(Record[2]), getMDString(Record[3]),
getMDString(Record[4]), getMDString(Record[5]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_FILE: {
if (Record.size() != 3)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(
DIFile, (Context, getMDString(Record[1]), getMDString(Record[2]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_COMPILE_UNIT: {
if (Record.size() < 14 || Record.size() > 17)
return error("Invalid record");
// Ignore Record[0], which indicates whether this compile unit is
// distinct. It's always distinct.
IsDistinct = true;
auto *CU = DICompileUnit::getDistinct(
Context, Record[1], getMDOrNull(Record[2]), getMDString(Record[3]),
Record[4], getMDString(Record[5]), Record[6], getMDString(Record[7]),
Record[8], getMDOrNull(Record[9]), getMDOrNull(Record[10]),
getMDOrNull(Record[12]), getMDOrNull(Record[13]),
Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]),
Record.size() <= 14 ? 0 : Record[14],
Record.size() <= 16 ? true : Record[16]);
MetadataList.assignValue(CU, NextMetadataNo++);
// Move the Upgrade the list of subprograms.
if (Metadata *SPs = getMDOrNullWithoutPlaceholders(Record[11]))
CUSubprograms.push_back({CU, SPs});
break;
}
case bitc::METADATA_SUBPROGRAM: {
if (Record.size() < 18 || Record.size() > 20)
return error("Invalid record");
IsDistinct =
(Record[0] & 1) || Record[8]; // All definitions should be distinct.
// Version 1 has a Function as Record[15].
// Version 2 has removed Record[15].
// Version 3 has the Unit as Record[15].
// Version 4 added thisAdjustment.
bool HasUnit = Record[0] >= 2;
if (HasUnit && Record.size() < 19)
return error("Invalid record");
Metadata *CUorFn = getMDOrNull(Record[15]);
unsigned Offset = Record.size() >= 19 ? 1 : 0;
bool HasFn = Offset && !HasUnit;
bool HasThisAdj = Record.size() >= 20;
DISubprogram *SP = GET_OR_DISTINCT(
DISubprogram, (Context,
getDITypeRefOrNull(Record[1]), // scope
getMDString(Record[2]), // name
getMDString(Record[3]), // linkageName
getMDOrNull(Record[4]), // file
Record[5], // line
getMDOrNull(Record[6]), // type
Record[7], // isLocal
Record[8], // isDefinition
Record[9], // scopeLine
getDITypeRefOrNull(Record[10]), // containingType
Record[11], // virtuality
Record[12], // virtualIndex
HasThisAdj ? Record[19] : 0, // thisAdjustment
static_cast<DINode::DIFlags>(Record[13] // flags
),
Record[14], // isOptimized
HasUnit ? CUorFn : nullptr, // unit
getMDOrNull(Record[15 + Offset]), // templateParams
getMDOrNull(Record[16 + Offset]), // declaration
getMDOrNull(Record[17 + Offset]) // variables
));
MetadataList.assignValue(SP, NextMetadataNo++);
// Upgrade sp->function mapping to function->sp mapping.
if (HasFn) {
if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(CUorFn))
if (auto *F = dyn_cast<Function>(CMD->getValue())) {
if (F->isMaterializable())
// Defer until materialized; unmaterialized functions may not have
// metadata.
FunctionsWithSPs[F] = SP;
else if (!F->empty())
F->setSubprogram(SP);
}
}
break;
}
case bitc::METADATA_LEXICAL_BLOCK: {
if (Record.size() != 5)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DILexicalBlock,
(Context, getMDOrNull(Record[1]),
getMDOrNull(Record[2]), Record[3], Record[4])),
NextMetadataNo++);
break;
}
case bitc::METADATA_LEXICAL_BLOCK_FILE: {
if (Record.size() != 4)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DILexicalBlockFile,
(Context, getMDOrNull(Record[1]),
getMDOrNull(Record[2]), Record[3])),
NextMetadataNo++);
break;
}
case bitc::METADATA_NAMESPACE: {
if (Record.size() != 5)
return error("Invalid record");
IsDistinct = Record[0] & 1;
bool ExportSymbols = Record[0] & 2;
MetadataList.assignValue(
GET_OR_DISTINCT(DINamespace,
(Context, getMDOrNull(Record[1]),
getMDOrNull(Record[2]), getMDString(Record[3]),
Record[4], ExportSymbols)),
NextMetadataNo++);
break;
}
case bitc::METADATA_MACRO: {
if (Record.size() != 5)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DIMacro,
(Context, Record[1], Record[2], getMDString(Record[3]),
getMDString(Record[4]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_MACRO_FILE: {
if (Record.size() != 5)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DIMacroFile,
(Context, Record[1], Record[2], getMDOrNull(Record[3]),
getMDOrNull(Record[4]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_TEMPLATE_TYPE: {
if (Record.size() != 3)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(GET_OR_DISTINCT(DITemplateTypeParameter,
(Context, getMDString(Record[1]),
getDITypeRefOrNull(Record[2]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_TEMPLATE_VALUE: {
if (Record.size() != 5)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DITemplateValueParameter,
(Context, Record[1], getMDString(Record[2]),
getDITypeRefOrNull(Record[3]),
getMDOrNull(Record[4]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_GLOBAL_VAR: {
if (Record.size() < 11 || Record.size() > 12)
return error("Invalid record");
IsDistinct = Record[0] & 1;
unsigned Version = Record[0] >> 1;
if (Version == 1) {
MetadataList.assignValue(
GET_OR_DISTINCT(DIGlobalVariable,
(Context, getMDOrNull(Record[1]),
getMDString(Record[2]), getMDString(Record[3]),
getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
getMDOrNull(Record[10]), Record[11])),
NextMetadataNo++);
} else if (Version == 0) {
// Upgrade old metadata, which stored a global variable reference or a
// ConstantInt here.
Metadata *Expr = getMDOrNull(Record[9]);
uint32_t AlignInBits = 0;
if (Record.size() > 11) {
if (Record[11] > (uint64_t)std::numeric_limits<uint32_t>::max())
return error("Alignment value is too large");
AlignInBits = Record[11];
}
GlobalVariable *Attach = nullptr;
if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
if (auto *GV = dyn_cast<GlobalVariable>(CMD->getValue())) {
Attach = GV;
Expr = nullptr;
} else if (auto *CI = dyn_cast<ConstantInt>(CMD->getValue())) {
Expr = DIExpression::get(Context,
{dwarf::DW_OP_constu, CI->getZExtValue(),
dwarf::DW_OP_stack_value});
} else {
Expr = nullptr;
}
}
DIGlobalVariable *DGV = GET_OR_DISTINCT(
DIGlobalVariable,
(Context, getMDOrNull(Record[1]), getMDString(Record[2]),
getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
getMDOrNull(Record[10]), AlignInBits));
auto *DGVE = DIGlobalVariableExpression::getDistinct(Context, DGV, Expr);
MetadataList.assignValue(DGVE, NextMetadataNo++);
if (Attach)
Attach->addDebugInfo(DGVE);
} else
return error("Invalid record");
break;
}
case bitc::METADATA_LOCAL_VAR: {
// 10th field is for the obseleted 'inlinedAt:' field.
if (Record.size() < 8 || Record.size() > 10)
return error("Invalid record");
IsDistinct = Record[0] & 1;
bool HasAlignment = Record[0] & 2;
// 2nd field used to be an artificial tag, either DW_TAG_auto_variable or
// DW_TAG_arg_variable, if we have alignment flag encoded it means, that
// this is newer version of record which doesn't have artifical tag.
bool HasTag = !HasAlignment && Record.size() > 8;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7 + HasTag]);
uint32_t AlignInBits = 0;
if (HasAlignment) {
if (Record[8 + HasTag] > (uint64_t)std::numeric_limits<uint32_t>::max())
return error("Alignment value is too large");
AlignInBits = Record[8 + HasTag];
}
MetadataList.assignValue(
GET_OR_DISTINCT(DILocalVariable,
(Context, getMDOrNull(Record[1 + HasTag]),
getMDString(Record[2 + HasTag]),
getMDOrNull(Record[3 + HasTag]), Record[4 + HasTag],
getDITypeRefOrNull(Record[5 + HasTag]),
Record[6 + HasTag], Flags, AlignInBits)),
NextMetadataNo++);
break;
}
case bitc::METADATA_EXPRESSION: {
if (Record.size() < 1)
return error("Invalid record");
IsDistinct = Record[0] & 1;
bool HasOpFragment = Record[0] & 2;
auto Elts = MutableArrayRef<uint64_t>(Record).slice(1);
if (!HasOpFragment)
if (unsigned N = Elts.size())
if (N >= 3 && Elts[N - 3] == dwarf::DW_OP_bit_piece)
Elts[N - 3] = dwarf::DW_OP_LLVM_fragment;
MetadataList.assignValue(
GET_OR_DISTINCT(DIExpression, (Context, makeArrayRef(Record).slice(1))),
NextMetadataNo++);
break;
}
case bitc::METADATA_GLOBAL_VAR_EXPR: {
if (Record.size() != 3)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(GET_OR_DISTINCT(DIGlobalVariableExpression,
(Context, getMDOrNull(Record[1]),
getMDOrNull(Record[2]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_OBJC_PROPERTY: {
if (Record.size() != 8)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DIObjCProperty,
(Context, getMDString(Record[1]),
getMDOrNull(Record[2]), Record[3],
getMDString(Record[4]), getMDString(Record[5]),
Record[6], getDITypeRefOrNull(Record[7]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_IMPORTED_ENTITY: {
if (Record.size() != 6)
return error("Invalid record");
IsDistinct = Record[0];
MetadataList.assignValue(
GET_OR_DISTINCT(DIImportedEntity,
(Context, Record[1], getMDOrNull(Record[2]),
getDITypeRefOrNull(Record[3]), Record[4],
getMDString(Record[5]))),
NextMetadataNo++);
break;
}
case bitc::METADATA_STRING_OLD: {
std::string String(Record.begin(), Record.end());
// Test for upgrading !llvm.loop.
HasSeenOldLoopTags |= mayBeOldLoopAttachmentTag(String);
Metadata *MD = MDString::get(Context, String);
MetadataList.assignValue(MD, NextMetadataNo++);
break;
}
case bitc::METADATA_STRINGS:
if (Error Err = parseMetadataStrings(Record, Blob, NextMetadataNo))
return Err;
break;
case bitc::METADATA_GLOBAL_DECL_ATTACHMENT: {
if (Record.size() % 2 == 0)
return error("Invalid record");
unsigned ValueID = Record[0];
if (ValueID >= ValueList.size())
return error("Invalid record");
if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID]))
if (Error Err = parseGlobalObjectAttachment(
*GO, ArrayRef<uint64_t>(Record).slice(1)))
return Err;
break;
}
case bitc::METADATA_KIND: {
// Support older bitcode files that had METADATA_KIND records in a
// block with METADATA_BLOCK_ID.
if (Error Err = parseMetadataKindRecord(Record))
return Err;
break;
}
}
#undef GET_OR_DISTINCT
return Error::success();
}
Error MetadataLoader::MetadataLoaderImpl::parseMetadataStrings(
ArrayRef<uint64_t> Record, StringRef Blob, unsigned &NextMetadataNo) {
// All the MDStrings in the block are emitted together in a single
// record. The strings are concatenated and stored in a blob along with
// their sizes.
if (Record.size() != 2)
return error("Invalid record: metadata strings layout");
unsigned NumStrings = Record[0];
unsigned StringsOffset = Record[1];
if (!NumStrings)
return error("Invalid record: metadata strings with no strings");
if (StringsOffset > Blob.size())
return error("Invalid record: metadata strings corrupt offset");
StringRef Lengths = Blob.slice(0, StringsOffset);
SimpleBitstreamCursor R(Lengths);
StringRef Strings = Blob.drop_front(StringsOffset);
do {
if (R.AtEndOfStream())
return error("Invalid record: metadata strings bad length");
unsigned Size = R.ReadVBR(6);
if (Strings.size() < Size)
return error("Invalid record: metadata strings truncated chars");
MetadataList.assignValue(MDString::get(Context, Strings.slice(0, Size)),
NextMetadataNo++);
Strings = Strings.drop_front(Size);
} while (--NumStrings);
return Error::success();
}
Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment(
GlobalObject &GO, ArrayRef<uint64_t> Record) {
assert(Record.size() % 2 == 0);
for (unsigned I = 0, E = Record.size(); I != E; I += 2) {
auto K = MDKindMap.find(Record[I]);
if (K == MDKindMap.end())
return error("Invalid ID");
MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
if (!MD)
return error("Invalid metadata attachment");
GO.addMetadata(K->second, *MD);
}
return Error::success();
}
/// Parse metadata attachments.
Error MetadataLoader::MetadataLoaderImpl::parseMetadataAttachment(
Function &F, const SmallVectorImpl<Instruction *> &InstructionList) {
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
return error("Invalid record");
SmallVector<uint64_t, 64> Record;
while (true) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
return error("Malformed block");
case BitstreamEntry::EndBlock:
return Error::success();
case BitstreamEntry::Record:
// The interesting case.
break;
}
// Read a metadata attachment record.
Record.clear();
switch (Stream.readRecord(Entry.ID, Record)) {
default: // Default behavior: ignore.
break;
case bitc::METADATA_ATTACHMENT: {
unsigned RecordLength = Record.size();
if (Record.empty())
return error("Invalid record");
if (RecordLength % 2 == 0) {
// A function attachment.
if (Error Err = parseGlobalObjectAttachment(F, Record))
return Err;
continue;
}
// An instruction attachment.
Instruction *Inst = InstructionList[Record[0]];
for (unsigned i = 1; i != RecordLength; i = i + 2) {
unsigned Kind = Record[i];
DenseMap<unsigned, unsigned>::iterator I = MDKindMap.find(Kind);
if (I == MDKindMap.end())
return error("Invalid ID");
if (I->second == LLVMContext::MD_tbaa && StripTBAA)
continue;
Metadata *Node = MetadataList.getMetadataFwdRef(Record[i + 1]);
if (isa<LocalAsMetadata>(Node))
// Drop the attachment. This used to be legal, but there's no
// upgrade path.
break;
MDNode *MD = dyn_cast_or_null<MDNode>(Node);
if (!MD)
return error("Invalid metadata attachment");
if (HasSeenOldLoopTags && I->second == LLVMContext::MD_loop)
MD = upgradeInstructionLoopAttachment(*MD);
if (I->second == LLVMContext::MD_tbaa) {
assert(!MD->isTemporary() && "should load MDs before attachments");
MD = UpgradeTBAANode(*MD);
}
Inst->setMetadata(I->second, MD);
}
break;
}
}
}
}
/// Parse a single METADATA_KIND record, inserting result in MDKindMap.
Error MetadataLoader::MetadataLoaderImpl::parseMetadataKindRecord(
SmallVectorImpl<uint64_t> &Record) {
if (Record.size() < 2)
return error("Invalid record");
unsigned Kind = Record[0];
SmallString<8> Name(Record.begin() + 1, Record.end());
unsigned NewKind = TheModule.getMDKindID(Name.str());
if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second)
return error("Conflicting METADATA_KIND records");
return Error::success();
}
/// Parse the metadata kinds out of the METADATA_KIND_BLOCK.
Error MetadataLoader::MetadataLoaderImpl::parseMetadataKinds() {
if (Stream.EnterSubBlock(bitc::METADATA_KIND_BLOCK_ID))
return error("Invalid record");
SmallVector<uint64_t, 64> Record;
// Read all the records.
while (true) {
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
switch (Entry.Kind) {
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
return error("Malformed block");
case BitstreamEntry::EndBlock:
return Error::success();
case BitstreamEntry::Record:
// The interesting case.
break;
}
// Read a record.
Record.clear();
unsigned Code = Stream.readRecord(Entry.ID, Record);
switch (Code) {
default: // Default behavior: ignore.
break;
case bitc::METADATA_KIND: {
if (Error Err = parseMetadataKindRecord(Record))
return Err;
break;
}
}
}
}
MetadataLoader &MetadataLoader::operator=(MetadataLoader &&RHS) {
Pimpl = std::move(RHS.Pimpl);
return *this;
}
MetadataLoader::MetadataLoader(MetadataLoader &&RHS)
: Pimpl(std::move(RHS.Pimpl)) {}
MetadataLoader::~MetadataLoader() = default;
MetadataLoader::MetadataLoader(BitstreamCursor &Stream, Module &TheModule,
BitcodeReaderValueList &ValueList,
bool IsImporting,
std::function<Type *(unsigned)> getTypeByID)
: Pimpl(llvm::make_unique<MetadataLoaderImpl>(Stream, TheModule, ValueList,
getTypeByID, IsImporting)) {}
Error MetadataLoader::parseMetadata(bool ModuleLevel) {
return Pimpl->parseMetadata(ModuleLevel);
}
bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }
/// Return the given metadata, creating a replaceable forward reference if
/// necessary.
Metadata *MetadataLoader::getMetadataFwdRef(unsigned Idx) {
return Pimpl->getMetadataFwdRef(Idx);
}
MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) {
return Pimpl->getMDNodeFwdRefOrNull(Idx);
}
DISubprogram *MetadataLoader::lookupSubprogramForFunction(Function *F) {
return Pimpl->lookupSubprogramForFunction(F);
}
Error MetadataLoader::parseMetadataAttachment(
Function &F, const SmallVectorImpl<Instruction *> &InstructionList) {
return Pimpl->parseMetadataAttachment(F, InstructionList);
}
Error MetadataLoader::parseMetadataKinds() {
return Pimpl->parseMetadataKinds();
}
void MetadataLoader::setStripTBAA(bool StripTBAA) {
return Pimpl->setStripTBAA(StripTBAA);
}
bool MetadataLoader::isStrippingTBAA() { return Pimpl->isStrippingTBAA(); }
unsigned MetadataLoader::size() const { return Pimpl->size(); }
void MetadataLoader::shrinkTo(unsigned N) { return Pimpl->shrinkTo(N); }