diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -2078,8 +2078,15 @@ case bitc::METADATA_ARG_LIST: { SmallVector Elts; Elts.reserve(Record.size()); - for (uint64_t Elt : Record) - Elts.push_back(dyn_cast_or_null(getMDOrNull(Elt))); + for (uint64_t Elt : Record) { + Metadata *MD = getMD(Elt); + if (isa(MD) && cast(MD)->isTemporary()) + return error( + "Invalid record: DIArgList should not contain forward refs"); + if (!isa(MD)) + return error("Invalid record"); + Elts.push_back(cast(MD)); + } MetadataList.assignValue(DIArgList::get(Context, Elts), NextMetadataNo); NextMetadataNo++; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1876,7 +1876,7 @@ unsigned Abbrev) { Record.reserve(N->getArgs().size()); for (ValueAsMetadata *MD : N->getArgs()) - Record.push_back(VE.getMetadataOrNullID(MD)); + Record.push_back(VE.getMetadataID(MD)); Stream.EmitRecord(bitc::METADATA_ARG_LIST, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -27,6 +27,7 @@ class BasicBlock; class Comdat; +class DIArgList; class Function; class Instruction; class LocalAsMetadata; @@ -286,6 +287,9 @@ void EnumerateFunctionLocalMetadata(const Function &F, const LocalAsMetadata *Local); void EnumerateFunctionLocalMetadata(unsigned F, const LocalAsMetadata *Local); + void EnumerateFunctionLocalListMetadata(const Function &F, + const DIArgList *ArgList); + void EnumerateFunctionLocalListMetadata(unsigned F, const DIArgList *Arglist); void EnumerateNamedMDNode(const NamedMDNode *NMD); void EnumerateValue(const Value *V); void EnumerateType(Type *T); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -620,6 +620,11 @@ EnumerateFunctionLocalMetadata(getMetadataFunctionID(&F), Local); } +void ValueEnumerator::EnumerateFunctionLocalListMetadata( + const Function &F, const DIArgList *ArgList) { + EnumerateFunctionLocalListMetadata(getMetadataFunctionID(&F), ArgList); +} + void ValueEnumerator::dropFunctionFromMetadata( MetadataMapType::value_type &FirstMD) { SmallVector Worklist; @@ -730,7 +735,7 @@ return nullptr; } -/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata +/// EnumerateFunctionLocalMetadata - Incorporate function-local metadata /// information reachable from the metadata. void ValueEnumerator::EnumerateFunctionLocalMetadata( unsigned F, const LocalAsMetadata *Local) { @@ -750,6 +755,37 @@ EnumerateValue(Local->getValue()); } +/// EnumerateFunctionLocalListMetadata - Incorporate function-local metadata +/// information reachable from the metadata. +void ValueEnumerator::EnumerateFunctionLocalListMetadata( + unsigned F, const DIArgList *ArgList) { + assert(F && "Expected a function"); + + // Check to see if it's already in! + MDIndex &Index = MetadataMap[ArgList]; + if (Index.ID) { + assert(Index.F == F && "Expected the same function"); + return; + } + + for (ValueAsMetadata *Value : ArgList->getArgs()) { + if (isa(Value)) { + assert(MetadataMap.count(Value) && + "LocalAsMetadata should be enumerated before DIArgList"); + assert(MetadataMap[Value].F == F && + "Expected LocalAsMetadata in the same function"); + } else { + assert(isa(Value) && + "Expected LocalAsMetadata or ConstantAsMetadata"); + EnumerateMetadata(F, Value); + } + } + + MDs.push_back(ArgList); + Index.F = F; + Index.ID = MDs.size(); +} + static unsigned getMetadataTypeOrder(const Metadata *MD) { // Strings are emitted in bulk and must come first. if (isa(MD)) @@ -1072,7 +1108,7 @@ // DIArgList entries must come after function-local metadata, as it is not // possible to forward-reference them. for (const DIArgList *ArgList : ArgListMDVector) - EnumerateMetadata(&F, ArgList); + EnumerateFunctionLocalListMetadata(F, ArgList); } void ValueEnumerator::purgeFunction() {