diff options
Diffstat (limited to 'include/llvm/DebugInfo/PDB')
36 files changed, 895 insertions, 128 deletions
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h new file mode 100644 index 000000000000..39490a4b2209 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h @@ -0,0 +1,40 @@ +//==- DIAEnumInjectedSources.h - DIA Injected Sources Enumerator -*- 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_DIA_DIAENUMINJECTEDSOURCES_H +#define LLVM_DEBUGINFO_PDB_DIA_DIAENUMINJECTEDSOURCES_H + +#include "DIASupport.h" +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h" + +namespace llvm { +namespace pdb { +class DIASession; + +class DIAEnumInjectedSources : public IPDBEnumChildren<IPDBInjectedSource> { +public: + explicit DIAEnumInjectedSources( + const DIASession &PDBSession, + CComPtr<IDiaEnumInjectedSources> DiaEnumerator); + + uint32_t getChildCount() const override; + ChildTypePtr getChildAtIndex(uint32_t Index) const override; + ChildTypePtr getNext() override; + void reset() override; + DIAEnumInjectedSources *clone() const override; + +private: + const DIASession &Session; + CComPtr<IDiaEnumInjectedSources> Enumerator; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIAENUMINJECTEDSOURCES_H diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h new file mode 100644 index 000000000000..52c9563b5d5f --- /dev/null +++ b/include/llvm/DebugInfo/PDB/DIA/DIAEnumSectionContribs.h @@ -0,0 +1,40 @@ +//==- DIAEnumSectionContribs.h --------------------------------- -*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_PDB_DIA_DIAENUMSECTIONCONTRIBS_H +#define LLVM_DEBUGINFO_PDB_DIA_DIAENUMSECTIONCONTRIBS_H + +#include "DIASupport.h" +#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h" + +namespace llvm { +namespace pdb { +class DIASession; + +class DIAEnumSectionContribs : public IPDBEnumChildren<IPDBSectionContrib> { +public: + explicit DIAEnumSectionContribs( + const DIASession &PDBSession, + CComPtr<IDiaEnumSectionContribs> DiaEnumerator); + + uint32_t getChildCount() const override; + ChildTypePtr getChildAtIndex(uint32_t Index) const override; + ChildTypePtr getNext() override; + void reset() override; + DIAEnumSectionContribs *clone() const override; + +private: + const DIASession &Session; + CComPtr<IDiaEnumSectionContribs> Enumerator; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIAENUMSECTIONCONTRIBS_H diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h b/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h new file mode 100644 index 000000000000..635508da84ea --- /dev/null +++ b/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h @@ -0,0 +1,38 @@ +//===- DIAInjectedSource.h - DIA impl for IPDBInjectedSource ----*- 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_DIA_DIAINJECTEDSOURCE_H +#define LLVM_DEBUGINFO_PDB_DIA_DIAINJECTEDSOURCE_H + +#include "DIASupport.h" +#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h" + +namespace llvm { +namespace pdb { +class DIASession; + +class DIAInjectedSource : public IPDBInjectedSource { +public: + explicit DIAInjectedSource(CComPtr<IDiaInjectedSource> DiaSourceFile); + + uint32_t getCrc32() const override; + uint64_t getCodeByteSize() const override; + std::string getFileName() const override; + std::string getObjectFileName() const override; + std::string getVirtualFileName() const override; + PDB_SourceCompression getCompression() const override; + std::string getCode() const override; + +private: + CComPtr<IDiaInjectedSource> SourceFile; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIAINJECTEDSOURCE_H diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h index 2d6c44905ce0..dfb35647055a 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h @@ -30,10 +30,31 @@ public: findChildren(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags) const override; std::unique_ptr<IPDBEnumSymbols> + findChildrenByAddr(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags, + uint32_t Section, uint32_t Offset) const override; + std::unique_ptr<IPDBEnumSymbols> + findChildrenByVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags, + uint64_t VA) const override; + std::unique_ptr<IPDBEnumSymbols> findChildrenByRVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags, uint32_t RVA) const override; + + std::unique_ptr<IPDBEnumSymbols> + findInlineFramesByAddr(uint32_t Section, uint32_t Offset) const override; std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const override; + std::unique_ptr<IPDBEnumSymbols> + findInlineFramesByVA(uint64_t VA) const override; + + std::unique_ptr<IPDBEnumLineNumbers> findInlineeLines() const override; + std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByAddr(uint32_t Section, uint32_t Offset, + uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByVA(uint64_t VA, uint32_t Length) const override; void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const override; void getFrontEndVersion(VersionInfo &Version) const override; @@ -82,6 +103,7 @@ public: uint32_t getSizeInUdt() const override; uint32_t getSlot() const override; std::string getSourceFileName() const override; + std::unique_ptr<IPDBLineNumber> getSrcLineOnTypeDefn() const override; uint32_t getStride() const override; uint32_t getSubTypeId() const override; std::string getSymbolsFileName() const override; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h b/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h new file mode 100644 index 000000000000..4688f1f91a89 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/DIA/DIASectionContrib.h @@ -0,0 +1,55 @@ +//===- DIASectionContrib.h - DIA Impl. of IPDBSectionContrib ------ 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_DIA_DIASECTIONCONTRIB_H +#define LLVM_DEBUGINFO_PDB_DIA_DIASECTIONCONTRIB_H + +#include "DIASupport.h" +#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h" + +namespace llvm { +namespace pdb { +class DIASession; + +class DIASectionContrib : public IPDBSectionContrib { +public: + explicit DIASectionContrib(const DIASession &PDBSession, + CComPtr<IDiaSectionContrib> DiaSection); + + std::unique_ptr<PDBSymbolCompiland> getCompiland() const override; + uint32_t getAddressSection() const override; + uint32_t getAddressOffset() const override; + uint32_t getRelativeVirtualAddress() const override; + uint64_t getVirtualAddress() const override; + uint32_t getLength() const override; + bool isNotPaged() const override; + bool hasCode() const override; + bool hasCode16Bit() const override; + bool hasInitializedData() const override; + bool hasUninitializedData() const override; + bool isRemoved() const override; + bool hasComdat() const override; + bool isDiscardable() const override; + bool isNotCached() const override; + bool isShared() const override; + bool isExecutable() const override; + bool isReadable() const override; + bool isWritable() const override; + uint32_t getDataCrc32() const override; + uint32_t getRelocationsCrc32() const override; + uint32_t getCompilandId() const override; + +private: + const DIASession &Session; + CComPtr<IDiaSectionContrib> Section; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIASECTIONCONTRIB_H diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h index 66bd7a7e9c4e..a63659439389 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -30,18 +30,33 @@ public: std::unique_ptr<IPDBSession> &Session); uint64_t getLoadAddress() const override; - void setLoadAddress(uint64_t Address) override; + bool setLoadAddress(uint64_t Address) override; std::unique_ptr<PDBSymbolExe> getGlobalScope() override; std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override; + bool addressForVA(uint64_t VA, uint32_t &Section, + uint32_t &Offset) const override; + bool addressForRVA(uint32_t RVA, uint32_t &Section, + uint32_t &Offset) const override; + std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override; + std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA, + PDB_SymType Type) const override; + std::unique_ptr<PDBSymbol> + findSymbolBySectOffset(uint32_t Section, uint32_t Offset, + PDB_SymType Type) const override; std::unique_ptr<IPDBEnumLineNumbers> findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const override; std::unique_ptr<IPDBEnumLineNumbers> findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, + uint32_t Length) const override; std::unique_ptr<IPDBEnumSourceFiles> findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, @@ -65,9 +80,14 @@ public: std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const override; std::unique_ptr<IPDBEnumTables> getEnumTables() const override; + + std::unique_ptr<IPDBEnumInjectedSources> getInjectedSources() const override; + + std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const override; + private: CComPtr<IDiaSession> Session; }; -} -} +} // namespace pdb +} // namespace llvm #endif diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASupport.h b/include/llvm/DebugInfo/PDB/DIA/DIASupport.h index 3b4a348289df..92ebc04ae5a4 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASupport.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASupport.h @@ -22,14 +22,6 @@ #define NOMINMAX #endif -// llvm/Support/Debug.h unconditionally #defines DEBUG as a macro. -// DIA headers #define it if it is not already defined, so we have -// an order of includes problem. The real fix is to make LLVM use -// something less generic than DEBUG, such as LLVM_DEBUG(), but it's -// fairly prevalent. So for now, we save the definition state and -// restore it. -#pragma push_macro("DEBUG") - // atlbase.h has to come before windows.h #include <atlbase.h> #include <windows.h> @@ -39,6 +31,4 @@ #include <dia2.h> #include <diacreate.h> -#pragma pop_macro("DEBUG") - #endif // LLVM_DEBUGINFO_PDB_DIA_DIASUPPORT_H diff --git a/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h b/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h new file mode 100644 index 000000000000..aa843e05de70 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h @@ -0,0 +1,31 @@ +//===- DIAUtils.h - Utility functions for working with DIA ------*- 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_DIA_DIAUTILS_H +#define LLVM_DEBUGINFO_PDB_DIA_DIAUTILS_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/ConvertUTF.h" + +template <typename Obj> +std::string invokeBstrMethod(Obj &Object, + HRESULT (__stdcall Obj::*Func)(BSTR *)) { + CComBSTR Str16; + HRESULT Result = (Object.*Func)(&Str16); + if (S_OK != Result) + return std::string(); + + std::string Str8; + llvm::ArrayRef<char> StrBytes(reinterpret_cast<char *>(Str16.m_str), + Str16.ByteLength()); + llvm::convertUTF16ToUTF8String(StrBytes, Str8); + return Str8; +} + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIAUTILS_H diff --git a/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h b/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h new file mode 100644 index 000000000000..e75d64af92bb --- /dev/null +++ b/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h @@ -0,0 +1,42 @@ +//===- IPDBInjectedSource.h - base class for PDB injected file --*- 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_IPDBINJECTEDSOURCE_H +#define LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H + +#include "PDBTypes.h" +#include "llvm/Support/raw_ostream.h" +#include <memory> +#include <string> + +namespace llvm { +class raw_ostream; + +namespace pdb { + +/// IPDBInjectedSource defines an interface used to represent source files +/// which were injected directly into the PDB file during the compilation +/// process. This is used, for example, to add natvis files to a PDB, but +/// in theory could be used to add arbitrary source code. +class IPDBInjectedSource { +public: + virtual ~IPDBInjectedSource(); + + virtual uint32_t getCrc32() const = 0; + virtual uint64_t getCodeByteSize() const = 0; + virtual std::string getFileName() const = 0; + virtual std::string getObjectFileName() const = 0; + virtual std::string getVirtualFileName() const = 0; + virtual PDB_SourceCompression getCompression() const = 0; + virtual std::string getCode() const = 0; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H diff --git a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h index 18b9423378a0..bcb2eaa35630 100644 --- a/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h @@ -42,10 +42,31 @@ public: findChildren(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags) const = 0; virtual std::unique_ptr<IPDBEnumSymbols> + findChildrenByAddr(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags, + uint32_t Section, uint32_t Offset) const = 0; + virtual std::unique_ptr<IPDBEnumSymbols> + findChildrenByVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags, + uint64_t VA) const = 0; + virtual std::unique_ptr<IPDBEnumSymbols> findChildrenByRVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags, uint32_t RVA) const = 0; + + virtual std::unique_ptr<IPDBEnumSymbols> + findInlineFramesByAddr(uint32_t Section, uint32_t Offset) const = 0; virtual std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const = 0; + virtual std::unique_ptr<IPDBEnumSymbols> + findInlineFramesByVA(uint64_t VA) const = 0; + + virtual std::unique_ptr<IPDBEnumLineNumbers> findInlineeLines() const = 0; + virtual std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByAddr(uint32_t Section, uint32_t Offset, + uint32_t Length) const = 0; + virtual std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const = 0; + virtual std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByVA(uint64_t VA, uint32_t Length) const = 0; virtual void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const = 0; virtual void getBackEndVersion(VersionInfo &Version) const = 0; @@ -94,6 +115,8 @@ public: virtual uint32_t getSizeInUdt() const = 0; virtual uint32_t getSlot() const = 0; virtual std::string getSourceFileName() const = 0; + virtual std::unique_ptr<IPDBLineNumber> + getSrcLineOnTypeDefn() const = 0; virtual uint32_t getStride() const = 0; virtual uint32_t getSubTypeId() const = 0; virtual std::string getSymbolsFileName() const = 0; diff --git a/include/llvm/DebugInfo/PDB/IPDBSectionContrib.h b/include/llvm/DebugInfo/PDB/IPDBSectionContrib.h new file mode 100644 index 000000000000..4fda62404672 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/IPDBSectionContrib.h @@ -0,0 +1,50 @@ +//==- IPDBSectionContrib.h - Interfaces for PDB SectionContribs --*- 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_IPDBSECTIONCONTRIB_H +#define LLVM_DEBUGINFO_PDB_IPDBSECTIONCONTRIB_H + +#include "PDBTypes.h" + +namespace llvm { +namespace pdb { + +/// IPDBSectionContrib defines an interface used to represent section +/// contributions whose information are stored in the PDB. +class IPDBSectionContrib { +public: + virtual ~IPDBSectionContrib(); + + virtual std::unique_ptr<PDBSymbolCompiland> getCompiland() const = 0; + virtual uint32_t getAddressSection() const = 0; + virtual uint32_t getAddressOffset() const = 0; + virtual uint32_t getRelativeVirtualAddress() const = 0; + virtual uint64_t getVirtualAddress() const = 0; + virtual uint32_t getLength() const = 0; + virtual bool isNotPaged() const = 0; + virtual bool hasCode() const = 0; + virtual bool hasCode16Bit() const = 0; + virtual bool hasInitializedData() const = 0; + virtual bool hasUninitializedData() const = 0; + virtual bool isRemoved() const = 0; + virtual bool hasComdat() const = 0; + virtual bool isDiscardable() const = 0; + virtual bool isNotCached() const = 0; + virtual bool isShared() const = 0; + virtual bool isExecutable() const = 0; + virtual bool isReadable() const = 0; + virtual bool isWritable() const = 0; + virtual uint32_t getDataCrc32() const = 0; + virtual uint32_t getRelocationsCrc32() const = 0; + virtual uint32_t getCompilandId() const = 0; +}; +} +} + +#endif // LLVM_DEBUGINFO_PDB_IPDBSECTIONCONTRIB_H diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index 6291289de5bf..88ec517bc4a5 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -28,10 +28,15 @@ public: virtual ~IPDBSession(); virtual uint64_t getLoadAddress() const = 0; - virtual void setLoadAddress(uint64_t Address) = 0; + virtual bool setLoadAddress(uint64_t Address) = 0; virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() = 0; virtual std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const = 0; + virtual bool addressForVA(uint64_t VA, uint32_t &Section, + uint32_t &Offset) const = 0; + virtual bool addressForRVA(uint32_t RVA, uint32_t &Section, + uint32_t &Offset) const = 0; + template <typename T> std::unique_ptr<T> getConcreteSymbolById(uint32_t SymbolId) const { return unique_dyn_cast_or_null<T>(getSymbolById(SymbolId)); @@ -39,12 +44,22 @@ public: virtual std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address, PDB_SymType Type) const = 0; + virtual std::unique_ptr<PDBSymbol> + findSymbolByRVA(uint32_t RVA, PDB_SymType Type) const = 0; + virtual std::unique_ptr<PDBSymbol> + findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, + PDB_SymType Type) const = 0; virtual std::unique_ptr<IPDBEnumLineNumbers> findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const = 0; virtual std::unique_ptr<IPDBEnumLineNumbers> findLineNumbersByAddress(uint64_t Address, uint32_t Length) const = 0; + virtual std::unique_ptr<IPDBEnumLineNumbers> + findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const = 0; + virtual std::unique_ptr<IPDBEnumLineNumbers> + findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, + uint32_t Length) const = 0; virtual std::unique_ptr<IPDBEnumSourceFiles> findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, @@ -69,8 +84,14 @@ public: virtual std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const = 0; virtual std::unique_ptr<IPDBEnumTables> getEnumTables() const = 0; + + virtual std::unique_ptr<IPDBEnumInjectedSources> + getInjectedSources() const = 0; + + virtual std::unique_ptr<IPDBEnumSectionContribs> + getSectionContribs() const = 0; }; -} -} +} // namespace pdb +} // namespace llvm #endif diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h index 8200f51e3da9..9eef4041d0a1 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h @@ -47,6 +47,8 @@ public: uint32_t getRecordLength() const; + const SectionContrib &getSectionContrib() const; + private: StringRef ModuleName; StringRef ObjFileName; diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h index c918a5d5e976..ce4d07917755 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h @@ -49,6 +49,7 @@ public: void setPdbFilePathNI(uint32_t NI); void setObjFileName(StringRef Name); + void setFirstSectionContrib(const SectionContrib &SC); void addSymbol(codeview::CVSymbol Symbol); void diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 4be113f28d6f..280615bdb507 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -38,9 +38,9 @@ class DbiStream { friend class DbiStreamBuilder; public: - DbiStream(PDBFile &File, std::unique_ptr<msf::MappedBlockStream> Stream); + explicit DbiStream(std::unique_ptr<BinaryStream> Stream); ~DbiStream(); - Error reload(); + Error reload(PDBFile *Pdb); PdbRaw_DbiVer getDbiVersion() const; uint32_t getAge() const; @@ -63,6 +63,8 @@ public: PDB_Machine getMachineType() const; + const DbiStreamHeader *getHeader() const { return Header; } + BinarySubstreamRef getSectionContributionData() const; BinarySubstreamRef getSecMapSubstreamData() const; BinarySubstreamRef getModiSubstreamData() const; @@ -87,12 +89,11 @@ public: private: Error initializeSectionContributionData(); - Error initializeSectionHeadersData(); + Error initializeSectionHeadersData(PDBFile *Pdb); Error initializeSectionMapData(); - Error initializeFpoRecords(); + Error initializeFpoRecords(PDBFile *Pdb); - PDBFile &Pdb; - std::unique_ptr<msf::MappedBlockStream> Stream; + std::unique_ptr<BinaryStream> Stream; PDBStringTable ECNames; diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index ad4a0d1bcb6b..51befcdac775 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -12,6 +12,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSet.h" +#include "llvm/BinaryFormat/COFF.h" #include "llvm/Support/Error.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" @@ -46,10 +47,12 @@ public: void setVersionHeader(PdbRaw_DbiVer V); void setAge(uint32_t A); void setBuildNumber(uint16_t B); + void setBuildNumber(uint8_t Major, uint8_t Minor); void setPdbDllVersion(uint16_t V); void setPdbDllRbld(uint16_t R); void setFlags(uint16_t F); void setMachineType(PDB_Machine M); + void setMachineType(COFF::MachineTypes M); void setSectionMap(ArrayRef<SecMapEntry> SecMap); // Add given bytes as a new stream. @@ -121,7 +124,7 @@ private: MutableBinaryByteStream FileInfoBuffer; std::vector<SectionContrib> SectionContribs; ArrayRef<SecMapEntry> SectionMap; - llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams; + std::array<Optional<DebugStream>, (int)DbgHeaderType::Max> DbgStreams; }; } } diff --git a/include/llvm/DebugInfo/PDB/Native/HashTable.h b/include/llvm/DebugInfo/PDB/Native/HashTable.h index 05c70c4f2175..34cc6179688b 100644 --- a/include/llvm/DebugInfo/PDB/Native/HashTable.h +++ b/include/llvm/DebugInfo/PDB/Native/HashTable.h @@ -12,6 +12,9 @@ #include "llvm/ADT/SparseBitVector.h" #include "llvm/ADT/iterator.h" +#include "llvm/DebugInfo/PDB/Native/RawError.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamWriter.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> @@ -26,80 +29,303 @@ class BinaryStreamWriter; namespace pdb { -class HashTableIterator; +Error readSparseBitVector(BinaryStreamReader &Stream, SparseBitVector<> &V); +Error writeSparseBitVector(BinaryStreamWriter &Writer, SparseBitVector<> &Vec); +template <typename ValueT, typename TraitsT> class HashTable; + +template <typename ValueT, typename TraitsT> +class HashTableIterator + : public iterator_facade_base<HashTableIterator<ValueT, TraitsT>, + std::forward_iterator_tag, + std::pair<uint32_t, ValueT>> { + friend HashTable<ValueT, TraitsT>; + + HashTableIterator(const HashTable<ValueT, TraitsT> &Map, uint32_t Index, + bool IsEnd) + : Map(&Map), Index(Index), IsEnd(IsEnd) {} + +public: + HashTableIterator(const HashTable<ValueT, TraitsT> &Map) : Map(&Map) { + int I = Map.Present.find_first(); + if (I == -1) { + Index = 0; + IsEnd = true; + } else { + Index = static_cast<uint32_t>(I); + IsEnd = false; + } + } + + HashTableIterator &operator=(const HashTableIterator &R) { + Map = R.Map; + return *this; + } + bool operator==(const HashTableIterator &R) const { + if (IsEnd && R.IsEnd) + return true; + if (IsEnd != R.IsEnd) + return false; + + return (Map == R.Map) && (Index == R.Index); + } + const std::pair<uint32_t, ValueT> &operator*() const { + assert(Map->Present.test(Index)); + return Map->Buckets[Index]; + } + HashTableIterator &operator++() { + while (Index < Map->Buckets.size()) { + ++Index; + if (Map->Present.test(Index)) + return *this; + } + + IsEnd = true; + return *this; + } + +private: + bool isEnd() const { return IsEnd; } + uint32_t index() const { return Index; } + + const HashTable<ValueT, TraitsT> *Map; + uint32_t Index; + bool IsEnd; +}; + +template <typename T> struct PdbHashTraits {}; + +template <> struct PdbHashTraits<uint32_t> { + uint32_t hashLookupKey(uint32_t N) const { return N; } + uint32_t storageKeyToLookupKey(uint32_t N) const { return N; } + uint32_t lookupKeyToStorageKey(uint32_t N) { return N; } +}; + +template <typename ValueT, typename TraitsT = PdbHashTraits<ValueT>> class HashTable { - friend class HashTableIterator; + using iterator = HashTableIterator<ValueT, TraitsT>; + friend iterator; struct Header { support::ulittle32_t Size; support::ulittle32_t Capacity; }; - using BucketList = std::vector<std::pair<uint32_t, uint32_t>>; + using BucketList = std::vector<std::pair<uint32_t, ValueT>>; public: - HashTable(); - explicit HashTable(uint32_t Capacity); + HashTable() { Buckets.resize(8); } + + explicit HashTable(TraitsT Traits) : HashTable(8, std::move(Traits)) {} + HashTable(uint32_t Capacity, TraitsT Traits) : Traits(Traits) { + Buckets.resize(Capacity); + } + + Error load(BinaryStreamReader &Stream) { + const Header *H; + if (auto EC = Stream.readObject(H)) + return EC; + if (H->Capacity == 0) + return make_error<RawError>(raw_error_code::corrupt_file, + "Invalid Hash Table Capacity"); + if (H->Size > maxLoad(H->Capacity)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Invalid Hash Table Size"); + + Buckets.resize(H->Capacity); + + if (auto EC = readSparseBitVector(Stream, Present)) + return EC; + if (Present.count() != H->Size) + return make_error<RawError>(raw_error_code::corrupt_file, + "Present bit vector does not match size!"); + + if (auto EC = readSparseBitVector(Stream, Deleted)) + return EC; + if (Present.intersects(Deleted)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Present bit vector interesects deleted!"); - Error load(BinaryStreamReader &Stream); + for (uint32_t P : Present) { + if (auto EC = Stream.readInteger(Buckets[P].first)) + return EC; + const ValueT *Value; + if (auto EC = Stream.readObject(Value)) + return EC; + Buckets[P].second = *Value; + } - uint32_t calculateSerializedLength() const; - Error commit(BinaryStreamWriter &Writer) const; + return Error::success(); + } - void clear(); + uint32_t calculateSerializedLength() const { + uint32_t Size = sizeof(Header); - uint32_t capacity() const; - uint32_t size() const; + constexpr int BitsPerWord = 8 * sizeof(uint32_t); - HashTableIterator begin() const; - HashTableIterator end() const; - HashTableIterator find(uint32_t K); + int NumBitsP = Present.find_last() + 1; + int NumBitsD = Deleted.find_last() + 1; - void set(uint32_t K, uint32_t V); - void remove(uint32_t K); - uint32_t get(uint32_t K); + uint32_t NumWordsP = alignTo(NumBitsP, BitsPerWord) / BitsPerWord; + uint32_t NumWordsD = alignTo(NumBitsD, BitsPerWord) / BitsPerWord; + + // Present bit set number of words (4 bytes), followed by that many actual + // words (4 bytes each). + Size += sizeof(uint32_t); + Size += NumWordsP * sizeof(uint32_t); + + // Deleted bit set number of words (4 bytes), followed by that many actual + // words (4 bytes each). + Size += sizeof(uint32_t); + Size += NumWordsD * sizeof(uint32_t); + + // One (Key, ValueT) pair for each entry Present. + Size += (sizeof(uint32_t) + sizeof(ValueT)) * size(); + + return Size; + } + + Error commit(BinaryStreamWriter &Writer) const { + Header H; + H.Size = size(); + H.Capacity = capacity(); + if (auto EC = Writer.writeObject(H)) + return EC; + + if (auto EC = writeSparseBitVector(Writer, Present)) + return EC; + + if (auto EC = writeSparseBitVector(Writer, Deleted)) + return EC; + + for (const auto &Entry : *this) { + if (auto EC = Writer.writeInteger(Entry.first)) + return EC; + if (auto EC = Writer.writeObject(Entry.second)) + return EC; + } + return Error::success(); + } + + void clear() { + Buckets.resize(8); + Present.clear(); + Deleted.clear(); + } + + bool empty() const { return size() == 0; } + uint32_t capacity() const { return Buckets.size(); } + uint32_t size() const { return Present.count(); } + + iterator begin() const { return iterator(*this); } + iterator end() const { return iterator(*this, 0, true); } + + /// Find the entry whose key has the specified hash value, using the specified + /// traits defining hash function and equality. + template <typename Key> iterator find_as(const Key &K) const { + uint32_t H = Traits.hashLookupKey(K) % capacity(); + uint32_t I = H; + Optional<uint32_t> FirstUnused; + do { + if (isPresent(I)) { + if (Traits.storageKeyToLookupKey(Buckets[I].first) == K) + return iterator(*this, I, false); + } else { + if (!FirstUnused) + FirstUnused = I; + // Insertion occurs via linear probing from the slot hint, and will be + // inserted at the first empty / deleted location. Therefore, if we are + // probing and find a location that is neither present nor deleted, then + // nothing must have EVER been inserted at this location, and thus it is + // not possible for a matching value to occur later. + if (!isDeleted(I)) + break; + } + I = (I + 1) % capacity(); + } while (I != H); + + // The only way FirstUnused would not be set is if every single entry in the + // table were Present. But this would violate the load factor constraints + // that we impose, so it should never happen. + assert(FirstUnused); + return iterator(*this, *FirstUnused, true); + } + + /// Set the entry using a key type that the specified Traits can convert + /// from a real key to an internal key. + template <typename Key> bool set_as(const Key &K, ValueT V) { + return set_as_internal(K, std::move(V), None); + } + + template <typename Key> ValueT get(const Key &K) const { + auto Iter = find_as(K); + assert(Iter != end()); + return (*Iter).second; + } protected: bool isPresent(uint32_t K) const { return Present.test(K); } bool isDeleted(uint32_t K) const { return Deleted.test(K); } + TraitsT Traits; BucketList Buckets; mutable SparseBitVector<> Present; mutable SparseBitVector<> Deleted; private: - static uint32_t maxLoad(uint32_t capacity); - void grow(); + /// Set the entry using a key type that the specified Traits can convert + /// from a real key to an internal key. + template <typename Key> + bool set_as_internal(const Key &K, ValueT V, Optional<uint32_t> InternalKey) { + auto Entry = find_as(K); + if (Entry != end()) { + assert(isPresent(Entry.index())); + assert(Traits.storageKeyToLookupKey(Buckets[Entry.index()].first) == K); + // We're updating, no need to do anything special. + Buckets[Entry.index()].second = V; + return false; + } - static Error readSparseBitVector(BinaryStreamReader &Stream, - SparseBitVector<> &V); - static Error writeSparseBitVector(BinaryStreamWriter &Writer, - SparseBitVector<> &Vec); -}; + auto &B = Buckets[Entry.index()]; + assert(!isPresent(Entry.index())); + assert(Entry.isEnd()); + B.first = InternalKey ? *InternalKey : Traits.lookupKeyToStorageKey(K); + B.second = V; + Present.set(Entry.index()); + Deleted.reset(Entry.index()); -class HashTableIterator - : public iterator_facade_base<HashTableIterator, std::forward_iterator_tag, - std::pair<uint32_t, uint32_t>> { - friend class HashTable; + grow(); - HashTableIterator(const HashTable &Map, uint32_t Index, bool IsEnd); + assert((find_as(K)) != end()); + return true; + } -public: - HashTableIterator(const HashTable &Map); + static uint32_t maxLoad(uint32_t capacity) { return capacity * 2 / 3 + 1; } - HashTableIterator &operator=(const HashTableIterator &R); - bool operator==(const HashTableIterator &R) const; - const std::pair<uint32_t, uint32_t> &operator*() const; - HashTableIterator &operator++(); + void grow() { + uint32_t S = size(); + uint32_t MaxLoad = maxLoad(capacity()); + if (S < maxLoad(capacity())) + return; + assert(capacity() != UINT32_MAX && "Can't grow Hash table!"); -private: - bool isEnd() const { return IsEnd; } - uint32_t index() const { return Index; } + uint32_t NewCapacity = (capacity() <= INT32_MAX) ? MaxLoad * 2 : UINT32_MAX; - const HashTable *Map; - uint32_t Index; - bool IsEnd; + // Growing requires rebuilding the table and re-hashing every item. Make a + // copy with a larger capacity, insert everything into the copy, then swap + // it in. + HashTable NewMap(NewCapacity, Traits); + for (auto I : Present) { + auto LookupKey = Traits.storageKeyToLookupKey(Buckets[I].first); + NewMap.set_as_internal(LookupKey, Buckets[I].second, Buckets[I].first); + } + + Buckets.swap(NewMap.Buckets); + std::swap(Present, NewMap.Present); + std::swap(Deleted, NewMap.Deleted); + assert(capacity() == NewCapacity); + assert(size() == S); + } }; } // end namespace pdb diff --git a/include/llvm/DebugInfo/PDB/Native/InfoStream.h b/include/llvm/DebugInfo/PDB/Native/InfoStream.h index fb8271cb5ebc..8c52b042f289 100644 --- a/include/llvm/DebugInfo/PDB/Native/InfoStream.h +++ b/include/llvm/DebugInfo/PDB/Native/InfoStream.h @@ -30,12 +30,14 @@ class InfoStream { friend class InfoStreamBuilder; public: - InfoStream(std::unique_ptr<msf::MappedBlockStream> Stream); + InfoStream(std::unique_ptr<BinaryStream> Stream); Error reload(); uint32_t getStreamSize() const; + const InfoStreamHeader *getHeader() const { return Header; } + bool containsIdStream() const; PdbRaw_ImplVer getVersion() const; uint32_t getSignature() const; @@ -50,29 +52,13 @@ public: BinarySubstreamRef getNamedStreamsBuffer() const; - uint32_t getNamedStreamIndex(llvm::StringRef Name) const; - iterator_range<StringMapConstIterator<uint32_t>> named_streams() const; + Expected<uint32_t> getNamedStreamIndex(llvm::StringRef Name) const; + StringMap<uint32_t> named_streams() const; private: - std::unique_ptr<msf::MappedBlockStream> Stream; - - // PDB file format version. We only support VC70. See the enumeration - // `PdbRaw_ImplVer` for the other possible values. - uint32_t Version; - - // A 32-bit signature unique across all PDBs. This is generated with - // a call to time() when the PDB is written, but obviously this is not - // universally unique. - uint32_t Signature; - - // The number of times the PDB has been written. Might also be used to - // ensure that the PDB matches the executable. - uint32_t Age; + std::unique_ptr<BinaryStream> Stream; - // Due to the aforementioned limitations with `Signature`, this is a new - // signature present on VC70 and higher PDBs which is guaranteed to be - // universally unique. - codeview::GUID Guid; + const InfoStreamHeader *Header; BinarySubstreamRef SubNamedStreams; diff --git a/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h index c6cb0e221e70..419e8ada06f7 100644 --- a/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h @@ -40,6 +40,10 @@ public: void setGuid(codeview::GUID G); void addFeature(PdbRaw_FeatureSig Sig); + uint32_t getAge() const { return Age; } + codeview::GUID getGuid() const { return Guid; } + Optional<uint32_t> getSignature() const { return Signature; } + uint32_t finalize(); Error finalizeMsfLayout(); @@ -52,8 +56,8 @@ private: std::vector<PdbRaw_FeatureSig> Features; PdbRaw_ImplVer Ver; - uint32_t Sig; uint32_t Age; + Optional<uint32_t> Signature; codeview::GUID Guid; NamedStreamMap &NamedStreams; diff --git a/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h b/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h index 17a82b7ce12d..01b8f1b5da56 100644 --- a/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h +++ b/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h @@ -25,32 +25,45 @@ class BinaryStreamWriter; namespace pdb { +class NamedStreamMap; + +struct NamedStreamMapTraits { + NamedStreamMap *NS; + + explicit NamedStreamMapTraits(NamedStreamMap &NS); + uint16_t hashLookupKey(StringRef S) const; + StringRef storageKeyToLookupKey(uint32_t Offset) const; + uint32_t lookupKeyToStorageKey(StringRef S); +}; + class NamedStreamMap { friend class NamedStreamMapBuilder; - struct FinalizationInfo { - uint32_t StringDataBytes = 0; - uint32_t SerializedLength = 0; - }; - public: NamedStreamMap(); Error load(BinaryStreamReader &Stream); Error commit(BinaryStreamWriter &Writer) const; - uint32_t finalize(); + uint32_t calculateSerializedLength() const; uint32_t size() const; bool get(StringRef Stream, uint32_t &StreamNo) const; void set(StringRef Stream, uint32_t StreamNo); - void remove(StringRef Stream); - const StringMap<uint32_t> &getStringMap() const { return Mapping; } - iterator_range<StringMapConstIterator<uint32_t>> entries() const; + + uint32_t appendStringData(StringRef S); + StringRef getString(uint32_t Offset) const; + uint32_t hashString(uint32_t Offset) const; + + StringMap<uint32_t> entries() const; private: - Optional<FinalizationInfo> FinalizedInfo; - HashTable FinalizedHashTable; - StringMap<uint32_t> Mapping; + NamedStreamMapTraits HashTraits; + /// Closed hash table from Offset -> StreamNumber, where Offset is the offset + /// of the stream name in NamesBuffer. + HashTable<support::ulittle32_t, NamedStreamMapTraits> OffsetIndexMap; + + /// Buffer of string data. + std::vector<char> NamesBuffer; }; } // end namespace pdb diff --git a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h index 931b93fb7266..5b70ecfa2056 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h @@ -35,10 +35,31 @@ public: findChildren(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags) const override; std::unique_ptr<IPDBEnumSymbols> + findChildrenByAddr(PDB_SymType Type, StringRef Name, + PDB_NameSearchFlags Flags, + uint32_t Section, uint32_t Offset) const override; + std::unique_ptr<IPDBEnumSymbols> + findChildrenByVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags, + uint64_t VA) const override; + std::unique_ptr<IPDBEnumSymbols> findChildrenByRVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags, uint32_t RVA) const override; + + std::unique_ptr<IPDBEnumSymbols> + findInlineFramesByAddr(uint32_t Section, uint32_t Offset) const override; std::unique_ptr<IPDBEnumSymbols> findInlineFramesByRVA(uint32_t RVA) const override; + std::unique_ptr<IPDBEnumSymbols> + findInlineFramesByVA(uint64_t VA) const override; + + std::unique_ptr<IPDBEnumLineNumbers> findInlineeLines() const override; + std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByAddr(uint32_t Section, uint32_t Offset, + uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findInlineeLinesByVA(uint64_t VA, uint32_t Length) const override; void getDataBytes(SmallVector<uint8_t, 32> &Bytes) const override; void getFrontEndVersion(VersionInfo &Version) const override; @@ -87,6 +108,7 @@ public: uint32_t getSizeInUdt() const override; uint32_t getSlot() const override; std::string getSourceFileName() const override; + std::unique_ptr<IPDBLineNumber> getSrcLineOnTypeDefn() const override; uint32_t getStride() const override; uint32_t getSubTypeId() const override; std::string getSymbolsFileName() const override; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/include/llvm/DebugInfo/PDB/Native/NativeSession.h index 2e68ced46bfe..aff7ef2f8f21 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeSession.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -49,18 +49,33 @@ public: SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI); uint64_t getLoadAddress() const override; - void setLoadAddress(uint64_t Address) override; + bool setLoadAddress(uint64_t Address) override; std::unique_ptr<PDBSymbolExe> getGlobalScope() override; std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override; + bool addressForVA(uint64_t VA, uint32_t &Section, + uint32_t &Offset) const override; + bool addressForRVA(uint32_t RVA, uint32_t &Section, + uint32_t &Offset) const override; + std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override; + std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA, + PDB_SymType Type) const override; + std::unique_ptr<PDBSymbol> + findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, + PDB_SymType Type) const override; std::unique_ptr<IPDBEnumLineNumbers> findLineNumbers(const PDBSymbolCompiland &Compiland, const IPDBSourceFile &File) const override; std::unique_ptr<IPDBEnumLineNumbers> findLineNumbersByAddress(uint64_t Address, uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const override; + std::unique_ptr<IPDBEnumLineNumbers> + findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset, + uint32_t Length) const override; std::unique_ptr<IPDBEnumSourceFiles> findSourceFiles(const PDBSymbolCompiland *Compiland, llvm::StringRef Pattern, @@ -85,6 +100,10 @@ public: std::unique_ptr<IPDBEnumTables> getEnumTables() const override; + std::unique_ptr<IPDBEnumInjectedSources> getInjectedSources() const override; + + std::unique_ptr<IPDBEnumSectionContribs> getSectionContribs() const override; + PDBFile &getPDBFile() { return *Pdb; } const PDBFile &getPDBFile() const { return *Pdb; } @@ -94,7 +113,7 @@ private: std::vector<std::unique_ptr<NativeRawSymbol>> SymbolCache; DenseMap<codeview::TypeIndex, SymIndexId> TypeIndexToSymbolId; }; -} -} +} // namespace pdb +} // namespace llvm #endif diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h index 7ed164bee9ee..7f9c4cf9fa83 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h @@ -17,9 +17,11 @@ #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBuffer.h" #include <memory> #include <vector> @@ -54,12 +56,34 @@ public: Error commit(StringRef Filename); Expected<uint32_t> getNamedStreamIndex(StringRef Name) const; - Error addNamedStream(StringRef Name, uint32_t Size); + Error addNamedStream(StringRef Name, StringRef Data); + void addInjectedSource(StringRef Name, std::unique_ptr<MemoryBuffer> Buffer); private: - Expected<msf::MSFLayout> finalizeMsfLayout(); + struct InjectedSourceDescriptor { + // The full name of the stream that contains the contents of this injected + // source. This is built as a concatenation of the literal "/src/files" + // plus the "vname". + std::string StreamName; + + // The exact name of the file name as specified by the user. + uint32_t NameIndex; + + // The string table index of the "vname" of the file. As far as we + // understand, this is the same as the name, except it is lowercased and + // forward slashes are converted to backslashes. + uint32_t VNameIndex; + std::unique_ptr<MemoryBuffer> Content; + }; + + Error finalizeMsfLayout(); + Expected<uint32_t> allocateNamedStream(StringRef Name, uint32_t Size); void commitFpm(WritableBinaryStream &MsfBuffer, const msf::MSFLayout &Layout); + void commitInjectedSources(WritableBinaryStream &MsfBuffer, + const msf::MSFLayout &Layout); + void commitSrcHeaderBlock(WritableBinaryStream &MsfBuffer, + const msf::MSFLayout &Layout); BumpPtrAllocator &Allocator; @@ -71,7 +95,13 @@ private: std::unique_ptr<TpiStreamBuilder> Ipi; PDBStringTableBuilder Strings; + StringTableHashTraits InjectedSourceHashTraits; + HashTable<SrcHeaderBlockEntry, StringTableHashTraits> InjectedSourceTable; + + SmallVector<InjectedSourceDescriptor, 2> InjectedSources; + NamedStreamMap NamedStreams; + DenseMap<uint32_t, std::string> NamedStreamData; }; } } diff --git a/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h index b57707ee7923..0f81c18eafe6 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h @@ -31,6 +31,16 @@ struct MSFLayout; namespace pdb { class PDBFileBuilder; +class PDBStringTableBuilder; + +struct StringTableHashTraits { + PDBStringTableBuilder *Table; + + explicit StringTableHashTraits(PDBStringTableBuilder &Table); + uint32_t hashLookupKey(StringRef S) const; + StringRef storageKeyToLookupKey(uint32_t Offset) const; + uint32_t lookupKeyToStorageKey(StringRef S); +}; class PDBStringTableBuilder { public: @@ -38,6 +48,9 @@ public: // Returns the ID for S. uint32_t insert(StringRef S); + uint32_t getIdForString(StringRef S) const; + StringRef getStringForId(uint32_t Id) const; + uint32_t calculateSerializedSize() const; Error commit(BinaryStreamWriter &Writer) const; diff --git a/include/llvm/DebugInfo/PDB/Native/RawConstants.h b/include/llvm/DebugInfo/PDB/Native/RawConstants.h index bb1d097b5123..fbbd3318d958 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawConstants.h +++ b/include/llvm/DebugInfo/PDB/Native/RawConstants.h @@ -32,6 +32,8 @@ enum PdbRaw_ImplVer : uint32_t { PdbImplVC140 = 20140508, }; +enum class PdbRaw_SrcHeaderBlockVer : uint32_t { SrcVerOne = 19980827 }; + enum class PdbRaw_FeatureSig : uint32_t { VC110 = PdbImplVC110, VC140 = PdbImplVC140, diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index 8cc083685265..19f592d562e4 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -112,6 +112,8 @@ struct DbiBuildNo { static const uint16_t BuildMajorMask = 0x7F00; static const uint16_t BuildMajorShift = 8; + + static const uint16_t NewVersionFormatMask = 0x8000; }; /// The fixed size header that appears at the beginning of the DBI Stream. @@ -175,18 +177,6 @@ struct DbiStreamHeader { }; static_assert(sizeof(DbiStreamHeader) == 64, "Invalid DbiStreamHeader size!"); -struct SectionContribEntry { - support::ulittle16_t Section; - char Padding1[2]; - support::little32_t Offset; - support::little32_t Size; - support::ulittle32_t Characteristics; - support::ulittle16_t ModuleIndex; - char Padding2[2]; - support::ulittle32_t DataCrc; - support::ulittle32_t RelocCrc; -}; - /// The header preceeding the File Info Substream of the DBI stream. struct FileInfoSubstreamHeader { /// Total # of modules, should match number of records in the ModuleInfo @@ -228,7 +218,7 @@ struct ModuleInfoHeader { support::ulittle32_t Mod; /// First section contribution of this module. - SectionContribEntry SC; + SectionContrib SC; /// See ModInfoFlags definition. support::ulittle16_t Flags; @@ -328,6 +318,34 @@ struct PDBStringTableHeader { const uint32_t PDBStringTableSignature = 0xEFFEEFFE; +/// The header preceding the /src/headerblock stream. +struct SrcHeaderBlockHeader { + support::ulittle32_t Version; // PdbRaw_SrcHeaderBlockVer enumeration. + support::ulittle32_t Size; // Size of entire stream. + uint64_t FileTime; // Time stamp (Windows FILETIME format). + support::ulittle32_t Age; // Age + uint8_t Padding[44]; // Pad to 64 bytes. +}; +static_assert(sizeof(SrcHeaderBlockHeader) == 64, "Incorrect struct size!"); + +/// A single file record entry within the /src/headerblock stream. +struct SrcHeaderBlockEntry { + support::ulittle32_t Size; // Record Length. + support::ulittle32_t Version; // PdbRaw_SrcHeaderBlockVer enumeration. + support::ulittle32_t CRC; // CRC of the original file contents. + support::ulittle32_t FileSize; // Size of original source file. + support::ulittle32_t FileNI; // String table index of file name. + support::ulittle32_t ObjNI; // String table index of object name. + support::ulittle32_t VFileNI; // String table index of virtual file name. + uint8_t Compression; // PDB_SourceCompression enumeration. + uint8_t IsVirtual; // Is this a virtual file (injected)? + short Padding; // Pad to 4 bytes. + char Reserved[8]; +}; + +constexpr int I = sizeof(SrcHeaderBlockEntry); +static_assert(sizeof(SrcHeaderBlockEntry) == 40, "Incorrect struct size!"); + } // namespace pdb } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/Native/TpiStream.h b/include/llvm/DebugInfo/PDB/Native/TpiStream.h index d3475205a6c2..b77939929ecf 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStream.h @@ -51,7 +51,7 @@ public: uint32_t getNumHashBuckets() const; FixedStreamArray<support::ulittle32_t> getHashValues() const; FixedStreamArray<codeview::TypeIndexOffset> getTypeIndexOffsets() const; - HashTable &getHashAdjusters(); + HashTable<support::ulittle32_t> &getHashAdjusters(); codeview::CVTypeRange types(bool *HadError) const; const codeview::CVTypeArray &typeArray() const { return TypeRecords; } @@ -75,7 +75,7 @@ private: std::unique_ptr<BinaryStream> HashStream; FixedStreamArray<support::ulittle32_t> HashValues; FixedStreamArray<codeview::TypeIndexOffset> TypeIndexOffsets; - HashTable HashAdjusters; + HashTable<support::ulittle32_t> HashAdjusters; const TpiStreamHeader *Header; }; diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h index 778121c8eb79..3c9a19801f89 100644 --- a/include/llvm/DebugInfo/PDB/PDBExtras.h +++ b/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -34,6 +34,8 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag); raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access); raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type); raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine); +raw_ostream &operator<<(raw_ostream &OS, + const PDB_SourceCompression &Compression); raw_ostream &operator<<(raw_ostream &OS, const Variant &Value); raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version); diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h index 26788017cf32..9549089c7eb4 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h @@ -34,6 +34,7 @@ public: FORWARD_SYMBOL_METHOD(getName) std::string getSourceFileName() const; + std::string getSourceFileFullPath() const; }; } } diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolData.h b/include/llvm/DebugInfo/PDB/PDBSymbolData.h index ad4285df4d44..76b14bf17784 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolData.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolData.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOLDATA_H #define LLVM_DEBUGINFO_PDB_PDBSYMBOLDATA_H +#include "IPDBLineNumber.h" #include "PDBSymbol.h" #include "PDBTypes.h" @@ -53,9 +54,11 @@ public: FORWARD_SYMBOL_METHOD(getValue) FORWARD_SYMBOL_METHOD(getVirtualAddress) FORWARD_SYMBOL_METHOD(isVolatileType) -}; + std::unique_ptr<IPDBEnumLineNumbers> getLineNumbers() const; + uint32_t getCompilandId() const; +}; +} // namespace pdb } // namespace llvm -} #endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLDATA_H diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h index c2f02ea6f126..05d585d25763 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOLFUNC_H #define LLVM_DEBUGINFO_PDB_PDBSYMBOLFUNC_H +#include "IPDBLineNumber.h" #include "PDBSymbol.h" #include "PDBSymbolTypeFunctionSig.h" #include "PDBTypes.h" @@ -38,7 +39,9 @@ public: FORWARD_SYMBOL_METHOD(getAddressSection) FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_METHOD(isCompilerGenerated) + FORWARD_SYMBOL_METHOD(isConstructorVirtualBase) FORWARD_SYMBOL_METHOD(isConstType) + FORWARD_SYMBOL_METHOD(isCxxReturnUdt) FORWARD_SYMBOL_METHOD(hasCustomCallingConvention) FORWARD_SYMBOL_METHOD(hasFarReturn) FORWARD_SYMBOL_METHOD(hasAlloca) @@ -76,6 +79,9 @@ public: FORWARD_SYMBOL_METHOD(getVirtualAddress) FORWARD_SYMBOL_METHOD(getVirtualBaseOffset) FORWARD_SYMBOL_METHOD(isVolatileType) + + std::unique_ptr<IPDBEnumLineNumbers> getLineNumbers() const; + uint32_t getCompilandId() const; }; } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h index c5ae3c51162c..ddbe7e58f183 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEENUM_H #define LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEENUM_H +#include "IPDBLineNumber.h" #include "PDBSymbol.h" #include "PDBSymbolTypeBuiltin.h" #include "PDBTypes.h" @@ -38,6 +39,7 @@ public: FORWARD_SYMBOL_METHOD(getLength) FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) + FORWARD_SYMBOL_METHOD(getSrcLineOnTypeDefn) FORWARD_SYMBOL_METHOD(isNested) FORWARD_SYMBOL_METHOD(hasOverloadedOperator) FORWARD_SYMBOL_METHOD(isPacked) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h index 8de54e70701d..abd4cf5effa2 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h @@ -31,6 +31,8 @@ public: void dumpRight(PDBSymDumper &Dumper) const override; void dumpArgList(raw_ostream &OS) const; + bool isCVarArgs() const; + FORWARD_SYMBOL_METHOD(getCallingConvention) FORWARD_SYMBOL_ID_METHOD(getClassParent) FORWARD_SYMBOL_ID_METHOD(getUnmodifiedType) diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h index c502d4e77afe..7612ebac31dd 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h @@ -32,7 +32,11 @@ public: FORWARD_SYMBOL_METHOD(getLength) FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(isReference) + FORWARD_SYMBOL_METHOD(isRValueReference) + FORWARD_SYMBOL_METHOD(isPointerToDataMember) + FORWARD_SYMBOL_METHOD(isPointerToMemberFunction) FORWARD_SYMBOL_ID_METHOD_WITH_NAME(getType, getPointeeType) + FORWARD_SYMBOL_METHOD(isRestrictedType) FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_METHOD(isVolatileType) }; diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h index e9e7fe8c9865..e259b6dca3d5 100644 --- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h +++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h @@ -10,6 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEUDT_H #define LLVM_DEBUGINFO_PDB_PDBSYMBOLTYPEUDT_H +#include "IPDBLineNumber.h" #include "IPDBSession.h" #include "PDBSymbol.h" #include "PDBSymbolTypeBaseClass.h" @@ -45,6 +46,7 @@ public: FORWARD_SYMBOL_METHOD(getLength) FORWARD_SYMBOL_ID_METHOD(getLexicalParent) FORWARD_SYMBOL_METHOD(getName) + FORWARD_SYMBOL_METHOD(getSrcLineOnTypeDefn) FORWARD_SYMBOL_METHOD(isNested) FORWARD_SYMBOL_METHOD(hasOverloadedOperator) FORWARD_SYMBOL_METHOD(isPacked) @@ -53,6 +55,7 @@ public: FORWARD_SYMBOL_METHOD(isUnalignedType) FORWARD_SYMBOL_ID_METHOD(getVirtualTableShape) FORWARD_SYMBOL_METHOD(isVolatileType) + FORWARD_SYMBOL_METHOD(getAccess) }; } } // namespace llvm diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h index a6c6da37d1cc..da6cb1d26771 100644 --- a/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -23,7 +23,9 @@ namespace llvm { namespace pdb { class IPDBDataStream; +class IPDBInjectedSource; class IPDBLineNumber; +class IPDBSectionContrib; class IPDBSourceFile; class IPDBTable; class PDBSymDumper; @@ -65,6 +67,8 @@ using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>; using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>; using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>; using IPDBEnumTables = IPDBEnumChildren<IPDBTable>; +using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>; +using IPDBEnumSectionContribs = IPDBEnumChildren<IPDBSectionContrib>; /// Specifies which PDB reader implementation is to be used. Only a value /// of PDB_ReaderType::DIA is currently supported, but Native is in the works. @@ -96,13 +100,18 @@ enum PDB_NameSearchFlags { NS_CaseInsensitive = 0x2, NS_FileNameExtMatch = 0x4, NS_Regex = 0x8, - NS_UndecoratedName = 0x10 + NS_UndecoratedName = 0x10, + + // For backward compatibility. + NS_CaseInFileNameExt = NS_CaseInsensitive | NS_FileNameExtMatch, + NS_CaseRegex = NS_Regex | NS_CaseSensitive, + NS_CaseInRex = NS_Regex | NS_CaseInsensitive }; /// Specifies the hash algorithm that a source file from a PDB was hashed with. /// This corresponds to the CV_SourceChksum_t enumeration and are documented /// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx -enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 }; +enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2, SHA256 = 3 }; /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx @@ -133,6 +142,13 @@ enum class PDB_Machine { WceMipsV2 = 0x169 }; +enum class PDB_SourceCompression { + None, + RunLengthEncoded, + Huffman, + LZ, +}; + /// These values correspond to the CV_call_e enumeration, and are documented /// at the following locations: /// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx @@ -209,6 +225,7 @@ enum class PDB_LocType { IlRel, MetaData, Constant, + RegRelAliasIndir, Max }; @@ -218,11 +235,24 @@ enum class PDB_UdtType { Struct, Class, Union, Interface }; /// These values correspond to the StackFrameTypeEnum enumeration, and are /// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. -enum class PDB_StackFrameType { FPO, KernelTrap, KernelTSS, EBP, FrameData }; +enum class PDB_StackFrameType : uint16_t { + FPO, + KernelTrap, + KernelTSS, + EBP, + FrameData, + Unknown = 0xffff +}; -/// These values correspond to the StackFrameTypeEnum enumeration, and are -/// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. -enum class PDB_MemoryType { Code, Data, Stack, HeapCode }; +/// These values correspond to the MemoryTypeEnum enumeration, and are +/// documented here: https://msdn.microsoft.com/en-us/library/ms165609.aspx. +enum class PDB_MemoryType : uint16_t { + Code, + Data, + Stack, + HeapCode, + Any = 0xffff +}; /// These values correspond to the Basictype enumeration, and are documented /// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx @@ -244,13 +274,15 @@ enum class PDB_BuiltinType { Complex = 28, Bitfield = 29, BSTR = 30, - HResult = 31 + HResult = 31, + Char16 = 32, + Char32 = 33 }; /// These values correspond to the flags that can be combined to control the /// return of an undecorated name for a C++ decorated name, and are documented /// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx -enum PDB_UndnameFlags: uint32_t { +enum PDB_UndnameFlags : uint32_t { Undname_Complete = 0x0, Undname_NoLeadingUnderscores = 0x1, Undname_NoMsKeywords = 0x2, |