[llvm] r342415 - [PDB] Make the native reader support enumerators.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 17 14:08:12 PDT 2018


Author: zturner
Date: Mon Sep 17 14:08:11 2018
New Revision: 342415

URL: http://llvm.org/viewvc/llvm-project?rev=342415&view=rev
Log:
[PDB] Make the native reader support enumerators.

Previously we would dump the names of enum types, but not their
enumerator values.  This adds support for enumerator values.  In
doing so, we have to introduce a general purpose mechanism for
caching symbol indices of field list members.  Unlike global
types, FieldList members do not have a TypeIndex.  So instead,
we identify them by the pair {TypeIndexOfFieldList, IndexInFieldList}.

Added:
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
    llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.cpp
    llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.pdb   (with props)
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
    llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
    llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp
    llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp
    llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-enums.test
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h Mon Sep 17 14:08:11 2018
@@ -29,6 +29,21 @@ public:
   virtual void reset() = 0;
 };
 
+template <typename ChildType>
+class NullEnumerator : public IPDBEnumChildren<ChildType> {
+  virtual uint32_t getChildCount() const override { return 0; }
+  virtual std::unique_ptr<ChildType>
+  getChildAtIndex(uint32_t Index) const override {
+    assert(false);
+    return nullptr;
+  }
+  virtual std::unique_ptr<ChildType> getNext() override {
+    assert(false);
+    return nullptr;
+  }
+  virtual void reset() override {}
+};
+
 } // end namespace pdb
 } // end namespace llvm
 

Added: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h?rev=342415&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h Mon Sep 17 14:08:11 2018
@@ -0,0 +1,50 @@
+//===- NativeSymbolEnumerator.h - info about enumerator values --*- 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_NATIVE_NATIVESYMBOLENUMERATOR_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVESYMBOLENUMERATOR_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+class NativeTypeEnum;
+
+class NativeSymbolEnumerator : public NativeRawSymbol {
+public:
+  NativeSymbolEnumerator(NativeSession &Session, SymIndexId Id,
+                         const NativeTypeEnum &Parent,
+                         codeview::EnumeratorRecord Record);
+
+  ~NativeSymbolEnumerator() override;
+
+  void dump(raw_ostream &OS, int Indent) const override;
+
+  SymIndexId getClassParentId() const override;
+  SymIndexId getLexicalParentId() const override;
+  std::string getName() const override;
+  SymIndexId getTypeId() const override;
+  PDB_DataKind getDataKind() const override;
+  PDB_LocType getLocationType() const override;
+  bool isConstType() const override;
+  bool isVolatileType() const override;
+  bool isUnalignedType() const override;
+  Variant getValue() const override;
+
+protected:
+  const NativeTypeEnum &Parent;
+  codeview::EnumeratorRecord Record;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEENUM_H

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeEnum.h Mon Sep 17 14:08:11 2018
@@ -18,6 +18,8 @@
 namespace llvm {
 namespace pdb {
 
+class NativeTypeBuiltin;
+
 class NativeTypeEnum : public NativeRawSymbol {
 public:
   NativeTypeEnum(NativeSession &Session, SymIndexId Id, codeview::TypeIndex TI,
@@ -56,6 +58,8 @@ public:
   bool isValueUdt() const override;
   bool isInterfaceUdt() const override;
 
+  const NativeTypeBuiltin &getUnderlyingBuiltinType() const;
+
 protected:
   codeview::TypeIndex Index;
   codeview::EnumRecord Record;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h Mon Sep 17 14:08:11 2018
@@ -31,6 +31,8 @@ class SymbolCache {
 
   std::vector<std::unique_ptr<NativeRawSymbol>> Cache;
   DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId;
+  DenseMap<std::pair<codeview::TypeIndex, uint32_t>, SymIndexId>
+      FieldListMembersToSymbolId;
   std::vector<SymIndexId> Compilands;
 
   SymIndexId createSymbolPlaceholder() {
@@ -77,6 +79,23 @@ public:
 
   SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);
 
+  template <typename ConcreteSymbolT, typename... Args>
+  SymIndexId getOrCreateFieldListMember(codeview::TypeIndex FieldListTI,
+                                        uint32_t Index,
+                                        Args &&... ConstructorArgs) {
+    SymIndexId SymId = Cache.size();
+    std::pair<codeview::TypeIndex, uint32_t> Key{FieldListTI, Index};
+    auto Result = FieldListMembersToSymbolId.try_emplace(Key, SymId);
+    if (Result.second) {
+      auto NewSymbol = llvm::make_unique<ConcreteSymbolT>(
+          Session, SymId, std::forward<Args>(ConstructorArgs)...);
+      Cache.push_back(std::move(NewSymbol));
+    } else {
+      SymId = Result.first->second;
+    }
+    return SymId;
+  }
+
   std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
   uint32_t getNumCompilands() const;
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h Mon Sep 17 14:08:11 2018
@@ -336,6 +336,36 @@ enum PDB_VariantType {
 struct Variant {
   Variant() = default;
 
+  explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; }
+  explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; }
+  explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) {
+    Value.Int16 = V;
+  }
+  explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) {
+    Value.Int32 = V;
+  }
+  explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) {
+    Value.Int64 = V;
+  }
+  explicit Variant(float V) : Type(PDB_VariantType::Single) {
+    Value.Single = V;
+  }
+  explicit Variant(double V) : Type(PDB_VariantType::Double) {
+    Value.Double = V;
+  }
+  explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) {
+    Value.UInt8 = V;
+  }
+  explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) {
+    Value.UInt16 = V;
+  }
+  explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) {
+    Value.UInt32 = V;
+  }
+  explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) {
+    Value.UInt64 = V;
+  }
+
   Variant(const Variant &Other) {
     *this = Other;
   }

Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Mon Sep 17 14:08:11 2018
@@ -51,6 +51,7 @@ add_pdb_impl_folder(Native
   Native/NativeEnumTypes.cpp
   Native/NativeExeSymbol.cpp
   Native/NativeRawSymbol.cpp
+  Native/NativeSymbolEnumerator.cpp
   Native/NativeTypeBuiltin.cpp
   Native/NativeTypeEnum.cpp
   Native/NativeTypePointer.cpp

Modified: llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp Mon Sep 17 14:08:11 2018
@@ -141,6 +141,15 @@ PrivateGetDIAValue(IDiaSymbol *Symbol,
   return IdResult;
 }
 
+template <typename PrintType, typename ArgType>
+void DumpDIAValueAs(llvm::raw_ostream &OS, int Indent, StringRef Name,
+                    IDiaSymbol *Symbol,
+                    HRESULT (__stdcall IDiaSymbol::*Method)(ArgType *)) {
+  ArgType Value;
+  if (S_OK == (Symbol->*Method)(&Value))
+    dumpSymbolField(OS, Name, static_cast<PrintType>(Value), Indent);
+}
+
 template <typename ArgType>
 void DumpDIAValue(llvm::raw_ostream &OS, int Indent, StringRef Name,
                   IDiaSymbol *Symbol,
@@ -194,6 +203,10 @@ DIARawSymbol::DIARawSymbol(const DIASess
   DumpDIAValue(Stream, Indent, StringRef{#Method}, Symbol,                     \
                &IDiaSymbol::get_##Method);
 
+#define RAW_METHOD_DUMP_AS(Stream, Method, Type)                               \
+  DumpDIAValueAs<Type>(Stream, Indent, StringRef{#Method}, Symbol,             \
+                       &IDiaSymbol::get_##Method);
+
 void DIARawSymbol::dump(raw_ostream &OS, int Indent) const {
   RAW_METHOD_DUMP(OS, symIndexId);
   RAW_METHOD_DUMP(OS, symTag);
@@ -267,12 +280,12 @@ void DIARawSymbol::dump(raw_ostream &OS,
   RAW_METHOD_DUMP(OS, virtualBaseDispIndex);
   RAW_METHOD_DUMP(OS, virtualBaseOffset);
   RAW_METHOD_DUMP(OS, virtualTableShapeId);
-  RAW_METHOD_DUMP(OS, dataKind);
+  RAW_METHOD_DUMP_AS(OS, dataKind, PDB_DataKind);
   RAW_METHOD_DUMP(OS, guid);
   RAW_METHOD_DUMP(OS, offset);
   RAW_METHOD_DUMP(OS, thisAdjust);
   RAW_METHOD_DUMP(OS, virtualBasePointerOffset);
-  RAW_METHOD_DUMP(OS, locationType);
+  RAW_METHOD_DUMP_AS(OS, locationType, PDB_LocType);
   RAW_METHOD_DUMP(OS, machineType);
   RAW_METHOD_DUMP(OS, thunkOrdinal);
   RAW_METHOD_DUMP(OS, length);

Added: llvm/trunk/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp?rev=342415&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp Mon Sep 17 14:08:11 2018
@@ -0,0 +1,116 @@
+//===- NativeSymbolEnumerator.cpp - info about enumerators ------*- 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/Native/NativeSymbolEnumerator.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeSymbolEnumerator::NativeSymbolEnumerator(
+    NativeSession &Session, SymIndexId Id, const NativeTypeEnum &Parent,
+    codeview::EnumeratorRecord Record)
+    : NativeRawSymbol(Session, PDB_SymType::Data, Id), Parent(Parent),
+      Record(std::move(Record)) {}
+
+NativeSymbolEnumerator::~NativeSymbolEnumerator() {}
+
+void NativeSymbolEnumerator::dump(raw_ostream &OS, int Indent) const {
+  NativeRawSymbol::dump(OS, Indent);
+  dumpSymbolField(OS, "classParentId", getClassParentId(), Indent);
+  dumpSymbolField(OS, "lexicalParentId", getLexicalParentId(), Indent);
+  dumpSymbolField(OS, "name", getName(), Indent);
+  dumpSymbolField(OS, "typeId", getTypeId(), Indent);
+  dumpSymbolField(OS, "dataKind", getDataKind(), Indent);
+  dumpSymbolField(OS, "locationType", getLocationType(), Indent);
+  dumpSymbolField(OS, "constType", isConstType(), Indent);
+  dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+  dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+  dumpSymbolField(OS, "value", getValue(), Indent);
+}
+
+SymIndexId NativeSymbolEnumerator::getClassParentId() const {
+  return Parent.getSymIndexId();
+}
+
+SymIndexId NativeSymbolEnumerator::getLexicalParentId() const { return 0; }
+
+std::string NativeSymbolEnumerator::getName() const { return Record.Name; }
+
+SymIndexId NativeSymbolEnumerator::getTypeId() const {
+  return Parent.getTypeId();
+}
+
+PDB_DataKind NativeSymbolEnumerator::getDataKind() const {
+  return PDB_DataKind::Constant;
+}
+
+PDB_LocType NativeSymbolEnumerator::getLocationType() const {
+  return PDB_LocType::Constant;
+}
+
+bool NativeSymbolEnumerator::isConstType() const { return false; }
+
+bool NativeSymbolEnumerator::isVolatileType() const { return false; }
+
+bool NativeSymbolEnumerator::isUnalignedType() const { return false; }
+
+Variant NativeSymbolEnumerator::getValue() const {
+  const NativeTypeBuiltin &BT = Parent.getUnderlyingBuiltinType();
+
+  switch (BT.getBuiltinType()) {
+  case PDB_BuiltinType::Int:
+  case PDB_BuiltinType::Long:
+  case PDB_BuiltinType::Char: {
+    assert(Record.Value.isSignedIntN(BT.getLength() * 8));
+    int64_t N = Record.Value.getSExtValue();
+    switch (BT.getLength()) {
+    case 1:
+      return Variant{static_cast<int8_t>(N)};
+    case 2:
+      return Variant{static_cast<int16_t>(N)};
+    case 4:
+      return Variant{static_cast<int32_t>(N)};
+    case 8:
+      return Variant{static_cast<int64_t>(N)};
+    }
+    break;
+  }
+  case PDB_BuiltinType::UInt:
+  case PDB_BuiltinType::ULong: {
+    assert(Record.Value.isIntN(BT.getLength() * 8));
+    uint64_t U = Record.Value.getZExtValue();
+    switch (BT.getLength()) {
+    case 1:
+      return Variant{static_cast<uint8_t>(U)};
+    case 2:
+      return Variant{static_cast<uint16_t>(U)};
+    case 4:
+      return Variant{static_cast<uint32_t>(U)};
+    case 8:
+      return Variant{static_cast<uint64_t>(U)};
+    }
+    break;
+  }
+  case PDB_BuiltinType::Bool: {
+    assert(Record.Value.isIntN(BT.getLength() * 8));
+    uint64_t U = Record.Value.getZExtValue();
+    return Variant{static_cast<bool>(U)};
+  }
+  default:
+    assert(false && "Invalid enumeration type");
+    break;
+  }
+
+  return Variant{Record.Value.getSExtValue()};
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp Mon Sep 17 14:08:11 2018
@@ -12,7 +12,11 @@
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
 
 #include "llvm/Support/FormatVariadic.h"
@@ -23,6 +27,95 @@ using namespace llvm;
 using namespace llvm::codeview;
 using namespace llvm::pdb;
 
+namespace {
+// Yea, this is a pretty terrible class name.  But if we have an enum:
+//
+// enum Foo {
+//  A,
+//  B
+// };
+//
+// then A and B are the "enumerators" of the "enum" Foo.  And we need
+// to enumerate them.
+class NativeEnumEnumEnumerators : public IPDBEnumSymbols, TypeVisitorCallbacks {
+public:
+  NativeEnumEnumEnumerators(NativeSession &Session,
+                            const NativeTypeEnum &ClassParent,
+                            const codeview::EnumRecord &CVEnum);
+
+  uint32_t getChildCount() const override;
+  std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
+  std::unique_ptr<PDBSymbol> getNext() override;
+  void reset() override;
+
+private:
+  Error visitKnownMember(CVMemberRecord &CVM,
+                         EnumeratorRecord &Record) override;
+  Error visitKnownMember(CVMemberRecord &CVM,
+                         ListContinuationRecord &Record) override;
+
+  NativeSession &Session;
+  const NativeTypeEnum &ClassParent;
+  const codeview::EnumRecord &CVEnum;
+  std::vector<EnumeratorRecord> Enumerators;
+  Optional<TypeIndex> ContinuationIndex;
+  uint32_t Index = 0;
+};
+} // namespace
+
+NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
+    NativeSession &Session, const NativeTypeEnum &ClassParent,
+    const codeview::EnumRecord &CVEnum)
+    : Session(Session), ClassParent(ClassParent), CVEnum(CVEnum) {
+  TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
+  LazyRandomTypeCollection &Types = Tpi.typeCollection();
+
+  ContinuationIndex = CVEnum.FieldList;
+  while (ContinuationIndex) {
+    CVType FieldList = Types.getType(*ContinuationIndex);
+    assert(FieldList.kind() == LF_FIELDLIST);
+    ContinuationIndex.reset();
+    cantFail(visitMemberRecordStream(FieldList.data(), *this));
+  }
+}
+
+Error NativeEnumEnumEnumerators::visitKnownMember(CVMemberRecord &CVM,
+                                                  EnumeratorRecord &Record) {
+  Enumerators.push_back(Record);
+  return Error::success();
+}
+
+Error NativeEnumEnumEnumerators::visitKnownMember(
+    CVMemberRecord &CVM, ListContinuationRecord &Record) {
+  ContinuationIndex = Record.ContinuationIndex;
+  return Error::success();
+}
+
+uint32_t NativeEnumEnumEnumerators::getChildCount() const {
+  return Enumerators.size();
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumEnumEnumerators::getChildAtIndex(uint32_t Index) const {
+  if (Index >= getChildCount())
+    return nullptr;
+
+  SymIndexId Id =
+      Session.getSymbolCache()
+          .getOrCreateFieldListMember<NativeSymbolEnumerator>(
+              CVEnum.FieldList, Index, ClassParent, Enumerators[Index]);
+  return Session.getSymbolCache().getSymbolById(Id);
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumEnumEnumerators::getNext() {
+  if (Index >= getChildCount())
+    return nullptr;
+
+  return getChildAtIndex(Index++);
+}
+
+void NativeEnumEnumEnumerators::reset() { Index = 0; }
+
 NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
                                TypeIndex Index, EnumRecord Record)
     : NativeRawSymbol(Session, PDB_SymType::Enum, Id), Index(Index),
@@ -67,14 +160,20 @@ void NativeTypeEnum::dump(raw_ostream &O
 
 std::unique_ptr<IPDBEnumSymbols>
 NativeTypeEnum::findChildren(PDB_SymType Type) const {
-  switch (Type) {
-  case PDB_SymType::Data: {
-    // TODO(amccarth) :  Provide an actual implementation.
-    return nullptr;
-  }
-  default:
-    return nullptr;
+  if (Type != PDB_SymType::Data)
+    return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+
+  const NativeTypeEnum *ClassParent = nullptr;
+  if (!Modifiers)
+    ClassParent = this;
+  else {
+    NativeRawSymbol &NRS =
+        Session.getSymbolCache().getNativeSymbolById(getUnmodifiedTypeId());
+    assert(NRS.getSymTag() == PDB_SymType::Enum);
+    ClassParent = static_cast<NativeTypeEnum *>(&NRS);
   }
+  return llvm::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent,
+                                                      Record);
 }
 
 PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
@@ -86,8 +185,9 @@ PDB_BuiltinType NativeTypeEnum::getBuilt
 
   // This indicates a corrupt record.
   if (!Underlying.isSimple() ||
-      Underlying.getSimpleMode() != SimpleTypeMode::Direct)
+      Underlying.getSimpleMode() != SimpleTypeMode::Direct) {
     return PDB_BuiltinType::None;
+  }
 
   switch (Underlying.getSimpleKind()) {
   case SimpleTypeKind::Boolean128:
@@ -98,6 +198,7 @@ PDB_BuiltinType NativeTypeEnum::getBuilt
     return PDB_BuiltinType::Bool;
   case SimpleTypeKind::NarrowCharacter:
   case SimpleTypeKind::UnsignedCharacter:
+  case SimpleTypeKind::SignedCharacter:
     return PDB_BuiltinType::Char;
   case SimpleTypeKind::WideCharacter:
     return PDB_BuiltinType::WCharT;
@@ -149,6 +250,7 @@ PDB_BuiltinType NativeTypeEnum::getBuilt
 SymIndexId NativeTypeEnum::getUnmodifiedTypeId() const {
   if (!Modifiers)
     return 0;
+
   return Session.getSymbolCache().findSymbolByTypeIndex(
       Modifiers->ModifiedType);
 }
@@ -235,3 +337,8 @@ bool NativeTypeEnum::isUnalignedType() c
   return ((Modifiers->getModifiers() & ModifierOptions::Unaligned) !=
           ModifierOptions::None);
 }
+
+const NativeTypeBuiltin &NativeTypeEnum::getUnderlyingBuiltinType() const {
+  return Session.getSymbolCache().getNativeSymbolById<NativeTypeBuiltin>(
+      getTypeId());
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp Mon Sep 17 14:08:11 2018
@@ -26,14 +26,17 @@ static const struct BuiltinTypeEntry {
   PDB_BuiltinType Type;
   uint32_t Size;
 } BuiltinTypes[] = {
+    {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
+    {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
     {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
     {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
+    {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4},
     {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
+    {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8},
     {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
     {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
     {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
     {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
-    {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
     {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1}
     // This table can be grown as necessary, but these are the only types we've
     // needed so far.
@@ -169,6 +172,8 @@ SymIndexId SymbolCache::findSymbolByType
 
 std::unique_ptr<PDBSymbol>
 SymbolCache::getSymbolById(SymIndexId SymbolId) const {
+  assert(SymbolId < Cache.size());
+
   // Id 0 is reserved.
   if (SymbolId == 0)
     return nullptr;

Modified: llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp Mon Sep 17 14:08:11 2018
@@ -293,7 +293,7 @@ raw_ostream &llvm::pdb::operator<<(raw_o
       OS << Value.Value.Single;
       break;
     case PDB_VariantType::UInt16:
-      OS << Value.Value.Double;
+      OS << Value.Value.UInt16;
       break;
     case PDB_VariantType::UInt32:
       OS << Value.Value.UInt32;

Added: llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.cpp?rev=342415&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.cpp (added)
+++ llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.cpp Mon Sep 17 14:08:11 2018
@@ -0,0 +1,110 @@
+// Build with "cl.exe /Zi /GR- /GX- every-enum.cpp /link /debug /nodefaultlib /incremental:no /entry:main"
+
+#include <stdint.h>
+
+// clang-format off
+void *__purecall = 0;
+
+void __cdecl operator delete(void *,unsigned int) {}
+void __cdecl operator delete(void *,unsigned __int64) {}
+
+
+enum I8 : int8_t {
+  I8A = INT8_MIN,
+  I8B = 0,
+  I8C = INT8_MAX
+};
+
+enum I16 : int16_t {
+  I16A = INT16_MIN,
+  I16B = 0,
+  I16C = INT16_MAX,
+};
+
+enum I32 : int32_t {
+  I32A = INT32_MIN,
+  I32B = 0,
+  I32C = INT32_MAX,
+};
+
+enum I64 : int64_t {
+  I64A = INT64_MIN,
+  I64B = 0,
+  I64C = INT64_MAX,
+};
+
+enum U8 : uint8_t {
+  U8A = 0,
+  U8B = UINT8_MAX
+};
+
+enum U16 : uint16_t {
+  U16A = 0,
+  U16B = UINT16_MAX,
+};
+
+enum U32 : uint32_t {
+  U32A = 0,
+  U32B = UINT32_MAX,
+};
+
+enum U64 : uint64_t {
+  U64A = 0,
+  U64B = UINT64_MAX,
+};
+
+enum Char16 : char16_t {
+  C16A = u'a',
+  C16B = u'b',
+};
+
+enum Char32 : char32_t {
+  C32A = U'a',
+  C32B = U'b',
+};
+
+enum WChar : wchar_t {
+  WCA = L'a',
+  WCB = L'b',
+};
+
+enum Bool : bool {
+  BA = true,
+  BB = false
+};
+
+enum class EC {
+  A = 1,
+  B = 2
+};
+
+struct Struct {
+  enum Nested {
+    A = 1,
+    B = 2
+  };
+};
+
+template<typename T> void f(T t) {}
+
+int main(int argc, char **argv) {
+  f(I8A);
+  f(I16A);
+  f(I32A);
+  f(I64A);
+  f(U8A);
+  f(U16A);
+  f(U32A);
+  f(U64A);
+
+  f(C16A);
+  f(C32A);
+  f(WCA);
+  f(BA);
+
+
+  f(EC::A);
+  f(Struct::A);
+
+  f<const volatile EC>(EC::A);
+}

Added: llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.pdb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.pdb?rev=342415&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/PDB/Inputs/every-enum.pdb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-enums.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-enums.test?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-enums.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-enums.test Mon Sep 17 14:08:11 2018
@@ -1,250 +1,916 @@
-; Test that the native PDB reader can enumerate the enum types.
-; RUN: llvm-pdbutil pretty -native -enums %p/../Inputs/every-type.pdb \
+; Test that the native PDB reader can enumerate the enum types.  The output
+; being checked against is golden output generated by llvm-pdbutil without
+; the -native flag.  Then we check that we generate the same output.
+; Unfortunately since we generate a slightly different (albeit correct)
+; class / parent hierarchy, if you re-generate this file you will need to
+; actually use the output from llvm-pdbutil *with* the -native flag, but
+; before "blessing" it, manually diff against the golden output from
+; llvm-pdbutil without the -native flag and verifying that there are no
+; substantive differences aside from the various symbol ids.
+
+; RUN: llvm-pdbutil pretty -native -enums %p/../Inputs/every-enum.pdb \
 ; RUN:   | FileCheck -check-prefix=ENUMS %s
-; RUN: llvm-pdbutil diadump -native -enums %p/../Inputs/every-type.pdb \
+; RUN: llvm-pdbutil diadump -native -enums %p/../Inputs/every-enum.pdb \
 ; RUN:   | FileCheck -check-prefix=DUMP %s
 
-ENUMS:  enum FooClass::NestedEnum {
-ENUMS-NEXT:  }
-ENUMS:  const volatile enum FooClass::NestedEnum
 
-DUMP:      {
-DUMP-NEXT:   symIndexId: 2
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: FooClass::NestedEnum
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 4
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::event_sourceAttribute::type_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 5
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::event_sourceAttribute::optimize_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 6
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::helper_attributes::v1_alttypeAttribute::type_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 7
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::helper_attributes::usageAttribute::usage_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 8
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::threadingAttribute::threading_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 9
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::aggregatableAttribute::type_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 10
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::event_receiverAttribute::type_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 11
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: __vc_attributes::moduleAttribute::type_e
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 0
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 0
-DUMP-NEXT: }
-DUMP-NEXT: {
-DUMP-NEXT:   symIndexId: 12
-DUMP-NEXT:   symTag: 12
-DUMP-NEXT:   baseType: 6
-DUMP-NEXT:   lexicalParentId: 0
-DUMP-NEXT:   name: FooClass::NestedEnum
-DUMP-NEXT:   typeId: 3
-DUMP-NEXT:   length: 4
-DUMP-NEXT:   constructor: 0
-DUMP-NEXT:   constType: 1
-DUMP-NEXT:   hasAssignmentOperator: 0
-DUMP-NEXT:   hasCastOperator: 0
-DUMP-NEXT:   hasNestedTypes: 0
-DUMP-NEXT:   overloadedOperator: 0
-DUMP-NEXT:   isInterfaceUdt: 0
-DUMP-NEXT:   intrinsic: 0
-DUMP-NEXT:   nested: 1
-DUMP-NEXT:   packed: 0
-DUMP-NEXT:   isRefUdt: 0
-DUMP-NEXT:   scoped: 0
-DUMP-NEXT:   unalignedType: 0
-DUMP-NEXT:   isValueUdt: 0
-DUMP-NEXT:   volatileType: 1
-DUMP-NEXT: }
+ENUMS: enum I8 : char {
+ENUMS:   I8A = -128
+ENUMS:   I8B = 0
+ENUMS:   I8C = 127
+ENUMS: }
+ENUMS: enum I16 : short {
+ENUMS:   I16A = -32768
+ENUMS:   I16B = 0
+ENUMS:   I16C = 32767
+ENUMS: }
+ENUMS: enum I32 {
+ENUMS:   I32A = -2147483648
+ENUMS:   I32B = 0
+ENUMS:   I32C = 2147483647
+ENUMS: }
+ENUMS: enum I64 : __int64 {
+ENUMS:   I64A = -9223372036854775808
+ENUMS:   I64B = 0
+ENUMS:   I64C = 9223372036854775807
+ENUMS: }
+ENUMS: enum U8 : unsigned char {
+ENUMS:   U8A = 0
+ENUMS:   U8B = 255
+ENUMS: }
+ENUMS: enum U16 : unsigned short {
+ENUMS:   U16A = 0
+ENUMS:   U16B = 65535
+ENUMS: }
+ENUMS: enum U32 : unsigned int {
+ENUMS:   U32A = 0
+ENUMS:   U32B = 4294967295
+ENUMS: }
+ENUMS: enum U64 : unsigned __int64 {
+ENUMS:   U64A = 0
+; FIXME: This should be UINT64_MAX.  Is the compiler encoding it wrong or
+; are we decoding it wrong?
+ENUMS:   U64B = 255
+ENUMS: }
+ENUMS: enum Char16 : unsigned short {
+ENUMS:   C16A = 97
+ENUMS:   C16B = 98
+ENUMS: }
+ENUMS: enum Char32 : unsigned int {
+ENUMS:   C32A = 97
+ENUMS:   C32B = 98
+ENUMS: }
+ENUMS: enum WChar : unsigned short {
+ENUMS:   WCA = 97
+ENUMS:   WCB = 98
+ENUMS: }
+ENUMS: enum Bool : bool {
+ENUMS:   BA = true
+ENUMS:   BB = false
+ENUMS: }
+ENUMS: enum EC {
+ENUMS:   A = 1
+ENUMS:   B = 2
+ENUMS: }
+ENUMS: enum Struct::Nested {
+ENUMS:   A = 1
+ENUMS:   B = 2
+ENUMS: }
+ENUMS: const volatile enum EC
+
+
+DUMP: {
+DUMP:   symIndexId: 2
+DUMP:   symTag: 12
+DUMP:   baseType: 2
+DUMP:   lexicalParentId: 0
+DUMP:   name: I8
+DUMP:   typeId: 3
+DUMP:   length: 1
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 4
+DUMP:     symTag: 7
+DUMP:     classParentId: 2
+DUMP:     lexicalParentId: 0
+DUMP:     name: I8A
+DUMP:     typeId: 3
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: -128
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 5
+DUMP:     symTag: 7
+DUMP:     classParentId: 2
+DUMP:     lexicalParentId: 0
+DUMP:     name: I8B
+DUMP:     typeId: 3
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 6
+DUMP:     symTag: 7
+DUMP:     classParentId: 2
+DUMP:     lexicalParentId: 0
+DUMP:     name: I8C
+DUMP:     typeId: 3
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 127
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 7
+DUMP:   symTag: 12
+DUMP:   baseType: 6
+DUMP:   lexicalParentId: 0
+DUMP:   name: I16
+DUMP:   typeId: 8
+DUMP:   length: 2
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 9
+DUMP:     symTag: 7
+DUMP:     classParentId: 7
+DUMP:     lexicalParentId: 0
+DUMP:     name: I16A
+DUMP:     typeId: 8
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: -32768
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 10
+DUMP:     symTag: 7
+DUMP:     classParentId: 7
+DUMP:     lexicalParentId: 0
+DUMP:     name: I16B
+DUMP:     typeId: 8
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 11
+DUMP:     symTag: 7
+DUMP:     classParentId: 7
+DUMP:     lexicalParentId: 0
+DUMP:     name: I16C
+DUMP:     typeId: 8
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 32767
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 12
+DUMP:   symTag: 12
+DUMP:   baseType: 6
+DUMP:   lexicalParentId: 0
+DUMP:   name: I32
+DUMP:   typeId: 13
+DUMP:   length: 4
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 14
+DUMP:     symTag: 7
+DUMP:     classParentId: 12
+DUMP:     lexicalParentId: 0
+DUMP:     name: I32A
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: -2147483648
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 15
+DUMP:     symTag: 7
+DUMP:     classParentId: 12
+DUMP:     lexicalParentId: 0
+DUMP:     name: I32B
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 16
+DUMP:     symTag: 7
+DUMP:     classParentId: 12
+DUMP:     lexicalParentId: 0
+DUMP:     name: I32C
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 2147483647
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 17
+DUMP:   symTag: 12
+DUMP:   baseType: 6
+DUMP:   lexicalParentId: 0
+DUMP:   name: I64
+DUMP:   typeId: 18
+DUMP:   length: 8
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 19
+DUMP:     symTag: 7
+DUMP:     classParentId: 17
+DUMP:     lexicalParentId: 0
+DUMP:     name: I64A
+DUMP:     typeId: 18
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: -9223372036854775808
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 20
+DUMP:     symTag: 7
+DUMP:     classParentId: 17
+DUMP:     lexicalParentId: 0
+DUMP:     name: I64B
+DUMP:     typeId: 18
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 21
+DUMP:     symTag: 7
+DUMP:     classParentId: 17
+DUMP:     lexicalParentId: 0
+DUMP:     name: I64C
+DUMP:     typeId: 18
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 9223372036854775807
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 22
+DUMP:   symTag: 12
+DUMP:   baseType: 2
+DUMP:   lexicalParentId: 0
+DUMP:   name: U8
+DUMP:   typeId: 23
+DUMP:   length: 1
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 24
+DUMP:     symTag: 7
+DUMP:     classParentId: 22
+DUMP:     lexicalParentId: 0
+DUMP:     name: U8A
+DUMP:     typeId: 23
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 25
+DUMP:     symTag: 7
+DUMP:     classParentId: 22
+DUMP:     lexicalParentId: 0
+DUMP:     name: U8B
+DUMP:     typeId: 23
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 255
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 26
+DUMP:   symTag: 12
+DUMP:   baseType: 7
+DUMP:   lexicalParentId: 0
+DUMP:   name: U16
+DUMP:   typeId: 27
+DUMP:   length: 2
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 28
+DUMP:     symTag: 7
+DUMP:     classParentId: 26
+DUMP:     lexicalParentId: 0
+DUMP:     name: U16A
+DUMP:     typeId: 27
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 29
+DUMP:     symTag: 7
+DUMP:     classParentId: 26
+DUMP:     lexicalParentId: 0
+DUMP:     name: U16B
+DUMP:     typeId: 27
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 65535
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 30
+DUMP:   symTag: 12
+DUMP:   baseType: 7
+DUMP:   lexicalParentId: 0
+DUMP:   name: U32
+DUMP:   typeId: 31
+DUMP:   length: 4
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 32
+DUMP:     symTag: 7
+DUMP:     classParentId: 30
+DUMP:     lexicalParentId: 0
+DUMP:     name: U32A
+DUMP:     typeId: 31
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 33
+DUMP:     symTag: 7
+DUMP:     classParentId: 30
+DUMP:     lexicalParentId: 0
+DUMP:     name: U32B
+DUMP:     typeId: 31
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 4294967295
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 34
+DUMP:   symTag: 12
+DUMP:   baseType: 7
+DUMP:   lexicalParentId: 0
+DUMP:   name: U64
+DUMP:   typeId: 35
+DUMP:   length: 8
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 36
+DUMP:     symTag: 7
+DUMP:     classParentId: 34
+DUMP:     lexicalParentId: 0
+DUMP:     name: U64A
+DUMP:     typeId: 35
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 0
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 37
+DUMP:     symTag: 7
+DUMP:     classParentId: 34
+DUMP:     lexicalParentId: 0
+DUMP:     name: U64B
+DUMP:     typeId: 35
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 255
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 38
+DUMP:   symTag: 12
+DUMP:   baseType: 7
+DUMP:   lexicalParentId: 0
+DUMP:   name: Char16
+DUMP:   typeId: 27
+DUMP:   length: 2
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 39
+DUMP:     symTag: 7
+DUMP:     classParentId: 38
+DUMP:     lexicalParentId: 0
+DUMP:     name: C16A
+DUMP:     typeId: 27
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 97
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 40
+DUMP:     symTag: 7
+DUMP:     classParentId: 38
+DUMP:     lexicalParentId: 0
+DUMP:     name: C16B
+DUMP:     typeId: 27
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 98
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 41
+DUMP:   symTag: 12
+DUMP:   baseType: 7
+DUMP:   lexicalParentId: 0
+DUMP:   name: Char32
+DUMP:   typeId: 42
+DUMP:   length: 4
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 43
+DUMP:     symTag: 7
+DUMP:     classParentId: 41
+DUMP:     lexicalParentId: 0
+DUMP:     name: C32A
+DUMP:     typeId: 42
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 97
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 44
+DUMP:     symTag: 7
+DUMP:     classParentId: 41
+DUMP:     lexicalParentId: 0
+DUMP:     name: C32B
+DUMP:     typeId: 42
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 98
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 45
+DUMP:   symTag: 12
+DUMP:   baseType: 7
+DUMP:   lexicalParentId: 0
+DUMP:   name: WChar
+DUMP:   typeId: 27
+DUMP:   length: 2
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 46
+DUMP:     symTag: 7
+DUMP:     classParentId: 45
+DUMP:     lexicalParentId: 0
+DUMP:     name: WCA
+DUMP:     typeId: 27
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 97
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 47
+DUMP:     symTag: 7
+DUMP:     classParentId: 45
+DUMP:     lexicalParentId: 0
+DUMP:     name: WCB
+DUMP:     typeId: 27
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 98
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 48
+DUMP:   symTag: 12
+DUMP:   baseType: 10
+DUMP:   lexicalParentId: 0
+DUMP:   name: Bool
+DUMP:   typeId: 49
+DUMP:   length: 1
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 50
+DUMP:     symTag: 7
+DUMP:     classParentId: 48
+DUMP:     lexicalParentId: 0
+DUMP:     name: BA
+DUMP:     typeId: 49
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: true
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 51
+DUMP:     symTag: 7
+DUMP:     classParentId: 48
+DUMP:     lexicalParentId: 0
+DUMP:     name: BB
+DUMP:     typeId: 49
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: false
+DUMP:   }
+DUMP: {
+DUMP:   symIndexId: 113
+DUMP:   symTag: 12
+DUMP:   baseType: 6
+DUMP:   lexicalParentId: 0
+DUMP:   name: EC
+DUMP:   typeId: 13
+DUMP:   length: 4
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 114
+DUMP:     symTag: 7
+DUMP:     classParentId: 113
+DUMP:     lexicalParentId: 0
+DUMP:     name: A
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 1
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 115
+DUMP:     symTag: 7
+DUMP:     classParentId: 113
+DUMP:     lexicalParentId: 0
+DUMP:     name: B
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 2
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 116
+DUMP:   symTag: 12
+DUMP:   baseType: 6
+DUMP:   lexicalParentId: 0
+DUMP:   name: Struct::Nested
+DUMP:   typeId: 13
+DUMP:   length: 4
+DUMP:   constructor: 0
+DUMP:   constType: 0
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 1
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 0
+DUMP:   {
+DUMP:     symIndexId: 114
+DUMP:     symTag: 7
+DUMP:     classParentId: 113
+DUMP:     lexicalParentId: 0
+DUMP:     name: A
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 1
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 115
+DUMP:     symTag: 7
+DUMP:     classParentId: 113
+DUMP:     lexicalParentId: 0
+DUMP:     name: B
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 2
+DUMP:   }
+DUMP: }
+DUMP: {
+DUMP:   symIndexId: 117
+DUMP:   symTag: 12
+DUMP:   baseType: 6
+DUMP:   lexicalParentId: 0
+DUMP:   name: EC
+DUMP:   typeId: 13
+DUMP:   unmodifiedTypeId: 113
+DUMP:   length: 4
+DUMP:   constructor: 0
+DUMP:   constType: 1
+DUMP:   hasAssignmentOperator: 0
+DUMP:   hasCastOperator: 0
+DUMP:   hasNestedTypes: 0
+DUMP:   overloadedOperator: 0
+DUMP:   isInterfaceUdt: 0
+DUMP:   intrinsic: 0
+DUMP:   nested: 0
+DUMP:   packed: 0
+DUMP:   isRefUdt: 0
+DUMP:   scoped: 0
+DUMP:   unalignedType: 0
+DUMP:   isValueUdt: 0
+DUMP:   volatileType: 1  {
+DUMP:     symIndexId: 114
+DUMP:     symTag: 7
+DUMP:     classParentId: 113
+DUMP:     lexicalParentId: 0
+DUMP:     name: A
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 1
+DUMP:   }
+DUMP:   {
+DUMP:     symIndexId: 115
+DUMP:     symTag: 7
+DUMP:     classParentId: 113
+DUMP:     lexicalParentId: 0
+DUMP:     name: B
+DUMP:     typeId: 13
+DUMP:     dataKind: const
+DUMP:     locationType: constant
+DUMP:     constType: 0
+DUMP:     unalignedType: 0
+DUMP:     volatileType: 0
+DUMP:     value: 2
+DUMP:   }
+DUMP: }

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=342415&r1=342414&r2=342415&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Mon Sep 17 14:08:11 2018
@@ -970,6 +970,14 @@ static void dumpDia(StringRef Path) {
     while (auto Child = Children->getNext()) {
       outs() << "{";
       Child->defaultDump(outs(), 2);
+      if (auto Enum = dyn_cast<PDBSymbolTypeEnum>(Child.get())) {
+        auto Enumerators = Enum->findAllChildren<PDBSymbolData>();
+        while (auto Enumerator = Enumerators->getNext()) {
+          outs() << "  {";
+          Enumerator->defaultDump(outs(), 4);
+          outs() << "\n  }\n";
+        }
+      }
       outs() << "\n}\n";
     }
   }




More information about the llvm-commits mailing list