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