Index: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h +++ llvm/trunk/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 { +public: + explicit DIAEnumInjectedSources( + const DIASession &PDBSession, + CComPtr 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 Enumerator; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIAENUMINJECTEDSOURCES_H Index: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h @@ -0,0 +1,40 @@ +//===- 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(const DIASession &Session, + CComPtr 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: + const DIASession &Session; + CComPtr SourceFile; +}; +} // namespace pdb +} // namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIAINJECTEDSOURCE_H Index: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -65,6 +65,9 @@ std::unique_ptr getDebugStreams() const override; std::unique_ptr getEnumTables() const override; + + std::unique_ptr getInjectedSources() const override; + private: CComPtr Session; }; Index: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIAUtils.h +++ llvm/trunk/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 +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 StrBytes(reinterpret_cast(Str16.m_str), + Str16.ByteLength()); + llvm::convertUTF16ToUTF8String(StrBytes, Str8); + return Str8; +} + +#endif // LLVM_DEBUGINFO_PDB_DIA_DIAUTILS_H Index: llvm/trunk/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h +++ llvm/trunk/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 +#include + +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 Index: llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -69,6 +69,9 @@ virtual std::unique_ptr getDebugStreams() const = 0; virtual std::unique_ptr getEnumTables() const = 0; + + virtual std::unique_ptr + getInjectedSources() const = 0; }; } } Index: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -85,6 +85,8 @@ std::unique_ptr getEnumTables() const override; + std::unique_ptr getInjectedSources() const override; + PDBFile &getPDBFile() { return *Pdb; } const PDBFile &getPDBFile() const { return *Pdb; } Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBExtras.h @@ -34,6 +34,8 @@ 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); Index: llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -23,6 +23,7 @@ namespace pdb { class IPDBDataStream; +class IPDBInjectedSource; class IPDBLineNumber; class IPDBSourceFile; class IPDBTable; @@ -65,6 +66,7 @@ using IPDBEnumDataStreams = IPDBEnumChildren; using IPDBEnumLineNumbers = IPDBEnumChildren; using IPDBEnumTables = IPDBEnumChildren; +using IPDBEnumInjectedSources = IPDBEnumChildren; /// 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. @@ -133,6 +135,13 @@ 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 Index: llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt +++ llvm/trunk/lib/DebugInfo/PDB/CMakeLists.txt @@ -14,11 +14,13 @@ add_pdb_impl_folder(DIA DIA/DIADataStream.cpp DIA/DIAEnumDebugStreams.cpp + DIA/DIAEnumInjectedSources.cpp DIA/DIAEnumLineNumbers.cpp DIA/DIAEnumSourceFiles.cpp DIA/DIAEnumSymbols.cpp DIA/DIAEnumTables.cpp DIA/DIAError.cpp + DIA/DIAInjectedSource.cpp DIA/DIALineNumber.cpp DIA/DIARawSymbol.cpp DIA/DIASession.cpp Index: llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp +++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp @@ -0,0 +1,54 @@ +//==- DIAEnumSourceFiles.cpp - DIA Source File Enumerator impl ---*- 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/DIA/DIAEnumInjectedSources.h" +#include "llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h" +#include "llvm/DebugInfo/PDB/PDBSymbol.h" + +using namespace llvm; +using namespace llvm::pdb; + +DIAEnumInjectedSources::DIAEnumInjectedSources( + const DIASession &PDBSession, + CComPtr DiaEnumerator) + : Session(PDBSession), Enumerator(DiaEnumerator) {} + +uint32_t DIAEnumInjectedSources::getChildCount() const { + LONG Count = 0; + return (S_OK == Enumerator->get_Count(&Count)) ? Count : 0; +} + +std::unique_ptr +DIAEnumInjectedSources::getChildAtIndex(uint32_t Index) const { + CComPtr Item; + if (S_OK != Enumerator->Item(Index, &Item)) + return nullptr; + + return std::unique_ptr( + new DIAInjectedSource(Session, Item)); +} + +std::unique_ptr DIAEnumInjectedSources::getNext() { + CComPtr Item; + ULONG NumFetched = 0; + if (S_OK != Enumerator->Next(1, &Item, &NumFetched)) + return nullptr; + + return std::unique_ptr( + new DIAInjectedSource(Session, Item)); +} + +void DIAEnumInjectedSources::reset() { Enumerator->Reset(); } + +DIAEnumInjectedSources *DIAEnumInjectedSources::clone() const { + CComPtr EnumeratorClone; + if (S_OK != Enumerator->Clone(&EnumeratorClone)) + return nullptr; + return new DIAEnumInjectedSources(Session, EnumeratorClone); +} Index: llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp +++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp @@ -0,0 +1,64 @@ +//===- DIAInjectedSource.cpp - 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. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/PDB/DIA/DIAInjectedSource.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" +#include "llvm/DebugInfo/PDB/DIA/DIASession.h" +#include "llvm/DebugInfo/PDB/DIA/DIAUtils.h" + +using namespace llvm; +using namespace llvm::pdb; + +DIAInjectedSource::DIAInjectedSource(const DIASession &Session, + CComPtr DiaSourceFile) + : Session(Session), SourceFile(DiaSourceFile) {} + +uint32_t DIAInjectedSource::getCrc32() const { + DWORD Crc; + return (S_OK == SourceFile->get_crc(&Crc)) ? Crc : 0; +} + +uint64_t DIAInjectedSource::getCodeByteSize() const { + ULONGLONG Size; + return (S_OK == SourceFile->get_length(&Size)) ? Size : 0; +} + +std::string DIAInjectedSource::getFileName() const { + return invokeBstrMethod(*SourceFile, &IDiaInjectedSource::get_filename); +} + +std::string DIAInjectedSource::getObjectFileName() const { + return invokeBstrMethod(*SourceFile, &IDiaInjectedSource::get_objectFilename); +} + +std::string DIAInjectedSource::getVirtualFileName() const { + return invokeBstrMethod(*SourceFile, + &IDiaInjectedSource::get_virtualFilename); +} + +PDB_SourceCompression DIAInjectedSource::getCompression() const { + DWORD Compression = 0; + if (S_OK != SourceFile->get_sourceCompression(&Compression)) + return PDB_SourceCompression::None; + return static_cast(Compression); +} + +std::string DIAInjectedSource::getCode() const { + DWORD DataSize; + if (S_OK != SourceFile->get_source(0, &DataSize, nullptr)) + return ""; + + std::vector Buffer(DataSize); + if (S_OK != SourceFile->get_source(DataSize, &DataSize, Buffer.data())) + return ""; + assert(Buffer.size() == DataSize); + return std::string(reinterpret_cast(Buffer.data()), + Buffer.size()); +} Index: llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp +++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp @@ -9,6 +9,7 @@ #include "llvm/DebugInfo/PDB/DIA/DIASession.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumDebugStreams.h" +#include "llvm/DebugInfo/PDB/DIA/DIAEnumInjectedSources.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumLineNumbers.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumSourceFiles.h" #include "llvm/DebugInfo/PDB/DIA/DIAEnumTables.h" @@ -310,3 +311,31 @@ return llvm::make_unique(DiaEnumerator); } + +static CComPtr +getEnumInjectedSources(IDiaSession &Session) { + CComPtr EIS; + CComPtr ET; + CComPtr Table; + ULONG Count = 0; + + if (Session.getEnumTables(&ET) != S_OK) + return nullptr; + + while (ET->Next(1, &Table, &Count) == S_OK && Count == 1) { + // There is only one table that matches the given iid + if (S_OK == + Table->QueryInterface(__uuidof(IDiaEnumInjectedSources), (void **)&EIS)) + break; + Table.Release(); + } + return EIS; +} +std::unique_ptr +DIASession::getInjectedSources() const { + CComPtr Files = getEnumInjectedSources(*Session); + if (!Files) + return nullptr; + + return llvm::make_unique(*this, Files); +} Index: llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeSession.cpp @@ -249,3 +249,8 @@ std::unique_ptr NativeSession::getEnumTables() const { return nullptr; } + +std::unique_ptr +NativeSession::getInjectedSources() const { + return nullptr; +} Index: llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp +++ llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp @@ -254,6 +254,18 @@ return OS; } +raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, + const PDB_SourceCompression &Compression) { + switch (Compression) { + CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, None, OS) + CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, Huffman, OS) + CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, LZ, OS) + CASE_OUTPUT_ENUM_CLASS_STR(PDB_SourceCompression, RunLengthEncoded, "RLE", + OS) + } + return OS; +} + raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const Variant &Value) { switch (Value.Type) { case PDB_VariantType::Bool: Index: llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp +++ llvm/trunk/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/PDB/IPDBDataStream.h" +#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h" #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" @@ -29,3 +30,5 @@ IPDBLineNumber::~IPDBLineNumber() = default; IPDBTable::~IPDBTable() = default; + +IPDBInjectedSource::~IPDBInjectedSource() = default; Index: llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test =================================================================== --- llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test +++ llvm/trunk/test/tools/llvm-pdbdump/injected-sources.test @@ -0,0 +1,16 @@ +; RUN: llvm-pdbutil pretty -injected-sources -injected-source-content \ +; RUN: %p/Inputs/InjectedSource.pdb | FileCheck %s +; RUN: llvm-pdbutil pretty -injected-sources -injected-source-content \ +; RUN: %p/Inputs/ClassLayoutTest.pdb | FileCheck --check-prefix=NEGATIVE %s + +; CHECK: ---INJECTED SOURCES--- +; CHECK-NEXT: d:\sandbox\natvistest\natvistest\test.natvis (220 bytes): obj=, vname=d:\sandbox\natvistest\natvistest\test.natvis, crc=2374979362, compression=None +; CHECK-NEXT: +; CHECK-NEXT: +; CHECK-NEXT: +; CHECK-NEXT: This is a test +; CHECK-NEXT: +; CHECK-NEXT: + +; NEGATIVE: ---INJECTED SOURCES--- +; NEGATIVE-NEXT: There are no injected sources. Index: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp +++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp @@ -45,6 +45,7 @@ #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" +#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h" #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h" @@ -147,6 +148,14 @@ cl::desc(""), cl::OneOrMore, cl::sub(PrettySubcommand)); +cl::opt InjectedSources("injected-sources", + cl::desc("Display injected sources"), + cl::cat(OtherOptions), cl::sub(PrettySubcommand)); +cl::opt ShowInjectedSourceContent( + "injected-source-content", + cl::desc("When displaying an injected source, display the file content"), + cl::cat(OtherOptions), cl::sub(PrettySubcommand)); + cl::opt Compilands("compilands", cl::desc("Display compilands"), cl::cat(TypeCategory), cl::sub(PrettySubcommand)); cl::opt Symbols("module-syms", @@ -840,6 +849,62 @@ return getTypeLength(*F1) > getTypeLength(*F2); } +static std::string stringOr(std::string Str, std::string IfEmpty) { + return (Str.empty()) ? IfEmpty : Str; +} + +static void dumpInjectedSources(LinePrinter &Printer, IPDBSession &Session) { + auto Sources = Session.getInjectedSources(); + if (0 == Sources->getChildCount()) { + Printer.printLine("There are no injected sources."); + return; + } + + while (auto IS = Sources->getNext()) { + Printer.NewLine(); + std::string File = stringOr(IS->getFileName(), ""); + uint64_t Size = IS->getCodeByteSize(); + std::string Obj = stringOr(IS->getObjectFileName(), ""); + std::string VFName = stringOr(IS->getVirtualFileName(), ""); + uint32_t CRC = IS->getCrc32(); + + std::string CompressionStr; + llvm::raw_string_ostream Stream(CompressionStr); + Stream << IS->getCompression(); + WithColor(Printer, PDB_ColorItem::Path).get() << File; + Printer << " ("; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Size; + Printer << " bytes): "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "obj"; + Printer << "="; + WithColor(Printer, PDB_ColorItem::Path).get() << Obj; + Printer << ", "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "vname"; + Printer << "="; + WithColor(Printer, PDB_ColorItem::Path).get() << VFName; + Printer << ", "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "crc"; + Printer << "="; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << CRC; + Printer << ", "; + WithColor(Printer, PDB_ColorItem::Keyword).get() << "compression"; + Printer << "="; + WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Stream.str(); + + if (!opts::pretty::ShowInjectedSourceContent) + continue; + + // Set the indent level to 0 when printing file content. + int Indent = Printer.getIndentLevel(); + Printer.Unindent(Indent); + + Printer.printLine(IS->getCode()); + + // Re-indent back to the original level. + Printer.Indent(Indent); + } +} + static void dumpPretty(StringRef Path) { std::unique_ptr Session; @@ -989,6 +1054,19 @@ if (opts::pretty::Lines) { Printer.NewLine(); } + if (opts::pretty::InjectedSources) { + Printer.NewLine(); + WithColor(Printer, PDB_ColorItem::SectionHeader).get() + << "---INJECTED SOURCES---"; + AutoIndent Indent1(Printer); + + if (ReaderType == PDB_ReaderType::Native) + Printer.printLine( + "Injected sources are not supported with the native reader."); + else + dumpInjectedSources(Printer, *Session); + } + outs().flush(); }