diff options
Diffstat (limited to 'llvm/lib/Bitcode/Reader/MetadataLoader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 1e28411d01e..eb24ac6def1 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -86,6 +86,12 @@ 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; } @@ -399,7 +405,7 @@ public: Stream(Stream), Context(TheModule.getContext()), TheModule(TheModule), getTypeByID(getTypeByID) {} - Error parseMetadata(bool ModuleLevel); + Error parseMetadata(bool ModuleLevel, bool IsImporting); bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); } Metadata *getMetadataFwdRef(unsigned Idx) { @@ -435,7 +441,8 @@ Error error(const Twine &Message) { /// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing /// module level metadata. -Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { +Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel, + bool IsImporting) { if (!ModuleLevel && MetadataList.hasFwdRefs()) return error("Invalid metadata: fwd refs into function blocks"); @@ -709,18 +716,38 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { Metadata *File = getMDOrNull(Record[3]); unsigned Line = Record[4]; Metadata *Scope = getDITypeRefOrNull(Record[5]); - Metadata *BaseType = getDITypeRefOrNull(Record[6]); + 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 = Record[9]; + uint64_t OffsetInBits = 0; DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]); - Metadata *Elements = getMDOrNull(Record[11]); + Metadata *Elements = nullptr; unsigned RuntimeLang = Record[12]; - Metadata *VTableHolder = getDITypeRefOrNull(Record[13]); - Metadata *TemplateParams = getMDOrNull(Record[14]); + 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( @@ -1281,17 +1308,19 @@ MetadataLoader &MetadataLoader::operator=(MetadataLoader &&RHS) { return *this; } MetadataLoader::MetadataLoader(MetadataLoader &&RHS) - : Pimpl(std::move(RHS.Pimpl)) {} + : Pimpl(std::move(RHS.Pimpl)), IsImporting(RHS.IsImporting) {} 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)) {} + getTypeByID)), + IsImporting(IsImporting) {} Error MetadataLoader::parseMetadata(bool ModuleLevel) { - return Pimpl->parseMetadata(ModuleLevel); + return Pimpl->parseMetadata(ModuleLevel, IsImporting); } bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); } |