[llvm] r342780 - [NativePDB] Add support for reading function signatures.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 21 15:36:28 PDT 2018


Author: zturner
Date: Fri Sep 21 15:36:28 2018
New Revision: 342780

URL: http://llvm.org/viewvc/llvm-project?rev=342780&view=rev
Log:
[NativePDB] Add support for reading function signatures.

This adds support for parsing function signature records and returning
them through the native DIA interface.

Added:
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
    llvm/trunk/test/DebugInfo/PDB/Inputs/every-function.cpp
    llvm/trunk/test/DebugInfo/PDB/Inputs/every-function.pdb   (with props)
    llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test
Modified:
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
    llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp
    llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.cpp
    llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.h
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeEnumTypes.h Fri Sep 21 15:36:28 2018
@@ -28,6 +28,9 @@ public:
                   codeview::LazyRandomTypeCollection &TypeCollection,
                   std::vector<codeview::TypeLeafKind> Kinds);
 
+  NativeEnumTypes(NativeSession &Session,
+                  std::vector<codeview::TypeIndex> Indices);
+
   uint32_t getChildCount() const override;
   std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
   std::unique_ptr<PDBSymbol> getNext() override;

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h Fri Sep 21 15:36:28 2018
@@ -20,6 +20,9 @@ namespace pdb {
 class NativeSession;
 
 class NativeRawSymbol : public IPDBRawSymbol {
+  friend class SymbolCache;
+  virtual void initialize() {}
+
 public:
   NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag,
                   SymIndexId SymbolId);

Added: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h?rev=342780&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h Fri Sep 21 15:36:28 2018
@@ -0,0 +1,74 @@
+//===- NativeTypeFunctionSig.h - info about function signature ---*- 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_NATIVETYPEFUNCTIONSIG_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEFUNCTIONSIG_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativeTypeUDT;
+
+class NativeTypeFunctionSig : public NativeRawSymbol {
+protected:
+  void initialize() override;
+
+public:
+  NativeTypeFunctionSig(NativeSession &Session, SymIndexId Id,
+                        codeview::TypeIndex TI, codeview::ProcedureRecord Proc);
+
+  NativeTypeFunctionSig(NativeSession &Session, SymIndexId Id,
+                        codeview::TypeIndex TI,
+                        codeview::MemberFunctionRecord MemberFunc);
+
+  ~NativeTypeFunctionSig() override;
+
+  void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
+            PdbSymbolIdField RecurseIdFields) const override;
+
+  std::unique_ptr<IPDBEnumSymbols>
+  findChildren(PDB_SymType Type) const override;
+
+  SymIndexId getClassParentId() const override;
+  PDB_CallingConv getCallingConvention() const override;
+  uint32_t getCount() const override;
+  SymIndexId getTypeId() const override;
+  int32_t getThisAdjust() const override;
+  bool hasConstructor() const override;
+  bool isConstType() const override;
+  bool isConstructorVirtualBase() const override;
+  bool isCxxReturnUdt() const override;
+  bool isUnalignedType() const override;
+  bool isVolatileType() const override;
+
+private:
+  void initializeArgList(codeview::TypeIndex ArgListTI);
+
+  union {
+    codeview::MemberFunctionRecord MemberFunc;
+    codeview::ProcedureRecord Proc;
+  };
+
+  SymIndexId ClassParentId = 0;
+  codeview::TypeIndex Index;
+  codeview::ArgListRecord ArgList;
+  bool IsMemberFunction = false;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
\ No newline at end of file

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h Fri Sep 21 15:36:28 2018
@@ -1,5 +1,4 @@
-//===- NativeTypePointer.h - info about pointer type ------------------*- C++
-//-*-===//
+//===- NativeTypePointer.h - info about pointer type -------------*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //

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=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/SymbolCache.h Fri Sep 21 15:36:28 2018
@@ -68,9 +68,18 @@ public:
   SymIndexId createSymbol(Args &&... ConstructorArgs) {
     SymIndexId Id = Cache.size();
 
+    // Initial construction must not access the cache, since it must be done
+    // atomically.
     auto Result = llvm::make_unique<ConcreteSymbolT>(
         Session, Id, std::forward<Args>(ConstructorArgs)...);
+    Result->SymbolId = Id;
+
+    NativeRawSymbol *NRS = static_cast<NativeRawSymbol *>(Result.get());
     Cache.push_back(std::move(Result));
+
+    // After the item is in the cache, we can do further initialization which
+    // is then allowed to access the cache.
+    NRS->initialize();
     return Id;
   }
 
@@ -89,13 +98,11 @@ public:
     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 {
+    if (Result.second)
+      SymId =
+          createSymbol<ConcreteSymbolT>(std::forward<Args>(ConstructorArgs)...);
+    else
       SymId = Result.first->second;
-    }
     return SymId;
   }
 

Modified: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt Fri Sep 21 15:36:28 2018
@@ -54,6 +54,7 @@ add_pdb_impl_folder(Native
   Native/NativeSymbolEnumerator.cpp
   Native/NativeTypeBuiltin.cpp
   Native/NativeTypeEnum.cpp
+  Native/NativeTypeFunctionSig.cpp
   Native/NativeTypePointer.cpp
   Native/NativeTypeUDT.cpp
   Native/NamedStreamMap.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=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp Fri Sep 21 15:36:28 2018
@@ -245,7 +245,7 @@ void DIARawSymbol::dump(raw_ostream &OS,
   RAW_METHOD_DUMP(OS, baseSymbolId);
   RAW_METHOD_DUMP_AS(OS, baseType, PDB_BuiltinType);
   RAW_METHOD_DUMP(OS, bitPosition);
-  RAW_METHOD_DUMP(OS, callingConvention);
+  RAW_METHOD_DUMP_AS(OS, callingConvention, PDB_CallingConv);
   RAW_ID_METHOD_DUMP(OS, classParentId, Session, PdbSymbolIdField::ClassParent,
                      ShowIdFields, RecurseIdFields);
   RAW_METHOD_DUMP(OS, compilerName);

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp Fri Sep 21 15:36:28 2018
@@ -48,15 +48,17 @@ NativeEnumTypes::NativeEnumTypes(NativeS
   }
 }
 
+NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
+                                 std::vector<codeview::TypeIndex> Indices)
+    : Matches(std::move(Indices)), Index(0), Session(PDBSession) {}
+
 uint32_t NativeEnumTypes::getChildCount() const {
   return static_cast<uint32_t>(Matches.size());
 }
 
-std::unique_ptr<PDBSymbol>
-NativeEnumTypes::getChildAtIndex(uint32_t Index) const {
-  if (Index < Matches.size()) {
-    SymIndexId Id =
-        Session.getSymbolCache().findSymbolByTypeIndex(Matches[Index]);
+std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const {
+  if (N < Matches.size()) {
+    SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]);
     return Session.getSymbolCache().getSymbolById(Id);
   }
   return nullptr;

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp Fri Sep 21 15:36:28 2018
@@ -49,6 +49,10 @@ NativeExeSymbol::findChildren(PDB_SymTyp
     return Session.getSymbolCache().createTypeEnumerator(
         {codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION,
          codeview::LF_INTERFACE});
+  case PDB_SymType::FunctionSig:
+    return Session.getSymbolCache().createTypeEnumerator(
+        {codeview::LF_PROCEDURE, codeview::LF_MFUNCTION});
+
   default:
     break;
   }

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp Fri Sep 21 15:36:28 2018
@@ -10,12 +10,13 @@
 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
 #include "llvm/Support/FormatVariadic.h"
 
-namespace llvm {
-namespace pdb {
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
 
 NativeTypeBuiltin::NativeTypeBuiltin(NativeSession &PDBSession, SymIndexId Id,
-                                     codeview::ModifierOptions Mods,
-                                     PDB_BuiltinType T, uint64_t L)
+                                     ModifierOptions Mods, PDB_BuiltinType T,
+                                     uint64_t L)
     : NativeRawSymbol(PDBSession, PDB_SymType::BuiltinType, Id),
       Session(PDBSession), Mods(Mods), Type(T), Length(L) {}
 
@@ -31,13 +32,16 @@ PDB_SymType NativeTypeBuiltin::getSymTag
 
 PDB_BuiltinType NativeTypeBuiltin::getBuiltinType() const { return Type; }
 
-bool NativeTypeBuiltin::isConstType() const { return false; }
+bool NativeTypeBuiltin::isConstType() const {
+  return (Mods & ModifierOptions::Const) != ModifierOptions::None;
+}
 
 uint64_t NativeTypeBuiltin::getLength() const { return Length; }
 
-bool NativeTypeBuiltin::isUnalignedType() const { return false; }
-
-bool NativeTypeBuiltin::isVolatileType() const { return false; }
+bool NativeTypeBuiltin::isUnalignedType() const {
+  return (Mods & ModifierOptions::Unaligned) != ModifierOptions::None;
+}
 
-} // namespace pdb
-} // namespace llvm
+bool NativeTypeBuiltin::isVolatileType() const {
+  return (Mods & ModifierOptions::Volatile) != ModifierOptions::None;
+}

Added: llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp?rev=342780&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp (added)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp Fri Sep 21 15:36:28 2018
@@ -0,0 +1,198 @@
+//===- NativeTypeFunctionSig.cpp - info about function signature -*- 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/NativeTypeFunctionSig.h"
+
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+namespace {
+// This is kind of a silly class, hence why we keep it private to the file.
+// It's only purpose is to wrap the real type record.  I guess this is so that
+// we can have the lexical parent point to the function instead of the global
+// scope.
+class NativeTypeFunctionArg : public NativeRawSymbol {
+public:
+  NativeTypeFunctionArg(NativeSession &Session,
+                        std::unique_ptr<PDBSymbol> RealType)
+      : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0),
+        RealType(std::move(RealType)) {}
+
+  void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
+            PdbSymbolIdField RecurseIdFields) const override {
+    NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+    dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+                      PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+  }
+
+  SymIndexId getTypeId() const override { return RealType->getSymIndexId(); }
+
+  std::unique_ptr<PDBSymbol> RealType;
+};
+
+class NativeEnumFunctionArgs : public IPDBEnumChildren<PDBSymbol> {
+public:
+  NativeEnumFunctionArgs(NativeSession &Session,
+                         std::unique_ptr<NativeEnumTypes> TypeEnumerator)
+      : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {}
+
+  uint32_t getChildCount() const override {
+    return TypeEnumerator->getChildCount();
+  }
+  std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
+    return wrap(TypeEnumerator->getChildAtIndex(Index));
+  }
+  std::unique_ptr<PDBSymbol> getNext() override {
+    return wrap(TypeEnumerator->getNext());
+  }
+
+  void reset() override { TypeEnumerator->reset(); }
+
+private:
+  std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
+    if (!S)
+      return nullptr;
+    auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
+    return PDBSymbol::create(Session, std::move(NTFA));
+  }
+  NativeSession &Session;
+  std::unique_ptr<NativeEnumTypes> TypeEnumerator;
+};
+} // namespace
+
+NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session,
+                                             SymIndexId Id,
+                                             codeview::TypeIndex Index,
+                                             codeview::ProcedureRecord Proc)
+    : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
+      Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {}
+
+NativeTypeFunctionSig::NativeTypeFunctionSig(
+    NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index,
+    codeview::MemberFunctionRecord MemberFunc)
+    : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
+      MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {}
+
+void NativeTypeFunctionSig::initialize() {
+  if (IsMemberFunction) {
+    ClassParentId =
+        Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType);
+    initializeArgList(MemberFunc.ArgumentList);
+  } else {
+    initializeArgList(Proc.ArgumentList);
+  }
+}
+
+NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
+
+void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
+  TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
+  CVType CVT = Tpi.typeCollection().getType(ArgListTI);
+
+  cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList));
+}
+
+void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
+                                 PdbSymbolIdField ShowIdFields,
+                                 PdbSymbolIdField RecurseIdFields) const {
+
+  NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+  dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+                    PdbSymbolIdField::LexicalParent, ShowIdFields,
+                    RecurseIdFields);
+
+  dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent);
+  dumpSymbolField(OS, "count", getCount(), Indent);
+  dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+                    PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+  if (IsMemberFunction)
+    dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent);
+  dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+  dumpSymbolField(OS, "constType", isConstType(), Indent);
+  dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(),
+                  Indent);
+  dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent);
+  dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+  dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
+  if (Type != PDB_SymType::FunctionArg)
+    return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+
+  auto NET = llvm::make_unique<NativeEnumTypes>(Session,
+                                                /* copy */ ArgList.ArgIndices);
+  return std::unique_ptr<IPDBEnumSymbols>(
+      new NativeEnumFunctionArgs(Session, std::move(NET)));
+}
+
+SymIndexId NativeTypeFunctionSig::getClassParentId() const {
+  if (!IsMemberFunction)
+    return 0;
+
+  return ClassParentId;
+}
+
+PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const {
+  return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv;
+}
+
+uint32_t NativeTypeFunctionSig::getCount() const {
+  return IsMemberFunction ? (1 + MemberFunc.getParameterCount())
+                          : Proc.getParameterCount();
+}
+
+SymIndexId NativeTypeFunctionSig::getTypeId() const {
+  TypeIndex ReturnTI =
+      IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
+
+  return Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
+}
+
+int32_t NativeTypeFunctionSig::getThisAdjust() const {
+  return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0;
+}
+
+bool NativeTypeFunctionSig::hasConstructor() const {
+  if (!IsMemberFunction)
+    return false;
+
+  return (MemberFunc.getOptions() & FunctionOptions::Constructor) !=
+         FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isConstType() const { return false; }
+
+bool NativeTypeFunctionSig::isConstructorVirtualBase() const {
+  if (!IsMemberFunction)
+    return false;
+
+  return (MemberFunc.getOptions() &
+          FunctionOptions::ConstructorWithVirtualBases) !=
+         FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isCxxReturnUdt() const {
+  FunctionOptions Options =
+      IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions();
+  return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isUnalignedType() const { return false; }
+
+bool NativeTypeFunctionSig::isVolatileType() const { return false; }

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=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/SymbolCache.cpp Fri Sep 21 15:36:28 2018
@@ -9,6 +9,7 @@
 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
 #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
 #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -29,6 +30,7 @@ static const struct BuiltinTypeEntry {
   uint32_t Size;
 } BuiltinTypes[] = {
     {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0},
+    {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0},
     {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
     {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
     {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
@@ -76,24 +78,16 @@ SymbolCache::createTypeEnumerator(std::v
 
 SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
                                          ModifierOptions Mods) {
-  if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct) {
-    SymIndexId Id = Cache.size();
-    Cache.emplace_back(
-        llvm::make_unique<NativeTypePointer>(Session, Id, Index));
-    return Id;
-  }
+  if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
+    return createSymbol<NativeTypePointer>(Index);
 
-  SymIndexId Id = Cache.size();
   const auto Kind = Index.getSimpleKind();
   const auto It = std::find_if(
       std::begin(BuiltinTypes), std::end(BuiltinTypes),
       [Kind](const BuiltinTypeEntry &Builtin) { return Builtin.Kind == Kind; });
   if (It == std::end(BuiltinTypes))
     return 0;
-  Cache.emplace_back(llvm::make_unique<NativeTypeBuiltin>(Session, Id, Mods,
-                                                          It->Type, It->Size));
-  TypeIndexToSymbolId[Index] = Id;
-  return Id;
+  return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
 }
 
 SymIndexId
@@ -135,8 +129,12 @@ SymIndexId SymbolCache::findSymbolByType
     return Entry->second;
 
   // Symbols for built-in types are created on the fly.
-  if (Index.isSimple())
-    return createSimpleType(Index, ModifierOptions::None);
+  if (Index.isSimple()) {
+    SymIndexId Result = createSimpleType(Index, ModifierOptions::None);
+    assert(TypeIndexToSymbolId.count(Index) == 0);
+    TypeIndexToSymbolId[Index] = Result;
+    return Result;
+  }
 
   // We need to instantiate and cache the desired type symbol.
   auto Tpi = Session.getPDBFile().getPDBTpiStream();
@@ -157,6 +155,7 @@ SymIndexId SymbolCache::findSymbolByType
       SymIndexId Result = findSymbolByTypeIndex(*EFD);
       // Record a mapping from ForwardRef -> SymIndex of complete type so that
       // we'll take the fast path next time.
+      assert(TypeIndexToSymbolId.count(Index) == 0);
       TypeIndexToSymbolId[Index] = Result;
       return Result;
     }
@@ -184,12 +183,22 @@ SymIndexId SymbolCache::findSymbolByType
   case codeview::LF_MODIFIER:
     Id = createSymbolForModifiedType(Index, std::move(CVT));
     break;
+  case codeview::LF_PROCEDURE:
+    Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
+        Index, std::move(CVT));
+    break;
+  case codeview::LF_MFUNCTION:
+    Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
+        Index, std::move(CVT));
+    break;
   default:
     Id = createSymbolPlaceholder();
     break;
   }
-  if (Id != 0)
+  if (Id != 0) {
+    assert(TypeIndexToSymbolId.count(Index) == 0);
     TypeIndexToSymbolId[Index] = Id;
+  }
   return Id;
 }
 

Added: llvm/trunk/test/DebugInfo/PDB/Inputs/every-function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/every-function.cpp?rev=342780&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/Inputs/every-function.cpp (added)
+++ llvm/trunk/test/DebugInfo/PDB/Inputs/every-function.cpp Fri Sep 21 15:36:28 2018
@@ -0,0 +1,80 @@
+// Build with "cl.exe /Zi /GR- /GS- -EHs-c- every-function.cpp /link /debug /nodefaultlib /incremental:no /entry:main"
+// Getting functions with the correct calling conventions requires building in x86.
+
+// clang-format off
+void *__purecall = 0;
+
+void __cdecl operator delete(void *,unsigned int) {}
+void __cdecl operator delete(void *,unsigned __int64) {}
+
+// All calling conventions that appear in normal code.
+int __cdecl cc_cdecl() { return 42; }
+int __stdcall cc_stdcall() { return 42; }
+int __fastcall cc_fastcall() { return 42; }
+int __vectorcall cc_vectorcall() { return 42; }
+
+
+struct Struct {
+  Struct() {}  // constructor
+
+  int __thiscall cc_thiscall() { return 42; }
+
+  void M() { }
+  void CM() const { }
+  void VM() volatile { }
+  void CVM() const volatile { }
+};
+
+int builtin_one_param(int x) { return 42; }
+int builtin_two_params(int x, char y) { return 42; }
+
+void struct_one_param(Struct S) { }
+
+void modified_builtin_param(const int X) { }
+void modified_struct_param(const Struct S) { }
+
+void pointer_builtin_param(int *X) { }
+void pointer_struct_param(Struct *S) { }
+
+
+void modified_pointer_builtin_param(const int *X) { }
+void modified_pointer_struct_param(const Struct *S) { }
+
+Struct rvo() { return Struct(); }
+
+struct Base1 {
+  virtual ~Base1() {}
+};
+
+struct Base2 : public virtual Base1 { };
+
+struct Derived : public virtual Base1, public Base2 {
+};
+
+
+int main() {
+  cc_cdecl();
+  cc_stdcall();
+  cc_fastcall();
+  Struct().cc_thiscall();
+  cc_vectorcall();
+
+  builtin_one_param(42);
+  builtin_two_params(42, 'x');
+  struct_one_param(Struct{});
+
+  modified_builtin_param(42);
+  modified_struct_param(Struct());
+
+  pointer_builtin_param(nullptr);
+  pointer_struct_param(nullptr);
+
+
+  modified_pointer_builtin_param(nullptr);
+  modified_pointer_struct_param(nullptr);
+
+  Struct S = rvo();
+
+  Derived D;
+  return 42;
+}

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

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

Added: llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test?rev=342780&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test (added)
+++ llvm/trunk/test/DebugInfo/PDB/Native/pdb-native-function-signatures.test Fri Sep 21 15:36:28 2018
@@ -0,0 +1,865 @@
+; Test that the native PDB reader can enumerate pointer 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.
+
+; RUN: llvm-pdbutil pretty -native -funcsigs %p/../Inputs/every-function.pdb \
+; RUN:     | FileCheck -check-prefix=PRETTY %s
+
+; RUN: llvm-pdbutil diadump -native -funcsigs %p/../Inputs/every-function.pdb \
+; RUN:     | FileCheck -check-prefix=DUMP %s
+
+
+; PRETTY:      void __cdecl (void*, unsigned int)
+; PRETTY-NEXT: void __cdecl (void*, unsigned __int64)
+; PRETTY-NEXT: int __cdecl ()
+; PRETTY-NEXT: int ()
+; PRETTY-NEXT: int __fastcall ()
+; PRETTY-NEXT: int __vectorcall ()
+; PRETTY-NEXT: int __cdecl (int)
+; PRETTY-NEXT: int __cdecl (int, char)
+; PRETTY-NEXT: void __cdecl (Struct)
+; PRETTY-NEXT: void (Struct::)()
+; PRETTY-NEXT: int (Struct::)()
+; PRETTY-NEXT: void (Struct::)()
+; PRETTY-NEXT: void (Struct::)()
+; PRETTY-NEXT: void (Struct::)()
+; PRETTY-NEXT: void (Struct::)()
+; PRETTY-NEXT: void __cdecl (const int)
+; PRETTY-NEXT: void __cdecl (Struct)
+; PRETTY-NEXT: void __cdecl (int*)
+; PRETTY-NEXT: void __cdecl (Struct*)
+; PRETTY-NEXT: void __cdecl (const int*)
+; PRETTY-NEXT: void __cdecl (Struct*)
+; PRETTY-NEXT: Struct __cdecl ()
+; PRETTY-NEXT: void (Derived::)(Derived*)
+; PRETTY-NEXT: void (Derived::)(Derived&)
+; PRETTY-NEXT: void (Derived::)()
+; PRETTY-NEXT: void (Derived::)()
+; PRETTY-NEXT: Derived& (Derived::)(Derived*)
+; PRETTY-NEXT: Derived& (Derived::)(Derived&)
+; PRETTY-NEXT: void (Derived::)()
+; PRETTY-NEXT: void* (Derived::)(unsigned int)
+; PRETTY-NEXT: void (__vc_attributes::event_sourceAttribute::)(__vc_attributes::event_sourceAttribute::type_e)
+; PRETTY-NEXT: void (__vc_attributes::event_sourceAttribute::)()
+; PRETTY-NEXT: void (__vc_attributes::helper_attributes::v1_alttypeAttribute::)(__vc_attributes::helper_attributes::v1_alttypeAttribute::type_e)
+; PRETTY-NEXT: void (__vc_attributes::helper_attributes::usageAttribute::)(unsigned int)
+; PRETTY-NEXT: void (__vc_attributes::threadingAttribute::)(__vc_attributes::threadingAttribute::threading_e)
+; PRETTY-NEXT: void (__vc_attributes::threadingAttribute::)()
+; PRETTY-NEXT: void (__vc_attributes::aggregatableAttribute::)(__vc_attributes::aggregatableAttribute::type_e)
+; PRETTY-NEXT: void (__vc_attributes::aggregatableAttribute::)()
+; PRETTY-NEXT: void (__vc_attributes::event_receiverAttribute::)(__vc_attributes::event_receiverAttribute::type_e, bool)
+; PRETTY-NEXT: void (__vc_attributes::event_receiverAttribute::)(__vc_attributes::event_receiverAttribute::type_e)
+; PRETTY-NEXT: void (__vc_attributes::event_receiverAttribute::)()
+; PRETTY-NEXT: void (__vc_attributes::moduleAttribute::)(__vc_attributes::moduleAttribute::type_e, const char*, const char*, const char*, int, bool, const char*, int, const char*, const char*, int, bool, bool, const char*, const char*)
+; PRETTY-NEXT: void (__vc_attributes::moduleAttribute::)(__vc_attributes::moduleAttribute::type_e)
+; PRETTY-NEXT: void (__vc_attributes::moduleAttribute::)()
+; PRETTY-NEXT: void (Base1::)()
+; PRETTY-NEXT: void (Base1::)(Base1&)
+; PRETTY-NEXT: void (Base1::)()
+; PRETTY-NEXT: Base1& (Base1::)(Base1&)
+; PRETTY-NEXT: void* (Base1::)(unsigned int)
+; PRETTY-NEXT: void (Base2::)(Base2*)
+; PRETTY-NEXT: void (Base2::)(Base2&)
+; PRETTY-NEXT: void (Base2::)()
+; PRETTY-NEXT: void (Base2::)()
+; PRETTY-NEXT: Base2& (Base2::)(Base2*)
+; PRETTY-NEXT: Base2& (Base2::)(Base2&)
+; PRETTY-NEXT: void (Base2::)()
+; PRETTY-NEXT: void* (Base2::)(unsigned int)
+; PRETTY-NEXT: void __cdecl ()
+
+; DUMP:      {
+; DUMP-NEXT:   symIndexId: 2
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 4
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 5
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 0
+; DUMP-NEXT:   typeId: 6
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 7
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __stdcall
+; DUMP-NEXT:   count: 0
+; DUMP-NEXT:   typeId: 6
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 8
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __fastcall
+; DUMP-NEXT:   count: 0
+; DUMP-NEXT:   typeId: 6
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 9
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __vectorcall
+; DUMP-NEXT:   count: 0
+; DUMP-NEXT:   typeId: 6
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 10
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 6
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 11
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 6
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 12
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 13
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 15
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 6
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 16
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 17
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 18
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 19
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 20
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 21
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 22
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 23
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 24
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 25
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 26
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 0
+; DUMP-NEXT:   typeId: 14
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 1
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 27
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 1
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 29
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 1
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 30
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 1
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 31
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 4
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 32
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 33
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 34
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 33
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 35
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 36
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 37
+; DUMP-NEXT:   thisAdjust: 4
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 38
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 40
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 41
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 43
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 45
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 47
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 48
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 50
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 51
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 3
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 53
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 54
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 55
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 16
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 57
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 58
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 59
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 61
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 62
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 63
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 64
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 65
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 37
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 66
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 1
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 68
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 1
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 69
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 1
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 1
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 70
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 4
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 71
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 72
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 73
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 72
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 74
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 1
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   thisAdjust: 0
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 75
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __thiscall
+; DUMP-NEXT:   count: 2
+; DUMP-NEXT:   typeId: 37
+; DUMP-NEXT:   thisAdjust: 4
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }
+; DUMP-NEXT: {
+; DUMP-NEXT:   symIndexId: 76
+; DUMP-NEXT:   symTag: FunctionSig
+; DUMP-NEXT:   callingConvention: __cdecl
+; DUMP-NEXT:   count: 0
+; DUMP-NEXT:   typeId: 3
+; DUMP-NEXT:   constructor: 0
+; DUMP-NEXT:   constType: 0
+; DUMP-NEXT:   isConstructorVirtualBase: 0
+; DUMP-NEXT:   isCxxReturnUdt: 0
+; DUMP-NEXT:   unalignedType: 0
+; DUMP-NEXT:   volatileType: 0
+; DUMP-NEXT: }

Modified: llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.cpp?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.cpp Fri Sep 21 15:36:28 2018
@@ -13,6 +13,7 @@
 #include "PrettyBuiltinDumper.h"
 #include "PrettyClassDefinitionDumper.h"
 #include "PrettyEnumDumper.h"
+#include "PrettyFunctionDumper.h"
 #include "PrettyTypedefDumper.h"
 #include "llvm-pdbutil.h"
 
@@ -20,6 +21,7 @@
 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
 #include "llvm/DebugInfo/PDB/UDTLayout.h"
@@ -147,6 +149,19 @@ void TypeDumper::start(const PDBSymbolEx
     }
   }
 
+  if (opts::pretty::Funcsigs) {
+    if (auto Funcsigs = Exe.findAllChildren<PDBSymbolTypeFunctionSig>()) {
+      Printer.NewLine();
+      WithColor(Printer, PDB_ColorItem::Identifier).get()
+          << "Function Signatures";
+      Printer << ": (" << Funcsigs->getChildCount() << " items)";
+      Printer.Indent();
+      while (auto FS = Funcsigs->getNext())
+        FS->dump(*this);
+      Printer.Unindent();
+    }
+  }
+
   if (opts::pretty::Typedefs) {
     if (auto Typedefs = Exe.findAllChildren<PDBSymbolTypeTypedef>()) {
       Printer.NewLine();
@@ -251,6 +266,12 @@ void TypeDumper::dump(const PDBSymbolTyp
   Dumper.start(Symbol);
 }
 
+void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {
+  Printer.NewLine();
+  FunctionDumper Dumper(Printer);
+  Dumper.start(Symbol, nullptr, FunctionDumper::PointerType::None);
+}
+
 void TypeDumper::dumpClassLayout(const ClassLayout &Class) {
   assert(opts::pretty::Classes);
 

Modified: llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.h?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/PrettyTypeDumper.h Fri Sep 21 15:36:28 2018
@@ -25,6 +25,7 @@ public:
 
   void dump(const PDBSymbolTypeEnum &Symbol) override;
   void dump(const PDBSymbolTypeTypedef &Symbol) override;
+  void dump(const PDBSymbolTypeFunctionSig &Symbol) override;
 
   void dumpClassLayout(const ClassLayout &Class);
 

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=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Fri Sep 21 15:36:28 2018
@@ -70,6 +70,8 @@
 #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
 #include "llvm/Support/BinaryByteStream.h"
@@ -188,6 +190,9 @@ static cl::opt<bool> UDTs("udts", cl::de
 static cl::opt<bool> Compilands("compilands",
                                 cl::desc("Dump compiland information"),
                                 cl::sub(DiaDumpSubcommand));
+static cl::opt<bool> Funcsigs("funcsigs",
+                              cl::desc("Dump function signature information"),
+                              cl::sub(DiaDumpSubcommand));
 } // namespace diadump
 
 namespace pretty {
@@ -236,6 +241,8 @@ cl::opt<bool> Enums("enums", cl::desc("D
                     cl::cat(TypeCategory), cl::sub(PrettySubcommand));
 cl::opt<bool> Typedefs("typedefs", cl::desc("Display typedef types"),
                        cl::cat(TypeCategory), cl::sub(PrettySubcommand));
+cl::opt<bool> Funcsigs("funcsigs", cl::desc("Display function signatures"),
+                       cl::cat(TypeCategory), cl::sub(PrettySubcommand));
 cl::opt<SymbolSortMode> SymbolOrder(
     "symbol-order", cl::desc("symbol sort order"),
     cl::init(SymbolSortMode::None),
@@ -969,6 +976,21 @@ static void dumpInjectedSources(LinePrin
   }
 }
 
+template <typename OuterT, typename ChildT>
+void diaDumpChildren(PDBSymbol &Outer, PdbSymbolIdField Ids,
+                     PdbSymbolIdField Recurse) {
+  OuterT *ConcreteOuter = dyn_cast<OuterT>(&Outer);
+  if (!ConcreteOuter)
+    return;
+
+  auto Children = ConcreteOuter->template findAllChildren<ChildT>();
+  while (auto Child = Children->getNext()) {
+    outs() << "  {";
+    Child->defaultDump(outs(), 4, Ids, Recurse);
+    outs() << "\n  }\n";
+  }
+}
+
 static void dumpDia(StringRef Path) {
   std::unique_ptr<IPDBSession> Session;
 
@@ -988,6 +1010,8 @@ static void dumpDia(StringRef Path) {
     SymTypes.push_back(PDB_SymType::PointerType);
   if (opts::diadump::UDTs)
     SymTypes.push_back(PDB_SymType::UDT);
+  if (opts::diadump::Funcsigs)
+    SymTypes.push_back(PDB_SymType::FunctionSig);
 
   PdbSymbolIdField Ids = opts::diadump::NoSymIndexIds ? PdbSymbolIdField::None
                                                       : PdbSymbolIdField::All;
@@ -1002,19 +1026,11 @@ static void dumpDia(StringRef Path) {
     while (auto Child = Children->getNext()) {
       outs() << "{";
       Child->defaultDump(outs(), 2, Ids, Recurse);
-      if (auto Enum = dyn_cast<PDBSymbolTypeEnum>(Child.get())) {
-        auto Enumerators = Enum->findAllChildren<PDBSymbolData>();
-        while (auto Enumerator = Enumerators->getNext()) {
-          outs() << "  {";
-          Enumerator->defaultDump(outs(), 4, Ids, Recurse);
-          outs() << "\n  }\n";
-        }
-      }
+
+      diaDumpChildren<PDBSymbolTypeEnum, PDBSymbolData>(*Child, Ids, Recurse);
       outs() << "\n}\n";
     }
   }
-  auto Child = Session->getSymbolById(3);
-  Child->defaultDump(outs(), 2, PdbSymbolIdField::All, PdbSymbolIdField::None);
 }
 
 static void dumpPretty(StringRef Path) {
@@ -1162,7 +1178,8 @@ static void dumpPretty(StringRef Path) {
     }
   }
 
-  if (opts::pretty::Classes || opts::pretty::Enums || opts::pretty::Typedefs) {
+  if (opts::pretty::Classes || opts::pretty::Enums || opts::pretty::Typedefs ||
+      opts::pretty::Funcsigs) {
     Printer.NewLine();
     WithColor(Printer, PDB_ColorItem::SectionHeader).get() << "---TYPES---";
     Printer.Indent();

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h?rev=342780&r1=342779&r2=342780&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Fri Sep 21 15:36:28 2018
@@ -82,6 +82,7 @@ extern llvm::cl::opt<bool> Symbols;
 extern llvm::cl::opt<bool> Globals;
 extern llvm::cl::opt<bool> Classes;
 extern llvm::cl::opt<bool> Enums;
+extern llvm::cl::opt<bool> Funcsigs;
 extern llvm::cl::opt<bool> Typedefs;
 extern llvm::cl::opt<bool> All;
 extern llvm::cl::opt<bool> ExcludeCompilerGenerated;




More information about the llvm-commits mailing list