[llvm] r267564 - Refactor some more PDB reading code into DebugInfoPDB.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 26 09:20:01 PDT 2016


Author: zturner
Date: Tue Apr 26 11:20:00 2016
New Revision: 267564

URL: http://llvm.org/viewvc/llvm-project?rev=267564&view=rev
Log:
Refactor some more PDB reading code into DebugInfoPDB.

Differential Revision: http://reviews.llvm.org/D19445
Reviewed By: David Majnemer

Added:
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBRawConstants.h
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
    llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
    llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h?rev=267564&r1=267563&r2=267564&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBFile.h Tue Apr 26 11:20:00 2016
@@ -20,6 +20,7 @@ namespace llvm {
 class MemoryBuffer;
 
 struct PDBFileContext;
+class PDBStream;
 
 class PDBFile {
 public:
@@ -54,6 +55,8 @@ public:
     return BlockNumber * BlockSize;
   }
 
+  PDBStream *getPDBStream() const;
+
 private:
   std::unique_ptr<PDBFileContext> Context;
 };

Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h?rev=267564&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h Tue Apr 26 11:20:00 2016
@@ -0,0 +1,62 @@
+//===- PDBInfoStream.h - PDB Info Stream (Stream 1) Access ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBNameMap.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBRawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBStream.h"
+
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+
+class PDBInfoStream {
+public:
+  PDBInfoStream(const PDBFile &File);
+
+  std::error_code reload();
+
+  PdbRaw_ImplVer getVersion() const;
+  uint32_t getSignature() const;
+  uint32_t getAge() const;
+  PDB_UniqueId getGuid() const;
+
+  uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
+
+private:
+  PDBStream Stream1;
+  const PDBFile &Pdb;
+
+  // PDB file format version.  We only support VC70.  See the enumeration
+  // `PdbRaw_ImplVer` for the other possible values.
+  uint32_t Version;
+
+  // A 32-bit signature unique across all PDBs.  This is generated with
+  // a call to time() when the PDB is written, but obviously this is not
+  // universally unique.
+  uint32_t Signature;
+
+  // The number of times the PDB has been written.  Might also be used to
+  // ensure that the PDB matches the executable.
+  uint32_t Age;
+
+  // Due to the aforementioned limitations with `Signature`, this is a new
+  // signature present on VC70 and higher PDBs which is guaranteed to be
+  // universally unique.
+  PDB_UniqueId Guid;
+
+  PDBNameMap NamedStreams;
+};
+}
+
+#endif

Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h?rev=267564&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h Tue Apr 26 11:20:00 2016
@@ -0,0 +1,34 @@
+//===- PDBNameMap.h - PDB Name Map ------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBNAMEMAP_H
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <stdint.h>
+#include <utility>
+
+namespace llvm {
+class PDBStream;
+class PDBNameMap {
+public:
+  PDBNameMap();
+
+  std::error_code load(PDBStream &Stream);
+
+  bool tryGetValue(StringRef Name, uint32_t &Value) const;
+
+private:
+  StringMap<uint32_t> Mapping;
+};
+}
+
+#endif
\ No newline at end of file

Added: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBRawConstants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBRawConstants.h?rev=267564&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBRawConstants.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/PDBRawConstants.h Tue Apr 26 11:20:00 2016
@@ -0,0 +1,31 @@
+//===- PDBRawConstants.h ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
+
+#include <stdint.h>
+
+namespace llvm {
+
+enum PdbRaw_ImplVer : uint32_t {
+  VC2 = 19941610,
+  VC4 = 19950623,
+  VC41 = 19950814,
+  VC50 = 19960307,
+  VC98 = 19970604,
+  VC70Dep = 19990604, // deprecated
+  VC70 = 20000404,
+  VC80 = 20030901,
+  VC110 = 20091201,
+  VC140 = 20140508,
+};
+}
+
+#endif

Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=267564&r1=267563&r2=267564&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Tue Apr 26 11:20:00 2016
@@ -28,6 +28,8 @@ endif()
 
 add_pdb_impl_folder(Raw
   Raw/PDBFile.cpp
+  Raw/PDBInfoStream.cpp
+  Raw/PDBNameMap.cpp
   Raw/PDBStream.cpp
   Raw/RawSession.cpp)
 

Added: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp?rev=267564&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp Tue Apr 26 11:20:00 2016
@@ -0,0 +1,54 @@
+//===- PDBInfoStream.cpp - PDB Info Stream (Stream 1) Access ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+
+using namespace llvm;
+
+PDBInfoStream::PDBInfoStream(const PDBFile &File)
+    : Pdb(File), Stream1(1, File) {}
+
+std::error_code PDBInfoStream::reload() {
+  Stream1.setOffset(0);
+  support::ulittle32_t Value;
+
+  Stream1.readObject(&Version);
+  if (Version < PdbRaw_ImplVer::VC70)
+    return std::make_error_code(std::errc::not_supported);
+
+  Stream1.readObject(&Value);
+  Signature = Value;
+
+  Stream1.readObject(&Value);
+  Age = Value;
+
+  Stream1.readObject(&Guid);
+  NamedStreams.load(Stream1);
+
+  return std::error_code();
+}
+
+uint32_t PDBInfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
+  uint32_t Result;
+  if (!NamedStreams.tryGetValue(Name, Result))
+    return 0;
+  return Result;
+}
+
+PdbRaw_ImplVer PDBInfoStream::getVersion() const {
+  return static_cast<PdbRaw_ImplVer>(Version);
+}
+
+uint32_t PDBInfoStream::getSignature() const { return Signature; }
+
+uint32_t PDBInfoStream::getAge() const { return Age; }
+
+PDB_UniqueId PDBInfoStream::getGuid() const { return Guid; }

Added: llvm/trunk/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp?rev=267564&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp Tue Apr 26 11:20:00 2016
@@ -0,0 +1,108 @@
+//===- PDBNameMap.cpp - PDB Name Map ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/PDBNameMap.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBStream.h"
+
+using namespace llvm;
+
+PDBNameMap::PDBNameMap() {}
+
+std::error_code PDBNameMap::load(PDBStream &Stream) {
+  // This is some sort of weird string-set/hash table encoded in the stream.
+  // It starts with the number of bytes in the table.
+  uint32_t NumberOfBytes;
+  Stream.readInteger(NumberOfBytes);
+
+  // Following that field is the starting offset of strings in the name table.
+  uint32_t StringsOffset = Stream.getOffset();
+  Stream.setOffset(StringsOffset + NumberOfBytes);
+
+  // This appears to be equivalent to the total number of strings *actually*
+  // in the name table.
+  uint32_t HashSize;
+  Stream.readInteger(HashSize);
+
+  // This appears to be an upper bound on the number of strings in the name
+  // table.
+  uint32_t MaxNumberOfStrings;
+  Stream.readInteger(MaxNumberOfStrings);
+
+  // This appears to be a hash table which uses bitfields to determine whether
+  // or not a bucket is 'present'.
+  uint32_t NumPresentWords;
+  Stream.readInteger(NumPresentWords);
+
+  // Store all the 'present' bits in a vector for later processing.
+  SmallVector<uint32_t, 1> PresentWords;
+  for (uint32_t I = 0; I != NumPresentWords; ++I) {
+    uint32_t Word;
+    Stream.readInteger(Word);
+    PresentWords.push_back(Word);
+  }
+
+  // This appears to be a hash table which uses bitfields to determine whether
+  // or not a bucket is 'deleted'.
+  uint32_t NumDeletedWords;
+  Stream.readInteger(NumDeletedWords);
+
+  // Store all the 'deleted' bits in a vector for later processing.
+  SmallVector<uint32_t, 1> DeletedWords;
+  for (uint32_t I = 0; I != NumDeletedWords; ++I) {
+    uint32_t Word;
+    Stream.readInteger(Word);
+    DeletedWords.push_back(Word);
+  }
+
+  BitVector Present(MaxNumberOfStrings, false);
+  if (!PresentWords.empty())
+    Present.setBitsInMask(PresentWords.data(), PresentWords.size());
+  BitVector Deleted(MaxNumberOfStrings, false);
+  if (!DeletedWords.empty())
+    Deleted.setBitsInMask(DeletedWords.data(), DeletedWords.size());
+
+  for (uint32_t I = 0; I < MaxNumberOfStrings; ++I) {
+    if (!Present.test(I))
+      continue;
+
+    // For all present entries, dump out their mapping.
+
+    // This appears to be an offset relative to the start of the strings.
+    // It tells us where the null-terminated string begins.
+    uint32_t NameOffset;
+    Stream.readInteger(NameOffset);
+
+    // This appears to be a stream number into the stream directory.
+    uint32_t NameIndex;
+    Stream.readInteger(NameIndex);
+
+    // Compute the offset of the start of the string relative to the stream.
+    uint32_t StringOffset = StringsOffset + NameOffset;
+    uint32_t OldOffset = Stream.getOffset();
+    // Pump out our c-string from the stream.
+    std::string Str;
+    Stream.setOffset(StringOffset);
+    Stream.readZeroString(Str);
+
+    Stream.setOffset(OldOffset);
+    // Add this to a string-map from name to stream number.
+    Mapping.insert({Str, NameIndex});
+  }
+
+  return std::error_code();
+}
+
+bool PDBNameMap::tryGetValue(StringRef Name, uint32_t &Value) const {
+  auto Iter = Mapping.find(Name);
+  if (Iter == Mapping.end())
+    return false;
+  Value = Iter->second;
+  return true;
+}

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=267564&r1=267563&r2=267564&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Tue Apr 26 11:20:00 2016
@@ -14,23 +14,6 @@
 ; CHECK-NEXT: Signature: 54e507e2
 ; CHECK-NEXT: Age: 1
 ; CHECK-NEXT: Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
-; CHECK-NEXT: NumberOfBytes: 34
-; CHECK-NEXT: HashSize: 3
-; CHECK-NEXT: MaxNumberOfStrings: 6
-; CHECK-NEXT: NumPresentWords: 1
-; CHECK-NEXT: Word: 26
-; CHECK-NEXT: NumDeletedWords: 0
-; CHECK-NEXT: NameOffset: 17
-; CHECK-NEXT: NameIndex: 9
-; CHECK-NEXT: String: /src/headerblock
-
-; CHECK:      NameOffset: 10
-; CHECK-NEXT: NameIndex: 13
-; CHECK-NEXT: String: /names
-
-; CHECK:      NameOffset: 0
-; CHECK-NEXT: NameIndex: 5
-; CHECK-NEXT: String: /LinkInfo
 
 ; CHECK:      NameStream: 13
 ; CHECK-NEXT: NameStreamSignature: effeeffe

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=267564&r1=267563&r2=267564&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Tue Apr 26 11:20:00 2016
@@ -36,6 +36,7 @@
 #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
 #include "llvm/DebugInfo/PDB/Raw/PDBStream.h"
 #include "llvm/DebugInfo/PDB/Raw/RawSession.h"
 #include "llvm/Support/CommandLine.h"
@@ -233,135 +234,21 @@ static void dumpStructure(RawSession &RS
     }
   }
 
-  // Stream 1 starts with the following header:
-  //   uint32_t Version;
-  //   uint32_t Signature;
-  //   uint32_t Age;
-  //   GUID Guid;
-  PDBStream Stream1(1, File);
-  uint32_t Version;
-  uint32_t Signature;
-  uint32_t Age;
-  PDB_UniqueId Guid;
-
-  Stream1.readInteger(Version);
-  outs() << "Version: " << Version << '\n';
-  // PDB's with versions before PDBImpvVC70 might not have the Guid field, we
-  // don't support them.
-  if (Version < 20000404)
-    reportError("", std::make_error_code(std::errc::not_supported));
-
-  // This appears to be the time the PDB was last opened by an MSVC tool?
-  // It is definitely a timestamp of some sort.
-  Stream1.readInteger(Signature);
-  outs() << "Signature: ";
-  outs().write_hex(Signature) << '\n';
-
-  // This appears to be a number which is used to determine that the PDB is kept
-  // in sync with the EXE.
-  Stream1.readInteger(Age);
-  outs() << "Age: " << Age << '\n';
-
-  // I'm not sure what the purpose of the GUID is.
-  Stream1.readObject(&Guid);
-  outs() << "Guid: " << Guid << '\n';
-
-  // This is some sort of weird string-set/hash table encoded in the stream.
-  // It starts with the number of bytes in the table.
-  uint32_t NumberOfBytes;
-  Stream1.readInteger(NumberOfBytes);
-  outs() << "NumberOfBytes: " << NumberOfBytes << '\n';
-
-  // Following that field is the starting offset of strings in the name table.
-  uint32_t StringsOffset = Stream1.getOffset();
-  Stream1.setOffset(StringsOffset + NumberOfBytes);
-
-  // This appears to be equivalent to the total number of strings *actually*
-  // in the name table.
-  uint32_t HashSize;
-  Stream1.readInteger(HashSize);
-  outs() << "HashSize: " << HashSize << '\n';
-
-  // This appears to be an upper bound on the number of strings in the name
-  // table.
-  uint32_t MaxNumberOfStrings;
-  Stream1.readInteger(MaxNumberOfStrings);
-  outs() << "MaxNumberOfStrings: " << MaxNumberOfStrings << '\n';
-
-  // This appears to be a hash table which uses bitfields to determine whether
-  // or not a bucket is 'present'.
-  uint32_t NumPresentWords;
-  Stream1.readInteger(NumPresentWords);
-  outs() << "NumPresentWords: " << NumPresentWords << '\n';
-
-  // Store all the 'present' bits in a vector for later processing.
-  SmallVector<uint32_t, 1> PresentWords;
-  for (uint32_t I = 0; I != NumPresentWords; ++I) {
-    uint32_t Word;
-    Stream1.readInteger(Word);
-    PresentWords.push_back(Word);
-    outs() << "Word: " << Word << '\n';
-  }
+  PDBInfoStream InfoStream(File);
+  if (auto EC = InfoStream.reload())
+    reportError("", EC);
 
-  // This appears to be a hash table which uses bitfields to determine whether
-  // or not a bucket is 'deleted'.
-  uint32_t NumDeletedWords;
-  Stream1.readInteger(NumDeletedWords);
-  outs() << "NumDeletedWords: " << NumDeletedWords << '\n';
-
-  // Store all the 'deleted' bits in a vector for later processing.
-  SmallVector<uint32_t, 1> DeletedWords;
-  for (uint32_t I = 0; I != NumDeletedWords; ++I) {
-    uint32_t Word;
-    Stream1.readInteger(Word);
-    DeletedWords.push_back(Word);
-    outs() << "Word: " << Word << '\n';
-  }
-
-  BitVector Present(MaxNumberOfStrings, false);
-  if (!PresentWords.empty())
-    Present.setBitsInMask(PresentWords.data(), PresentWords.size());
-  BitVector Deleted(MaxNumberOfStrings, false);
-  if (!DeletedWords.empty())
-    Deleted.setBitsInMask(DeletedWords.data(), DeletedWords.size());
-
-  StringMap<uint32_t> NamedStreams;
-  for (uint32_t I = 0; I < MaxNumberOfStrings; ++I) {
-    if (!Present.test(I))
-      continue;
-
-    // For all present entries, dump out their mapping.
-
-    // This appears to be an offset relative to the start of the strings.
-    // It tells us where the null-terminated string begins.
-    uint32_t NameOffset;
-    Stream1.readInteger(NameOffset);
-    outs() << "NameOffset: " << NameOffset << '\n';
-
-    // This appears to be a stream number into the stream directory.
-    uint32_t NameIndex;
-    Stream1.readInteger(NameIndex);
-    outs() << "NameIndex: " << NameIndex << '\n';
-
-    // Compute the offset of the start of the string relative to the stream.
-    uint32_t StringOffset = StringsOffset + NameOffset;
-    uint32_t OldOffset = Stream1.getOffset();
-    // Pump out our c-string from the stream.
-    std::string Str;
-    Stream1.setOffset(StringOffset);
-    Stream1.readZeroString(Str);
-    outs() << "String: " << Str << "\n\n";
-
-    Stream1.setOffset(OldOffset);
-    // Add this to a string-map from name to stream number.
-    NamedStreams.insert({Str, NameIndex});
-  }
+  outs() << "Version: " << InfoStream.getVersion() << '\n';
+  outs() << "Signature: ";
+  outs().write_hex(InfoStream.getSignature()) << '\n';
+  outs() << "Age: " << InfoStream.getAge() << '\n';
+  outs() << "Guid: " << InfoStream.getGuid() << '\n';
 
   // Let's try to dump out the named stream "/names".
-  auto NameI = NamedStreams.find("/names");
-  if (NameI != NamedStreams.end()) {
-    PDBStream NameStream(NameI->second, File);
-    outs() << "NameStream: " << NameI->second << '\n';
+  uint32_t NameStreamIndex = InfoStream.getNamedStreamIndex("/names");
+  if (NameStreamIndex != 0) {
+    PDBStream NameStream(NameStreamIndex, File);
+    outs() << "NameStream: " << NameStreamIndex << '\n';
 
     // The name stream appears to start with a signature and version.
     uint32_t NameStreamSignature;




More information about the llvm-commits mailing list