[llvm] r303577 - Implement various flavors of type merging.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 17:35:40 PDT 2017


No it's due to a patch a few minutes ago.  I have a fix incoming.

On Tue, May 23, 2017 at 5:33 PM Kostya Serebryany <kcc at google.com> wrote:

> Looks like due to this patch:
>
> llvm/tools/llvm-readobj/COFFDumper.cpp:1077:21: error: no matching
> function for call to 'mergeTypeAndIdRecords'
>
>
> On Mon, May 22, 2017 at 2:07 PM, Zachary Turner via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: zturner
>> Date: Mon May 22 16:07:43 2017
>> New Revision: 303577
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=303577&view=rev
>> Log:
>> Implement various flavors of type merging.
>>
>> Previous algotirhm assumed that types and ids are in a single
>> unified stream.  For inputs that come from object files, this
>> is the case.  But if the input is already a PDB, or is the result
>> of a previous merge, then the types and ids will already have
>> been split up, in which case we need an algorithm that can
>> accept operate on independent streams of types and ids that
>> refer across stream boundaries to each other.
>>
>> Differential Revision: https://reviews.llvm.org/D33417
>>
>> Added:
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-1.yaml
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-2.yaml
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-1.yaml
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-2.yaml
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-1.yaml
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-2.yaml
>>     llvm/trunk/test/DebugInfo/PDB/pdbdump-merge-ids-and-types.test
>>     llvm/trunk/test/DebugInfo/PDB/pdbdump-mergeids.test
>> Removed:
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge1.yaml
>>     llvm/trunk/test/DebugInfo/PDB/Inputs/merge2.yaml
>> Modified:
>>     llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
>>     llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h
>>     llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
>>     llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
>>     llvm/trunk/test/DebugInfo/PDB/pdbdump-mergetypes.test
>>     llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
>>     llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h?rev=303577&r1=303576&r2=303577&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h
>> (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h Mon May
>> 22 16:07:43 2017
>> @@ -22,11 +22,74 @@ class TypeIndex;
>>  class TypeServerHandler;
>>  class TypeTableBuilder;
>>
>> -/// Merges one type stream into another. Returns true on success.
>> -Error mergeTypeStreams(TypeTableBuilder &DestIdStream,
>> -                       TypeTableBuilder &DestTypeStream,
>> +/// \brief Merge one set of type records into another.  This method
>> assumes
>> +/// that all records are type records, and there are no Id records
>> present.
>> +///
>> +/// \param Dest The table to store the re-written type records into.
>> +///
>> +/// \param SourceToDest A vector, indexed by the TypeIndex in the source
>> +/// type stream, that contains the index of the corresponding type record
>> +/// in the destination stream.
>> +///
>> +/// \param Handler (optional) If non-null, an interface that gets invoked
>> +/// to handle type server records.
>> +///
>> +/// \param Types The collection of types to merge in.
>> +///
>> +/// \returns Error::success() if the operation succeeded, otherwise an
>> +/// appropriate error code.
>> +Error mergeTypeRecords(TypeTableBuilder &Dest,
>>                         SmallVectorImpl<TypeIndex> &SourceToDest,
>> -                       TypeServerHandler *Handler, const CVTypeArray
>> &Types);
>> +                       TypeServerHandler *Handler, TypeCollection
>> &Types);
>> +
>> +/// \brief Merge one set of id records into another.  This method assumes
>> +/// that all records are id records, and there are no Type records
>> present.
>> +/// However, since Id records can refer back to Type records, this method
>> +/// assumes that the referenced type records have also been merged into
>> +/// another type stream (for example using the above method), and accepts
>> +/// the mapping from source to dest for that stream so that it can
>> re-write
>> +/// the type record mappings accordingly.
>> +///
>> +/// \param Dest The table to store the re-written id records into.
>> +///
>> +/// \param Types The mapping to use for the type records that these id
>> +/// records refer to.
>> +///
>> +/// \param SourceToDest A vector, indexed by the TypeIndex in the source
>> +/// id stream, that contains the index of the corresponding id record
>> +/// in the destination stream.
>> +///
>> +/// \param Types The collection of id records to merge in.
>> +///
>> +/// \returns Error::success() if the operation succeeded, otherwise an
>> +/// appropriate error code.
>> +Error mergeIdRecords(TypeTableBuilder &Dest, ArrayRef<TypeIndex> Types,
>> +                     SmallVectorImpl<TypeIndex> &SourceToDest,
>> +                     TypeCollection &Ids);
>> +
>> +/// \brief Merge a unified set of type and id records, splitting them
>> into
>> +/// separate output streams.
>> +///
>> +/// \param DestIds The table to store the re-written id records into.
>> +///
>> +/// \param DestTypes the table to store the re-written type records into.
>> +///
>> +/// \param SourceToDest A vector, indexed by the TypeIndex in the source
>> +/// id stream, that contains the index of the corresponding id record
>> +/// in the destination stream.
>> +///
>> +/// \param Handler (optional) If non-null, an interface that gets invoked
>> +/// to handle type server records.
>> +///
>> +/// \param IdsAndTypes The collection of id records to merge in.
>> +///
>> +/// \returns Error::success() if the operation succeeded, otherwise an
>> +/// appropriate error code.
>> +Error mergeTypeAndIdRecords(TypeTableBuilder &DestIds,
>> +                            TypeTableBuilder &DestTypes,
>> +                            SmallVectorImpl<TypeIndex> &SourceToDest,
>> +                            TypeServerHandler *Handler,
>> +                            TypeCollection &IdsAndTypes);
>>
>>  } // end namespace codeview
>>  } // end namespace llvm
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h?rev=303577&r1=303576&r2=303577&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/TpiStream.h Mon May 22
>> 16:07:43 2017
>> @@ -21,6 +21,9 @@
>>  #include "llvm/Support/Error.h"
>>
>>  namespace llvm {
>> +namespace codeview {
>> +class LazyRandomTypeCollection;
>> +}
>>  namespace msf {
>>  class MappedBlockStream;
>>  }
>> @@ -53,12 +56,16 @@ public:
>>    codeview::CVTypeRange types(bool *HadError) const;
>>    const codeview::CVTypeArray &typeArray() const { return TypeRecords; }
>>
>> +  codeview::LazyRandomTypeCollection &typeCollection() { return *Types; }
>> +
>>    Error commit();
>>
>>  private:
>>    const PDBFile &Pdb;
>>    std::unique_ptr<msf::MappedBlockStream> Stream;
>>
>> +  std::unique_ptr<codeview::LazyRandomTypeCollection> Types;
>> +
>>    codeview::CVTypeArray TypeRecords;
>>
>>    std::unique_ptr<BinaryStream> HashStream;
>>
>> Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=303577&r1=303576&r2=303577&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp Mon May 22
>> 16:07:43 2017
>> @@ -57,13 +57,11 @@ namespace {
>>  /// looking at the record kind.
>>  class TypeStreamMerger : public TypeVisitorCallbacks {
>>  public:
>> -  TypeStreamMerger(TypeTableBuilder &DestIdStream,
>> -                   TypeTableBuilder &DestTypeStream,
>> -                   SmallVectorImpl<TypeIndex> &SourceToDest,
>> -                   TypeServerHandler *Handler)
>> -      : DestIdStream(DestIdStream), DestTypeStream(DestTypeStream),
>> -        FieldListBuilder(DestTypeStream), Handler(Handler),
>> -        IndexMap(SourceToDest) {}
>> +  explicit TypeStreamMerger(SmallVectorImpl<TypeIndex> &SourceToDest,
>> +                            TypeServerHandler *Handler)
>> +      : Handler(Handler), IndexMap(SourceToDest) {
>> +    SourceToDest.clear();
>> +  }
>>
>>    static const TypeIndex Untranslated;
>>
>> @@ -82,12 +80,22 @@ public:
>>    Error visitTypeEnd(CVType &Record) override;
>>    Error visitMemberEnd(CVMemberRecord &Record) override;
>>
>> -  Error mergeStream(const CVTypeArray &Types);
>> +  Error mergeTypesAndIds(TypeTableBuilder &DestIds, TypeTableBuilder
>> &DestTypes,
>> +                         TypeCollection &IdsAndTypes);
>> +  Error mergeIdRecords(TypeTableBuilder &Dest,
>> +                       ArrayRef<TypeIndex> TypeSourceToDest,
>> +                       TypeCollection &Ids);
>> +  Error mergeTypeRecords(TypeTableBuilder &Dest, TypeCollection &Types);
>>
>>  private:
>> +  Error doit(TypeCollection &Types);
>> +
>>    void addMapping(TypeIndex Idx);
>>
>> -  bool remapIndex(TypeIndex &Idx);
>> +  bool remapTypeIndex(TypeIndex &Idx);
>> +  bool remapItemIndex(TypeIndex &Idx);
>> +
>> +  bool remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map);
>>
>>    size_t slotForIndex(TypeIndex Idx) const {
>>      assert(!Idx.isSimple() && "simple type indices have no slots");
>> @@ -102,7 +110,7 @@ private:
>>    Error writeRecord(RecordType &R, bool RemapSuccess) {
>>      TypeIndex DestIdx = Untranslated;
>>      if (RemapSuccess)
>> -      DestIdx = DestTypeStream.writeKnownType(R);
>> +      DestIdx = DestTypeStream->writeKnownType(R);
>>      addMapping(DestIdx);
>>      return Error::success();
>>    }
>> @@ -111,7 +119,7 @@ private:
>>    Error writeIdRecord(RecordType &R, bool RemapSuccess) {
>>      TypeIndex DestIdx = Untranslated;
>>      if (RemapSuccess)
>> -      DestIdx = DestIdStream.writeKnownType(R);
>> +      DestIdx = DestIdStream->writeKnownType(R);
>>      addMapping(DestIdx);
>>      return Error::success();
>>    }
>> @@ -119,7 +127,7 @@ private:
>>    template <typename RecordType>
>>    Error writeMember(RecordType &R, bool RemapSuccess) {
>>      if (RemapSuccess)
>> -      FieldListBuilder.writeMemberType(R);
>> +      FieldListBuilder->writeMemberType(R);
>>      else
>>        HadUntranslatedMember = true;
>>      return Error::success();
>> @@ -135,13 +143,17 @@ private:
>>
>>    BumpPtrAllocator Allocator;
>>
>> -  TypeTableBuilder &DestIdStream;
>> -  TypeTableBuilder &DestTypeStream;
>> -  FieldListRecordBuilder FieldListBuilder;
>> -  TypeServerHandler *Handler;
>> -
>>    TypeIndex CurIndex{TypeIndex::FirstNonSimpleIndex};
>>
>> +  TypeTableBuilder *DestIdStream = nullptr;
>> +  TypeTableBuilder *DestTypeStream = nullptr;
>> +  std::unique_ptr<FieldListRecordBuilder> FieldListBuilder;
>> +  TypeServerHandler *Handler = nullptr;
>> +
>> +  // If we're only mapping id records, this array contains the mapping
>> for
>> +  // type records.
>> +  ArrayRef<TypeIndex> TypeLookup;
>> +
>>    /// Map from source type index to destination type index. Indexed by
>> source
>>    /// type index minus 0x1000.
>>    SmallVectorImpl<TypeIndex> &IndexMap;
>> @@ -178,7 +190,7 @@ void TypeStreamMerger::addMapping(TypeIn
>>    }
>>  }
>>
>> -bool TypeStreamMerger::remapIndex(TypeIndex &Idx) {
>> +bool TypeStreamMerger::remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex>
>> Map) {
>>    // Simple types are unchanged.
>>    if (Idx.isSimple())
>>      return true;
>> @@ -187,14 +199,14 @@ bool TypeStreamMerger::remapIndex(TypeIn
>>    // successfully. If it refers to a type later in the stream or a
>> record we
>>    // had to defer, defer it until later pass.
>>    unsigned MapPos = slotForIndex(Idx);
>> -  if (MapPos < IndexMap.size() && IndexMap[MapPos] != Untranslated) {
>> -    Idx = IndexMap[MapPos];
>> +  if (MapPos < Map.size() && Map[MapPos] != Untranslated) {
>> +    Idx = Map[MapPos];
>>      return true;
>>    }
>>
>>    // If this is the second pass and this index isn't in the map, then it
>> points
>>    // outside the current type stream, and this is a corrupt record.
>> -  if (IsSecondPass && MapPos >= IndexMap.size()) {
>> +  if (IsSecondPass && MapPos >= Map.size()) {
>>      // FIXME: Print a more useful error. We can give the current record
>> and the
>>      // index that we think its pointing to.
>>      LastError = joinErrors(std::move(*LastError), errorCorruptRecord());
>> @@ -208,55 +220,82 @@ bool TypeStreamMerger::remapIndex(TypeIn
>>    return false;
>>  }
>>
>> +bool TypeStreamMerger::remapTypeIndex(TypeIndex &Idx) {
>> +  // If we're mapping a pure index stream, then IndexMap only contains
>> mappings
>> +  // from OldIdStream -> NewIdStream, in which case we will need to use
>> the
>> +  // special mapping from OldTypeStream -> NewTypeStream which was
>> computed
>> +  // externally.  Regardless, we use this special map if and only if we
>> are
>> +  // doing an id-only mapping.
>> +  if (DestTypeStream == nullptr)
>> +    return remapIndex(Idx, TypeLookup);
>> +
>> +  assert(TypeLookup.empty());
>> +  return remapIndex(Idx, IndexMap);
>> +}
>> +
>> +bool TypeStreamMerger::remapItemIndex(TypeIndex &Idx) {
>> +  assert(DestIdStream);
>> +  return remapIndex(Idx, IndexMap);
>> +}
>> +
>>
>>  //----------------------------------------------------------------------------//
>>  // Item records
>>
>>  //----------------------------------------------------------------------------//
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, FuncIdRecord &R) {
>> +  assert(DestIdStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.ParentScope);
>> -  Success &= remapIndex(R.FunctionType);
>> +  Success &= remapItemIndex(R.ParentScope);
>> +  Success &= remapTypeIndex(R.FunctionType);
>>    return writeIdRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, MemberFuncIdRecord
>> &R) {
>> +  assert(DestIdStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.ClassType);
>> -  Success &= remapIndex(R.FunctionType);
>> +  Success &= remapTypeIndex(R.ClassType);
>> +  Success &= remapTypeIndex(R.FunctionType);
>>    return writeIdRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, StringIdRecord &R) {
>> -  return writeIdRecord(R, remapIndex(R.Id));
>> +  assert(DestIdStream);
>> +  return writeIdRecord(R, remapItemIndex(R.Id));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, StringListRecord &R) {
>> +  assert(DestIdStream);
>>    bool Success = true;
>>    for (TypeIndex &Str : R.StringIndices)
>> -    Success &= remapIndex(Str);
>> +    Success &= remapItemIndex(Str);
>>    return writeIdRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, BuildInfoRecord &R) {
>> +  assert(DestIdStream);
>>    bool Success = true;
>>    for (TypeIndex &Arg : R.ArgIndices)
>> -    Success &= remapIndex(Arg);
>> +    Success &= remapItemIndex(Arg);
>>    return writeIdRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, UdtSourceLineRecord
>> &R) {
>> +  assert(DestIdStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.UDT);
>> -  Success &= remapIndex(R.SourceFile);
>> +  Success &= remapTypeIndex(R.UDT);
>> +  Success &= remapItemIndex(R.SourceFile);
>>    // FIXME: Translate UdtSourceLineRecord into UdtModSourceLineRecords
>> in the
>>    // IPI stream.
>>    return writeIdRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &,
>> UdtModSourceLineRecord &R) {
>> +  assert(DestIdStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.UDT);
>> -  Success &= remapIndex(R.SourceFile);
>> +  Success &= remapTypeIndex(R.UDT);
>> +  // UdtModSourceLine Source File Ids are offsets into the global string
>> table.
>> +  // FIXME: We need to merge string table records for this to be valid.
>> +  // Success &= remapItemIndex(R.SourceFile);
>>    return writeIdRecord(R, Success);
>>  }
>>
>> @@ -265,112 +304,128 @@ Error TypeStreamMerger::visitKnownRecord
>>
>>  //----------------------------------------------------------------------------//
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, ModifierRecord &R) {
>> -  return writeRecord(R, remapIndex(R.ModifiedType));
>> +  assert(DestTypeStream);
>> +  return writeRecord(R, remapTypeIndex(R.ModifiedType));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, ProcedureRecord &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.ReturnType);
>> -  Success &= remapIndex(R.ArgumentList);
>> +  Success &= remapTypeIndex(R.ReturnType);
>> +  Success &= remapTypeIndex(R.ArgumentList);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, MemberFunctionRecord
>> &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.ReturnType);
>> -  Success &= remapIndex(R.ClassType);
>> -  Success &= remapIndex(R.ThisType);
>> -  Success &= remapIndex(R.ArgumentList);
>> +  Success &= remapTypeIndex(R.ReturnType);
>> +  Success &= remapTypeIndex(R.ClassType);
>> +  Success &= remapTypeIndex(R.ThisType);
>> +  Success &= remapTypeIndex(R.ArgumentList);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &Type, ArgListRecord &R)
>> {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>>    for (TypeIndex &Arg : R.ArgIndices)
>> -    Success &= remapIndex(Arg);
>> +    Success &= remapTypeIndex(Arg);
>>    if (auto EC = writeRecord(R, Success))
>>      return EC;
>>    return Error::success();
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, PointerRecord &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.ReferentType);
>> +  Success &= remapTypeIndex(R.ReferentType);
>>    if (R.isPointerToMember())
>> -    Success &= remapIndex(R.MemberInfo->ContainingType);
>> +    Success &= remapTypeIndex(R.MemberInfo->ContainingType);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, ArrayRecord &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.ElementType);
>> -  Success &= remapIndex(R.IndexType);
>> +  Success &= remapTypeIndex(R.ElementType);
>> +  Success &= remapTypeIndex(R.IndexType);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, ClassRecord &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.FieldList);
>> -  Success &= remapIndex(R.DerivationList);
>> -  Success &= remapIndex(R.VTableShape);
>> +  Success &= remapTypeIndex(R.FieldList);
>> +  Success &= remapTypeIndex(R.DerivationList);
>> +  Success &= remapTypeIndex(R.VTableShape);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, UnionRecord &R) {
>> -  return writeRecord(R, remapIndex(R.FieldList));
>> +  assert(DestTypeStream);
>> +  return writeRecord(R, remapTypeIndex(R.FieldList));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, EnumRecord &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.FieldList);
>> -  Success &= remapIndex(R.UnderlyingType);
>> +  Success &= remapTypeIndex(R.FieldList);
>> +  Success &= remapTypeIndex(R.UnderlyingType);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, BitFieldRecord &R) {
>> -  return writeRecord(R, remapIndex(R.Type));
>> +  assert(DestTypeStream);
>> +  return writeRecord(R, remapTypeIndex(R.Type));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, VFTableShapeRecord
>> &R) {
>> +  assert(DestTypeStream);
>>    return writeRecord(R, true);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, TypeServer2Record &R)
>> {
>> +  assert(DestTypeStream);
>>    return writeRecord(R, true);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, LabelRecord &R) {
>> +  assert(DestTypeStream);
>>    return writeRecord(R, true);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, VFTableRecord &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>> -  Success &= remapIndex(R.CompleteClass);
>> -  Success &= remapIndex(R.OverriddenVFTable);
>> +  Success &= remapTypeIndex(R.CompleteClass);
>> +  Success &= remapTypeIndex(R.OverriddenVFTable);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &,
>>                                           MethodOverloadListRecord &R) {
>> +  assert(DestTypeStream);
>>    bool Success = true;
>>    for (OneMethodRecord &Meth : R.Methods)
>> -    Success &= remapIndex(Meth.Type);
>> +    Success &= remapTypeIndex(Meth.Type);
>>    return writeRecord(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownRecord(CVType &, FieldListRecord &R) {
>> +  assert(DestTypeStream);
>>    // Visit the members inside the field list.
>>    HadUntranslatedMember = false;
>> -  FieldListBuilder.begin();
>> +  FieldListBuilder->begin();
>>    if (auto EC = codeview::visitMemberRecordStream(R.Data, *this))
>>      return EC;
>>
>>    // Write the record if we translated all field list members.
>>    TypeIndex DestIdx = Untranslated;
>>    if (!HadUntranslatedMember)
>> -    DestIdx = FieldListBuilder.end();
>> +    DestIdx = FieldListBuilder->end();
>>    else
>> -    FieldListBuilder.reset();
>> +    FieldListBuilder->reset();
>>    addMapping(DestIdx);
>>
>>    return Error::success();
>> @@ -382,28 +437,28 @@ Error TypeStreamMerger::visitKnownRecord
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>>                                           NestedTypeRecord &R) {
>> -  return writeMember(R, remapIndex(R.Type));
>> +  return writeMember(R, remapTypeIndex(R.Type));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>> OneMethodRecord &R) {
>>    bool Success = true;
>> -  Success &= remapIndex(R.Type);
>> +  Success &= remapTypeIndex(R.Type);
>>    return writeMember(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>>                                           OverloadedMethodRecord &R) {
>> -  return writeMember(R, remapIndex(R.MethodList));
>> +  return writeMember(R, remapTypeIndex(R.MethodList));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>>                                           DataMemberRecord &R) {
>> -  return writeMember(R, remapIndex(R.Type));
>> +  return writeMember(R, remapTypeIndex(R.Type));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>>                                           StaticDataMemberRecord &R) {
>> -  return writeMember(R, remapIndex(R.Type));
>> +  return writeMember(R, remapTypeIndex(R.Type));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>> @@ -412,24 +467,24 @@ Error TypeStreamMerger::visitKnownMember
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &, VFPtrRecord
>> &R) {
>> -  return writeMember(R, remapIndex(R.Type));
>> +  return writeMember(R, remapTypeIndex(R.Type));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>> BaseClassRecord &R) {
>> -  return writeMember(R, remapIndex(R.Type));
>> +  return writeMember(R, remapTypeIndex(R.Type));
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>>                                           VirtualBaseClassRecord &R) {
>>    bool Success = true;
>> -  Success &= remapIndex(R.BaseType);
>> -  Success &= remapIndex(R.VBPtrType);
>> +  Success &= remapTypeIndex(R.BaseType);
>> +  Success &= remapTypeIndex(R.VBPtrType);
>>    return writeMember(R, Success);
>>  }
>>
>>  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &,
>>                                           ListContinuationRecord &R) {
>> -  return writeMember(R, remapIndex(R.ContinuationIndex));
>> +  return writeMember(R, remapTypeIndex(R.ContinuationIndex));
>>  }
>>
>>  Error TypeStreamMerger::visitUnknownType(CVType &Rec) {
>> @@ -438,8 +493,34 @@ Error TypeStreamMerger::visitUnknownType
>>    return errorCorruptRecord();
>>  }
>>
>> -Error TypeStreamMerger::mergeStream(const CVTypeArray &Types) {
>> -  assert(IndexMap.empty());
>> +Error TypeStreamMerger::mergeTypeRecords(TypeTableBuilder &Dest,
>> +                                         TypeCollection &Types) {
>> +  DestTypeStream = &Dest;
>> +  FieldListBuilder = llvm::make_unique<FieldListRecordBuilder>(Dest);
>> +
>> +  return doit(Types);
>> +}
>> +
>> +Error TypeStreamMerger::mergeIdRecords(TypeTableBuilder &Dest,
>> +                                       ArrayRef<TypeIndex>
>> TypeSourceToDest,
>> +                                       TypeCollection &Ids) {
>> +  DestIdStream = &Dest;
>> +  TypeLookup = TypeSourceToDest;
>> +
>> +  return doit(Ids);
>> +}
>> +
>> +Error TypeStreamMerger::mergeTypesAndIds(TypeTableBuilder &DestIds,
>> +                                         TypeTableBuilder &DestTypes,
>> +                                         TypeCollection &IdsAndTypes) {
>> +  DestIdStream = &DestIds;
>> +  DestTypeStream = &DestTypes;
>> +  FieldListBuilder =
>> llvm::make_unique<FieldListRecordBuilder>(DestTypes);
>> +
>> +  return doit(IdsAndTypes);
>> +}
>> +
>> +Error TypeStreamMerger::doit(TypeCollection &Types) {
>>    LastError = Error::success();
>>
>>    if (auto EC = codeview::visitTypeStream(Types, *this, Handler))
>> @@ -469,18 +550,32 @@ Error TypeStreamMerger::mergeStream(cons
>>      }
>>    }
>>
>> -  IndexMap.clear();
>> -
>>    Error Ret = std::move(*LastError);
>>    LastError.reset();
>>    return Ret;
>>  }
>>
>> -Error llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestIdStream,
>> -                                       TypeTableBuilder &DestTypeStream,
>> +Error llvm::codeview::mergeTypeRecords(TypeTableBuilder &Dest,
>>                                         SmallVectorImpl<TypeIndex>
>> &SourceToDest,
>>                                         TypeServerHandler *Handler,
>> -                                       const CVTypeArray &Types) {
>> -  return TypeStreamMerger(DestIdStream, DestTypeStream, SourceToDest,
>> Handler)
>> -      .mergeStream(Types);
>> +                                       TypeCollection &Types) {
>> +  TypeStreamMerger M(SourceToDest, Handler);
>> +  return M.mergeTypeRecords(Dest, Types);
>> +}
>> +
>> +Error llvm::codeview::mergeIdRecords(TypeTableBuilder &Dest,
>> +                                     ArrayRef<TypeIndex>
>> TypeSourceToDest,
>> +                                     SmallVectorImpl<TypeIndex>
>> &SourceToDest,
>> +                                     TypeCollection &Ids) {
>> +  TypeStreamMerger M(SourceToDest, nullptr);
>> +  return M.mergeIdRecords(Dest, TypeSourceToDest, Ids);
>> +}
>> +
>> +Error llvm::codeview::mergeTypeAndIdRecords(
>> +    TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes,
>> +    SmallVectorImpl<TypeIndex> &SourceToDest, TypeServerHandler *Handler,
>> +    TypeCollection &IdsAndTypes) {
>> +
>> +  TypeStreamMerger M(SourceToDest, Handler);
>> +  return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes);
>>  }
>>
>> Modified: llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp?rev=303577&r1=303576&r2=303577&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp Mon May 22 16:07:43
>> 2017
>> @@ -8,7 +8,9 @@
>>
>>  //===----------------------------------------------------------------------===//
>>
>>  #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
>> +
>>  #include "llvm/ADT/iterator_range.h"
>> +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
>>  #include "llvm/DebugInfo/CodeView/TypeRecord.h"
>>  #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
>>  #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
>> @@ -104,6 +106,8 @@ Error TpiStream::reload() {
>>      HashStream = std::move(HS);
>>    }
>>
>> +  Types = llvm::make_unique<LazyRandomTypeCollection>(
>> +      TypeRecords, getNumTypeRecords(), getTypeIndexOffsets());
>>    return Error::success();
>>  }
>>
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-1.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-1.yaml?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-1.yaml (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-1.yaml Mon May 22
>> 16:07:43 2017
>> @@ -0,0 +1,36 @@
>> +IpiStream:
>> +  Records:
>> +    # 'One' [TypeIndex: 0x1000 (4096)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'One'
>> +    # 'Two' [TypeIndex: 0x1001 (4097)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'Two'
>> +    # 'OnlyInFirst' [TypeIndex: 0x1002 (4098)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'OnlyInFirst'
>> +    # 'SubOne' [TypeIndex: 0x1003 (4099)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'SubOne'
>> +    # 'SubTwo' [TypeIndex: 0x1004 (4100)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'SubTwo'
>> +    # 'SubOne', 'SubTwo' [TypeIndex: 0x1005 (4101)]
>> +    - Kind:            LF_SUBSTR_LIST
>> +      StringList:
>> +        StringIndices:   [ 4099, 4100 ]
>> +    # 'Main' {'SubOne', 'SubTwo'} [TypeIndex: 0x1006 (4102)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              4101
>> +        String:          'Main'
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-2.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-2.yaml?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-2.yaml (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-2.yaml Mon May 22
>> 16:07:43 2017
>> @@ -0,0 +1,31 @@
>> +IpiStream:
>> +  Records:
>> +    # 'SubTwo' [TypeIndex: 0x1000 (4096)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'SubTwo'
>> +    # 'OnlyInSecond' [TypeIndex: 0x1001 (4097)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'OnlyInSecond'
>> +    # 'SubOne' [TypeIndex: 0x1002 (4098)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'SubOne'
>> +    # 'SubOne', 'SubTwo' [TypeIndex: 0x1003 (4099)]
>> +    - Kind:            LF_SUBSTR_LIST
>> +      StringList:
>> +        StringIndices:   [ 4098, 4096 ]
>> +    # 'One' [TypeIndex: 0x1004 (4100)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              0
>> +        String:          'One'
>> +    # 'Main' {'SubOne', 'SubTwo'} [TypeIndex: 0x1005 (4101)]
>> +    - Kind:            LF_STRING_ID
>> +      StringId:
>> +        Id:              4099
>> +        String:          'Main'
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-1.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-1.yaml?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-1.yaml
>> (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-1.yaml Mon
>> May 22 16:07:43 2017
>> @@ -0,0 +1,113 @@
>> +# The idea is to set up some types in the TPI stream, and then have
>> records in
>> +# the IPI stream that refer to them.  There are three types of IPI
>> records that
>> +# can refer to TPI records.  They are:
>> +# 1) LF_PROCEDURE - Referred to by LF_FUNC_ID
>> +# 2) LF_STRUCTURE - Referred to by LF_UDT_MOD_SRC_LINE
>> +#                   Referred to by LF_UDT_SRC_LINE
>> +# 3) LF_MFUNCTION - Referred to by LF_MFUNC_ID
>> +# We will set up one of each of these, and then create IPI records that
>> refer to
>> +# them.  We intentionally choose an unintuitive ordering of the records
>> in both
>> +# streams (while still maintaining the topological sorting required by
>> CodeView
>> +# type streams), to make sure the merging algorithm is sufficiently
>> exercised.
>> +# For easy understanding, a semantic representation of the types we will
>> set up
>> +# is as follows:
>> +#  - int main(int, char**)
>> +#
>> +#  - struct FooBar {
>> +#    public:
>> +#      void *FooMember;
>> +#      void FooMethod(int);
>> +#    };
>> +TpiStream:
>> +  Records:
>> +    # TypeIndex: 4096 (0x1000)
>> +    # char**
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    1136
>> +        Attrs:           32778
>> +    # TypeIndex: 4097 (0x1001)
>> +    # public void *FooMember
>> +    - Kind:            LF_FIELDLIST
>> +      FieldList:
>> +        - Kind:            LF_MEMBER
>> +          DataMember:
>> +            Attrs:           3           # public
>> +            Type:            1027        # void*
>> +            FieldOffset:     0
>> +            Name:            FooMember   # FooMember
>> +    # TypeIndex: 4098 (0x1002)
>> +    # (int, char**)
>> +    - Kind:            LF_ARGLIST
>> +      ArgList:
>> +        ArgIndices:      [ 116, 4096 ]
>> +    # TypeIndex: 4099 (0x1003)
>> +    # struct FooBar {
>> +    # public:
>> +    #   void *FooMember;
>> +    # };
>> +    - Kind:            LF_STRUCTURE
>> +      Class:
>> +        MemberCount:     1
>> +        Options:         [ None, HasUniqueName ]
>> +        FieldList:       4097
>> +        Name:            FooBar
>> +        UniqueName:      'FooBar'
>> +        DerivationList:  0
>> +        VTableShape:     0
>> +        Size:            4
>> +    # TypeIndex: 4100 (0x1004)
>> +    # FooBar *
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4099       # FooBar
>> +        Attrs:           32778
>> +    # TypeIndex: 4101 (0x1005)
>> +    # (int)
>> +    - Kind:            LF_ARGLIST
>> +      ArgList:
>> +        ArgIndices:      [ 116 ]
>> +    # TypeIndex: 4102 (0x1006)
>> +    - Kind:            LF_MFUNCTION
>> +      MemberFunction:
>> +        ReturnType:      3                      # void
>> +        ClassType:       4099                   # struct FooBar
>> +        ThisType:        4100                   # FooBar *
>> +        CallConv:        ThisCall
>> +        Options:         [ None, Constructor ]
>> +        ParameterCount:  1
>> +        ArgumentList:    4101                   # (int)
>> +        ThisPointerAdjustment: 0
>> +    # TypeIndex: 4103 (0x1007)
>> +    # int (int, char**)
>> +    - Kind:            LF_PROCEDURE
>> +      Procedure:
>> +        ReturnType:      116         # int
>> +        CallConv:        NearC
>> +        Options:         [ None ]
>> +        ParameterCount:  2
>> +        ArgumentList:    4098        # (int, char**)
>> +IpiStream:
>> +  Records:
>> +    # TypeIndex: 4096 (0x1000)
>> +    # int main(int, char **)
>> +    - Kind:            LF_FUNC_ID
>> +      FuncId:
>> +        ParentScope:     0
>> +        FunctionType:    4103       # int main(int, char**)
>> +        Name:            main
>> +    # TypeIndex: 4097 (0x1001)
>> +    # void FooBar::FooMethod(int)
>> +    - Kind:            LF_MFUNC_ID
>> +      MemberFuncId:
>> +        ClassType:       4099       # struct FooBar
>> +        FunctionType:    4102       # void FooMethod(int)
>> +        Name:            FooMethod
>> +    # TypeIndex: 4098 (0x1002)
>> +    # struct FooBar
>> +    - Kind:            LF_UDT_MOD_SRC_LINE
>> +      UdtModSourceLine:
>> +        UDT:             4099       # struct FooBar
>> +        SourceFile:      0          # We don't support this yet
>> +        LineNumber:      0
>> +        Module:          0          # We don't support this yet
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-2.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-2.yaml?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-2.yaml
>> (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge-ids-and-types-2.yaml Mon
>> May 22 16:07:43 2017
>> @@ -0,0 +1,143 @@
>> +# In file 1 we set up some basic types and IDs to refer to them.  In
>> this file
>> +# we will set up the same types.  For some of them we will make them
>> identical
>> +# but re-order the records in the file to make sure they have different
>> type
>> +# indices and appear in different orders.  In other cases we will make
>> slight
>> +# adjustments to the types, to ensure that they do not get merged in.
>> +#
>> +# For easy understanding, a semantic representation of the types we will
>> set up
>> +# is as follows:
>> +#  - int main(int, char**)    // This record should share an
>> LF_PROCEDURE and id
>> +#                             // record with corresponding function from
>> the
>> +#                             // first file.
>> +#  - int main2(int, char**)   // This record should share the
>> LF_PROCEDURE
>> +#                             // record but have a unique id record.
>> +#  - void foo(int, char**)    // This record should have a unique
>> LF_PROCEDURE
>> +#                             // record, but the LF_ARGLIST record
>> internally
>> +#                             // should be shared.
>> +#
>> +#  - struct FooBar {          // Because the type of this record exactly
>> matches
>> +#                             // the corresponding file, its entire type
>> record
>> +#                             // hierarchy should be shared.
>> +#    public:
>> +#      void *FooMember;
>> +#      void FooMethod2(int);  // Note that the *type* of this member
>> should be
>> +#                             // the same as the type of the record from
>> the
>> +#                             // first stream.  But since it has a
>> different
>> +#                             // name, it will not share an id record.
>> +#    };
>> +TpiStream:
>> +  Records:
>> +    # TypeIndex: 4096 (0x1000)
>> +    # (int)
>> +    - Kind:            LF_ARGLIST
>> +      ArgList:
>> +        ArgIndices:      [ 116 ]
>> +    # TypeIndex: 4097 (0x1001)
>> +    # public void *FooMember
>> +    - Kind:            LF_FIELDLIST
>> +      FieldList:
>> +        - Kind:            LF_MEMBER
>> +          DataMember:
>> +            Attrs:           3           # public
>> +            Type:            1027        # void*
>> +            FieldOffset:     0
>> +            Name:            FooMember   # FooMember
>> +    # TypeIndex: 4098 (0x1002)
>> +    # char**
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    1136
>> +        Attrs:           32778
>> +    # TypeIndex: 4099 (0x1003)
>> +    # (int, char**)
>> +    - Kind:            LF_ARGLIST
>> +      ArgList:
>> +        ArgIndices:      [ 116, 4098 ]
>> +    # TypeIndex: 4100 (0x1004)
>> +    # struct FooBar {
>> +    # public:
>> +    #   void *FooMember;
>> +    # };
>> +    - Kind:            LF_STRUCTURE
>> +      Class:
>> +        MemberCount:     1
>> +        Options:         [ None, HasUniqueName ]
>> +        FieldList:       4097
>> +        Name:            FooBar
>> +        UniqueName:      'FooBar'
>> +        DerivationList:  0
>> +        VTableShape:     0
>> +        Size:            4
>> +    # TypeIndex: 4101 (0x1005)
>> +    # void (int, char**)
>> +    - Kind:            LF_PROCEDURE
>> +      Procedure:
>> +        ReturnType:      3           # void
>> +        CallConv:        NearC
>> +        Options:         [ None ]
>> +        ParameterCount:  2
>> +        ArgumentList:    4099        # (int, char**)
>> +    # TypeIndex: 4102 (0x1006)
>> +    # FooBar *
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4100       # FooBar
>> +        Attrs:           32778
>> +    # TypeIndex: 4103 (0x1007)
>> +    # int (int, char**)
>> +    - Kind:            LF_PROCEDURE
>> +      Procedure:
>> +        ReturnType:      116         # int
>> +        CallConv:        NearC
>> +        Options:         [ None ]
>> +        ParameterCount:  2
>> +        ArgumentList:    4099        # (int, char**)
>> +    # TypeIndex: 4104 (0x1008)
>> +    - Kind:            LF_MFUNCTION
>> +      MemberFunction:
>> +        ReturnType:      3                      # void
>> +        ClassType:       4100                   # struct FooBar
>> +        ThisType:        4102                   # FooBar *
>> +        CallConv:        ThisCall
>> +        Options:         [ None, Constructor ]
>> +        ParameterCount:  1
>> +        ArgumentList:    4096                   # (int)
>> +        ThisPointerAdjustment: 0
>> +IpiStream:
>> +  Records:
>> +    # TypeIndex: 4096 (0x1000)
>> +    # struct FooBar
>> +    - Kind:            LF_UDT_MOD_SRC_LINE
>> +      UdtModSourceLine:
>> +        UDT:             4100       # struct FooBar
>> +        SourceFile:      0          # We don't support this yet
>> +        LineNumber:      0
>> +        Module:          0          # We don't support this yet
>> +    # TypeIndex: 4097 (0x1001)
>> +    # int main2(int, char **)
>> +    - Kind:            LF_FUNC_ID
>> +      FuncId:
>> +        ParentScope:     0
>> +        FunctionType:    4103       # int main2(int, char**)
>> +        Name:            main2
>> +    # TypeIndex: 4098 (0x1002)
>> +    # void foo(int, char **)
>> +    - Kind:            LF_FUNC_ID
>> +      FuncId:
>> +        ParentScope:     0
>> +        FunctionType:    4101       # void main2(int, char**)
>> +        Name:            foo
>> +    # TypeIndex: 4099 (0x1003)
>> +    # void FooBar::FooMethod2(int)
>> +    - Kind:            LF_MFUNC_ID
>> +      MemberFuncId:
>> +        ClassType:       4100       # struct FooBar
>> +        FunctionType:    4104       # void FooBar::FooMethod2(int)
>> +        Name:            FooMethod2
>> +    # TypeIndex: 4100 (0x1004)
>> +    # int main(int, char **)
>> +    - Kind:            LF_FUNC_ID
>> +      FuncId:
>> +        ParentScope:     0
>> +        FunctionType:    4103       # int main(int, char**)
>> +        Name:            main
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-1.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-1.yaml?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-1.yaml (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-1.yaml Mon May 22
>> 16:07:43 2017
>> @@ -0,0 +1,52 @@
>> +---
>> +TpiStream:
>> +  Records:
>> +    # uint32_t* [Index: 0x1000]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    117
>> +        Attrs:           32778
>> +    # int64_t* [Index: 0x1001]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    118
>> +        Attrs:           32778
>> +    # struct OnlyInMerge1 [Index: 0x1002]
>> +    - Kind:            LF_STRUCTURE
>> +      Class:
>> +        MemberCount:     0
>> +        Options:         [ None, ForwardReference, HasUniqueName ]
>> +        FieldList:       0
>> +        Name:            'OnlyInMerge1'
>> +        UniqueName:      'OnlyInMerge1'
>> +        DerivationList:  0
>> +        VTableShape:     0
>> +        Size:            0
>> +    # uint32_t** [Index: 0x1003]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4096
>> +        Attrs:           32778
>> +    # uint32_t*** [Index: 0x1004]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4099
>> +        Attrs:           32778
>> +    # int64_t* [Index: 0x1005]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4097
>> +        Attrs:           32778
>> +    # [uint32_t, uint32_t*, uint32_t**] [Index: 0x1006]
>> +    - Kind:            LF_ARGLIST
>> +      ArgList:
>> +        ArgIndices:      [ 117, 4096, 4099 ]
>> +    # uint32_t (uint32_t, uint32_t*, uint32_t**) [Index: 0x1007]
>> +    - Kind:            LF_PROCEDURE
>> +      Procedure:
>> +        ReturnType:      117
>> +        CallConv:        NearC
>> +        Options:         [ None ]
>> +        ParameterCount:  0
>> +        ArgumentList:    4102
>> +...
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-2.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-2.yaml?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-2.yaml (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge-types-2.yaml Mon May 22
>> 16:07:43 2017
>> @@ -0,0 +1,52 @@
>> +---
>> +TpiStream:
>> +  Records:
>> +    # uint32_t* [Index: 0x1000]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    117
>> +        Attrs:           32778
>> +    # uint32_t** [Index: 0x1001]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4096
>> +        Attrs:           32778
>> +    # uint32_t*** [Index: 0x1002]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4097
>> +        Attrs:           32778
>> +    # [uint32_t, uint32_t*, uint32_t**] [Index: 0x1003]
>> +    - Kind:            LF_ARGLIST
>> +      ArgList:
>> +        ArgIndices:      [ 117, 4096, 4097 ]
>> +    # uint32_t (uint32_t, uint32_t*, uint32_t**) [Index: 0x1004]
>> +    - Kind:            LF_PROCEDURE
>> +      Procedure:
>> +        ReturnType:      117
>> +        CallConv:        NearC
>> +        Options:         [ None ]
>> +        ParameterCount:  0
>> +        ArgumentList:    4099
>> +    # int64_t* [Index: 0x1005]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    118
>> +        Attrs:           32778
>> +    # int64_t** [Index: 0x1006]
>> +    - Kind:            LF_POINTER
>> +      Pointer:
>> +        ReferentType:    4101
>> +        Attrs:           32778
>> +    # struct OnlyInMerge2 [Index: 0x1007]
>> +    - Kind:            LF_STRUCTURE
>> +      Class:
>> +        MemberCount:     0
>> +        Options:         [ None, ForwardReference, HasUniqueName ]
>> +        FieldList:       0
>> +        Name:            'OnlyInMerge2'
>> +        UniqueName:      'OnlyInMerge2'
>> +        DerivationList:  0
>> +        VTableShape:     0
>> +        Size:            0
>> +...
>>
>> Removed: llvm/trunk/test/DebugInfo/PDB/Inputs/merge1.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge1.yaml?rev=303576&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge1.yaml (original)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge1.yaml (removed)
>> @@ -1,52 +0,0 @@
>> ----
>> -TpiStream:
>> -  Records:
>> -    # uint32_t* [Index: 0x1000]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    117
>> -        Attrs:           32778
>> -    # int64_t* [Index: 0x1001]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    118
>> -        Attrs:           32778
>> -    # struct OnlyInMerge1 [Index: 0x1002]
>> -    - Kind:            LF_STRUCTURE
>> -      Class:
>> -        MemberCount:     0
>> -        Options:         [ None, ForwardReference, HasUniqueName ]
>> -        FieldList:       0
>> -        Name:            'OnlyInMerge1'
>> -        UniqueName:      'OnlyInMerge1'
>> -        DerivationList:  0
>> -        VTableShape:     0
>> -        Size:            0
>> -    # uint32_t** [Index: 0x1003]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    4096
>> -        Attrs:           32778
>> -    # uint32_t*** [Index: 0x1004]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    4099
>> -        Attrs:           32778
>> -    # int64_t* [Index: 0x1005]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    4097
>> -        Attrs:           32778
>> -    # [uint32_t, uint32_t*, uint32_t**] [Index: 0x1006]
>> -    - Kind:            LF_ARGLIST
>> -      ArgList:
>> -        ArgIndices:      [ 117, 4096, 4099 ]
>> -    # uint32_t (uint32_t, uint32_t*, uint32_t**) [Index: 0x1007]
>> -    - Kind:            LF_PROCEDURE
>> -      Procedure:
>> -        ReturnType:      117
>> -        CallConv:        NearC
>> -        Options:         [ None ]
>> -        ParameterCount:  0
>> -        ArgumentList:    4102
>> -...
>>
>> Removed: llvm/trunk/test/DebugInfo/PDB/Inputs/merge2.yaml
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/merge2.yaml?rev=303576&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/Inputs/merge2.yaml (original)
>> +++ llvm/trunk/test/DebugInfo/PDB/Inputs/merge2.yaml (removed)
>> @@ -1,52 +0,0 @@
>> ----
>> -TpiStream:
>> -  Records:
>> -    # uint32_t* [Index: 0x1000]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    117
>> -        Attrs:           32778
>> -    # uint32_t** [Index: 0x1001]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    4096
>> -        Attrs:           32778
>> -    # uint32_t*** [Index: 0x1002]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    4097
>> -        Attrs:           32778
>> -    # [uint32_t, uint32_t*, uint32_t**] [Index: 0x1003]
>> -    - Kind:            LF_ARGLIST
>> -      ArgList:
>> -        ArgIndices:      [ 117, 4096, 4097 ]
>> -    # uint32_t (uint32_t, uint32_t*, uint32_t**) [Index: 0x1004]
>> -    - Kind:            LF_PROCEDURE
>> -      Procedure:
>> -        ReturnType:      117
>> -        CallConv:        NearC
>> -        Options:         [ None ]
>> -        ParameterCount:  0
>> -        ArgumentList:    4099
>> -    # int64_t* [Index: 0x1005]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    118
>> -        Attrs:           32778
>> -    # int64_t** [Index: 0x1006]
>> -    - Kind:            LF_POINTER
>> -      Pointer:
>> -        ReferentType:    4101
>> -        Attrs:           32778
>> -    # struct OnlyInMerge2 [Index: 0x1007]
>> -    - Kind:            LF_STRUCTURE
>> -      Class:
>> -        MemberCount:     0
>> -        Options:         [ None, ForwardReference, HasUniqueName ]
>> -        FieldList:       0
>> -        Name:            'OnlyInMerge2'
>> -        UniqueName:      'OnlyInMerge2'
>> -        DerivationList:  0
>> -        VTableShape:     0
>> -        Size:            0
>> -...
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/pdbdump-merge-ids-and-types.test
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-merge-ids-and-types.test?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/pdbdump-merge-ids-and-types.test (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/pdbdump-merge-ids-and-types.test Mon
>> May 22 16:07:43 2017
>> @@ -0,0 +1,65 @@
>> +; RUN: llvm-pdbdump yaml2pdb -pdb=%t.1.pdb
>> %p/Inputs/merge-ids-and-types-1.yaml
>> +; RUN: llvm-pdbdump yaml2pdb -pdb=%t.2.pdb
>> %p/Inputs/merge-ids-and-types-2.yaml
>> +; RUN: llvm-pdbdump merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb
>> +; RUN: llvm-pdbdump raw -tpi-records %t.3.pdb | FileCheck
>> -check-prefix=TPI-TYPES %s
>> +; RUN: llvm-pdbdump raw -tpi-records %t.3.pdb | FileCheck
>> -check-prefix=INTMAIN %s
>> +; RUN: llvm-pdbdump raw -tpi-records %t.3.pdb | FileCheck
>> -check-prefix=VOIDMAIN %s
>> +; RUN: llvm-pdbdump raw -ipi-records %t.3.pdb | FileCheck
>> -check-prefix=IPI-TYPES %s
>> +; RUN: llvm-pdbdump raw -ipi-records %t.3.pdb | FileCheck
>> -check-prefix=IPI-NAMES %s
>> +; RUN: llvm-pdbdump raw -ipi-records %t.3.pdb | FileCheck
>> -check-prefix=IPI-UDT %s
>> +
>> +TPI-TYPES:     Type Info Stream (TPI)
>> +TPI-TYPES:     Record count: 9
>> +TPI-TYPES-DAG: TypeLeafKind: LF_POINTER
>> +TPI-TYPES-DAG: TypeLeafKind: LF_FIELDLIST
>> +TPI-TYPES-DAG: TypeLeafKind: LF_ARGLIST
>> +TPI-TYPES-DAG: TypeLeafKind: LF_STRUCTURE
>> +TPI-TYPES-DAG: TypeLeafKind: LF_MEMBER
>> +TPI-TYPES-DAG: TypeLeafKind: LF_POINTER
>> +TPI-TYPES-DAG: TypeLeafKind: LF_ARGLIST
>> +TPI-TYPES-DAG: TypeLeafKind: LF_MFUNCTION
>> +TPI-TYPES-DAG: TypeLeafKind: LF_PROCEDURE
>> +TPI-TYPES-DAG: TypeLeafKind: LF_PROCEDURE
>> +TPI-TYPES-DAG: TypeLeafKind: LF_ARGLIST
>> +
>> +; Both procedures should use the same arglist even though they have a
>> different
>> +; return type.
>> +INTMAIN:      ArgList ([[ID:.*]])
>> +INTMAIN-NEXT:   TypeLeafKind: LF_ARGLIST
>> +INTMAIN-NEXT:   NumArgs: 2
>> +INTMAIN-NEXT:   Arguments [
>> +INTMAIN-NEXT:     ArgType: int
>> +INTMAIN-NEXT:     ArgType: char**
>> +INTMAIN:        TypeLeafKind: LF_PROCEDURE
>> +INTMAIN:          ReturnType: int
>> +INTMAIN:          NumParameters: 2
>> +INTMAIN-NEXT:     ArgListType: (int, char**) ([[ID]])
>> +
>> +VOIDMAIN:      ArgList ([[ID:.*]])
>> +VOIDMAIN-NEXT:   TypeLeafKind: LF_ARGLIST
>> +VOIDMAIN-NEXT:   NumArgs: 2
>> +VOIDMAIN-NEXT:   Arguments [
>> +VOIDMAIN-NEXT:     ArgType: int
>> +VOIDMAIN-NEXT:     ArgType: char**
>> +VOIDMAIN:        TypeLeafKind: LF_PROCEDURE
>> +VOIDMAIN:          ReturnType: void
>> +VOIDMAIN:          NumParameters: 2
>> +VOIDMAIN-NEXT:     ArgListType: (int, char**) ([[ID]])
>> +
>> +IPI-TYPES:     Type Info Stream (IPI)
>> +IPI-TYPES:     Record count: 6
>> +IPI-TYPES-DAG: TypeLeafKind: LF_FUNC_ID
>> +IPI-TYPES-DAG: TypeLeafKind: LF_MFUNC_ID
>> +IPI-TYPES-DAG: TypeLeafKind: LF_UDT_MOD_SRC_LINE
>> +IPI-TYPES-DAG: TypeLeafKind: LF_FUNC_ID
>> +IPI-TYPES-DAG: TypeLeafKind: LF_FUNC_ID
>> +IPI-TYPES-DAG: TypeLeafKind: LF_MFUNC_ID
>> +
>> +IPI-NAMES-DAG: Name: main
>> +IPI-NAMES-DAG: Name: FooMethod
>> +IPI-NAMES-DAG: Name: main2
>> +IPI-NAMES-DAG: Name: foo
>> +IPI-NAMES-DAG: Name: FooMethod2
>> +
>> +IPI-UDT:      TypeLeafKind: LF_UDT_MOD_SRC_LINE
>> +IPI-UDT-NEXT: UDT: FooBar
>>
>> Added: llvm/trunk/test/DebugInfo/PDB/pdbdump-mergeids.test
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-mergeids.test?rev=303577&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/pdbdump-mergeids.test (added)
>> +++ llvm/trunk/test/DebugInfo/PDB/pdbdump-mergeids.test Mon May 22
>> 16:07:43 2017
>> @@ -0,0 +1,31 @@
>> +; RUN: llvm-pdbdump yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-ids-1.yaml
>> +; RUN: llvm-pdbdump yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-ids-2.yaml
>> +; RUN: llvm-pdbdump merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb
>> +; RUN: llvm-pdbdump raw -ipi-records %t.3.pdb | FileCheck
>> -check-prefix=MERGED %s
>> +; RUN: llvm-pdbdump raw -ipi-records %t.3.pdb | FileCheck
>> -check-prefix=SUBSTRS %s
>> +; RUN: llvm-pdbdump raw -tpi-records %t.3.pdb | FileCheck
>> -check-prefix=TPI-EMPTY %s
>> +
>> +
>> +MERGED: Type Info Stream (IPI)
>> +MERGED: Record count: 8
>> +MERGED-DAG: StringData: One
>> +MERGED-DAG: StringData: Two
>> +MERGED-DAG: StringData: SubOne
>> +MERGED-DAG: StringData: SubTwo
>> +MERGED-DAG: StringData: Main
>> +MERGED-DAG: TypeLeafKind: LF_SUBSTR_LIST
>> +MERGED-DAG: StringData: OnlyInFirst
>> +MERGED-DAG: StringData: OnlyInSecond
>> +
>> +SUBSTRS:      StringList
>> +SUBSTRS:        TypeLeafKind: LF_SUBSTR_LIST
>> +SUBSTRS-NEXT:   NumStrings: 2
>> +SUBSTRS-NEXT:   Strings [
>> +SUBSTRS-NEXT:     SubOne
>> +SUBSTRS-NEXT:     SubTwo
>> +SUBSTRS:      StringId
>> +SUBSTRS-NEXT:   TypeLeafKind: LF_STRING_ID
>> +SUBSTRS-NEXT:   Id: "SubOne" "SubTwo"
>> +SUBSTRS-NEXT:   StringData: Main
>> +
>> +TPI-EMPTY: Record count: 0
>>
>> Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-mergetypes.test
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-mergetypes.test?rev=303577&r1=303576&r2=303577&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/DebugInfo/PDB/pdbdump-mergetypes.test (original)
>> +++ llvm/trunk/test/DebugInfo/PDB/pdbdump-mergetypes.test Mon May 22
>> 16:07:43 2017
>> @@ -1,5 +1,5 @@
>> -; RUN: llvm-pdbdump yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge1.yaml
>> -; RUN: llvm-pdbdump yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge2.yaml
>> +; RUN: llvm-pdbdump yaml2pdb -pdb=%t.1.pdb %p/Inputs/merge-types-1.yaml
>> +; RUN: llvm-pdbdump yaml2pdb -pdb=%t.2.pdb %p/Inputs/merge-types-2.yaml
>>  ; RUN: llvm-pdbdump merge -pdb=%t.3.pdb %t.1.pdb %t.2.pdb
>>  ; RUN: llvm-pdbdump raw -tpi-records %t.3.pdb | FileCheck
>> -check-prefix=MERGED %s
>>  ; RUN: llvm-pdbdump raw -tpi-records %t.3.pdb | FileCheck
>> -check-prefix=ARGLIST %s
>>
>> Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=303577&r1=303576&r2=303577&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
>> +++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Mon May 22 16:07:43
>> 2017
>> @@ -500,6 +500,7 @@ static void yamlToPdb(StringRef Path) {
>>    pdb::yaml::PdbInfoStream DefaultInfoStream;
>>    pdb::yaml::PdbDbiStream DefaultDbiStream;
>>    pdb::yaml::PdbTpiStream DefaultTpiStream;
>> +  pdb::yaml::PdbTpiStream DefaultIpiStream;
>>
>>    const auto &Info = YamlObj.PdbStream.getValueOr(DefaultInfoStream);
>>
>> @@ -601,11 +602,11 @@ static void yamlToPdb(StringRef Path) {
>>    for (const auto &R : Tpi.Records)
>>      TpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash);
>>
>> -  const auto &Ipi = YamlObj.IpiStream.getValueOr(DefaultTpiStream);
>> +  const auto &Ipi = YamlObj.IpiStream.getValueOr(DefaultIpiStream);
>>    auto &IpiBuilder = Builder.getIpiBuilder();
>>    IpiBuilder.setVersionHeader(Ipi.Version);
>>    for (const auto &R : Ipi.Records)
>> -    TpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash);
>> +    IpiBuilder.addTypeRecord(R.Record.data(), R.Record.Hash);
>>
>>    ExitOnErr(Builder.commit(opts::yaml2pdb::YamlPdbOutputFile));
>>  }
>> @@ -852,18 +853,17 @@ static void mergePdbs() {
>>    for (const auto &Path : opts::merge::InputFilenames) {
>>      std::unique_ptr<IPDBSession> Session;
>>      auto &File = loadPDB(Path, Session);
>> -    SmallVector<TypeIndex, 128> SourceToDest;
>> +    SmallVector<TypeIndex, 128> TypeMap;
>> +    SmallVector<TypeIndex, 128> IdMap;
>>      if (File.hasPDBTpiStream()) {
>> -      SourceToDest.clear();
>>        auto &Tpi = ExitOnErr(File.getPDBTpiStream());
>> -      ExitOnErr(codeview::mergeTypeStreams(MergedIpi, MergedTpi,
>> SourceToDest,
>> -                                           nullptr, Tpi.typeArray()));
>> +      ExitOnErr(codeview::mergeTypeRecords(MergedTpi, TypeMap, nullptr,
>> +                                           Tpi.typeCollection()));
>>      }
>>      if (File.hasPDBIpiStream()) {
>> -      SourceToDest.clear();
>>        auto &Ipi = ExitOnErr(File.getPDBIpiStream());
>> -      ExitOnErr(codeview::mergeTypeStreams(MergedIpi, MergedTpi,
>> SourceToDest,
>> -                                           nullptr, Ipi.typeArray()));
>> +      ExitOnErr(codeview::mergeIdRecords(MergedIpi, TypeMap, IdMap,
>> +                                         Ipi.typeCollection()));
>>      }
>>    }
>>
>>
>> Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=303577&r1=303576&r2=303577&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
>> +++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Mon May 22 16:07:43 2017
>> @@ -1072,9 +1072,10 @@ void COFFDumper::mergeCodeViewTypes(Type
>>          W.flush();
>>          error(object_error::parse_failed);
>>        }
>> +      LazyRandomTypeCollection TypesAndIds(Types, 100);
>>        SmallVector<TypeIndex, 128> SourceToDest;
>> -      if (auto EC =
>> -              mergeTypeStreams(CVIDs, CVTypes, SourceToDest, nullptr,
>> Types))
>> +      if (auto EC = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest,
>> nullptr,
>> +                                          TypesAndIds))
>>          return error(std::move(EC));
>>      }
>>    }
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170524/215be1b8/attachment.html>


More information about the llvm-commits mailing list