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

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 17:33:31 PDT 2017


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/20170523/0e8c989b/attachment-0001.html>


More information about the llvm-commits mailing list