//===- LinePrinter.h ------------------------------------------ *- C++ --*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H #define LLVM_TOOLS_LLVMPDBDUMP_LINEPRINTER_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Regex.h" #include "llvm/Support/raw_ostream.h" #include namespace llvm { class BinaryStreamReader; namespace msf { class MSFStreamLayout; } // namespace msf namespace pdb { class ClassLayout; class PDBFile; class LinePrinter { friend class WithColor; public: LinePrinter(int Indent, bool UseColor, raw_ostream &Stream); void Indent(uint32_t Amount = 0); void Unindent(uint32_t Amount = 0); void NewLine(); void printLine(const Twine &T); void print(const Twine &T); template void formatLine(const char *Fmt, Ts &&... Items) { printLine(formatv(Fmt, std::forward(Items)...)); } template void format(const char *Fmt, Ts &&... Items) { print(formatv(Fmt, std::forward(Items)...)); } void formatBinary(StringRef Label, ArrayRef Data, uint32_t StartOffset); void formatBinary(StringRef Label, ArrayRef Data, uint64_t BaseAddr, uint32_t StartOffset); void formatMsfStreamData(StringRef Label, PDBFile &File, uint32_t StreamIdx, StringRef StreamPurpose, uint32_t Offset, uint32_t Size); void formatMsfStreamData(StringRef Label, PDBFile &File, const msf::MSFStreamLayout &Stream, BinarySubstreamRef Substream); void formatMsfStreamBlocks(PDBFile &File, const msf::MSFStreamLayout &Stream); bool hasColor() const { return UseColor; } raw_ostream &getStream() { return OS; } int getIndentLevel() const { return CurrentIndent; } bool IsClassExcluded(const ClassLayout &Class); bool IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size); bool IsSymbolExcluded(llvm::StringRef SymbolName); bool IsCompilandExcluded(llvm::StringRef CompilandName); private: template void SetFilters(std::list &List, Iter Begin, Iter End) { List.clear(); for (; Begin != End; ++Begin) List.emplace_back(StringRef(*Begin)); } raw_ostream &OS; int IndentSpaces; int CurrentIndent; bool UseColor; std::list ExcludeCompilandFilters; std::list ExcludeTypeFilters; std::list ExcludeSymbolFilters; std::list IncludeCompilandFilters; std::list IncludeTypeFilters; std::list IncludeSymbolFilters; }; struct PrintScope { explicit PrintScope(LinePrinter &P, uint32_t IndentLevel) : P(P), IndentLevel(IndentLevel) {} explicit PrintScope(const PrintScope &Other, uint32_t LabelWidth) : P(Other.P), IndentLevel(Other.IndentLevel), LabelWidth(LabelWidth) {} LinePrinter &P; uint32_t IndentLevel; uint32_t LabelWidth = 0; }; inline Optional withLabelWidth(const Optional &Scope, uint32_t W) { if (!Scope) return None; return PrintScope{*Scope, W}; } struct AutoIndent { explicit AutoIndent(LinePrinter &L, uint32_t Amount = 0) : L(&L), Amount(Amount) { L.Indent(Amount); } explicit AutoIndent(const Optional &Scope) { if (Scope.hasValue()) { L = &Scope->P; Amount = Scope->IndentLevel; } } ~AutoIndent() { if (L) L->Unindent(Amount); } LinePrinter *L = nullptr; uint32_t Amount = 0; }; template inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) { Printer.getStream() << Item; return Printer.getStream(); } enum class PDB_ColorItem { None, Address, Type, Comment, Padding, Keyword, Offset, Identifier, Path, SectionHeader, LiteralValue, Register, }; class WithColor { public: WithColor(LinePrinter &P, PDB_ColorItem C); ~WithColor(); raw_ostream &get() { return OS; } private: void applyColor(PDB_ColorItem C); raw_ostream &OS; bool UseColor; }; } } #endif