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

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


Should be fixed in r303711.

On Tue, May 23, 2017 at 5:35 PM Zachary Turner <zturner at google.com> wrote:

> 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/21836c14/attachment-0001.html>


More information about the llvm-commits mailing list