181ad6265SDimitry Andric //===- LinePrinter.h ------------------------------------------ *- C++ --*-===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric
981ad6265SDimitry Andric #ifndef LLVM_DEBUGINFO_PDB_NATIVE_LINEPRINTER_H
1081ad6265SDimitry Andric #define LLVM_DEBUGINFO_PDB_NATIVE_LINEPRINTER_H
1181ad6265SDimitry Andric
1281ad6265SDimitry Andric #include "llvm/ADT/ArrayRef.h"
1381ad6265SDimitry Andric #include "llvm/ADT/StringRef.h"
1481ad6265SDimitry Andric #include "llvm/ADT/Twine.h"
1581ad6265SDimitry Andric #include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
1681ad6265SDimitry Andric #include "llvm/Support/BinaryStreamRef.h"
1781ad6265SDimitry Andric #include "llvm/Support/FormatVariadic.h"
1881ad6265SDimitry Andric #include "llvm/Support/Regex.h"
1981ad6265SDimitry Andric #include "llvm/Support/raw_ostream.h"
2081ad6265SDimitry Andric
2181ad6265SDimitry Andric #include <list>
2281ad6265SDimitry Andric
2381ad6265SDimitry Andric // Container for filter options to control which elements will be printed.
2481ad6265SDimitry Andric struct FilterOptions {
2581ad6265SDimitry Andric std::list<std::string> ExcludeTypes;
2681ad6265SDimitry Andric std::list<std::string> ExcludeSymbols;
2781ad6265SDimitry Andric std::list<std::string> ExcludeCompilands;
2881ad6265SDimitry Andric std::list<std::string> IncludeTypes;
2981ad6265SDimitry Andric std::list<std::string> IncludeSymbols;
3081ad6265SDimitry Andric std::list<std::string> IncludeCompilands;
3181ad6265SDimitry Andric uint32_t PaddingThreshold;
3281ad6265SDimitry Andric uint32_t SizeThreshold;
33*bdd1243dSDimitry Andric std::optional<uint32_t> DumpModi;
34*bdd1243dSDimitry Andric std::optional<uint32_t> ParentRecurseDepth;
35*bdd1243dSDimitry Andric std::optional<uint32_t> ChildrenRecurseDepth;
36*bdd1243dSDimitry Andric std::optional<uint32_t> SymbolOffset;
3781ad6265SDimitry Andric bool JustMyCode;
3881ad6265SDimitry Andric };
3981ad6265SDimitry Andric
4081ad6265SDimitry Andric namespace llvm {
4181ad6265SDimitry Andric namespace msf {
4281ad6265SDimitry Andric class MSFStreamLayout;
4381ad6265SDimitry Andric } // namespace msf
4481ad6265SDimitry Andric namespace pdb {
4581ad6265SDimitry Andric
4681ad6265SDimitry Andric class ClassLayout;
4781ad6265SDimitry Andric class PDBFile;
4881ad6265SDimitry Andric class SymbolGroup;
4981ad6265SDimitry Andric
5081ad6265SDimitry Andric class LinePrinter {
5181ad6265SDimitry Andric friend class WithColor;
5281ad6265SDimitry Andric
5381ad6265SDimitry Andric public:
5481ad6265SDimitry Andric LinePrinter(int Indent, bool UseColor, raw_ostream &Stream,
5581ad6265SDimitry Andric const FilterOptions &Filters);
5681ad6265SDimitry Andric
5781ad6265SDimitry Andric void Indent(uint32_t Amount = 0);
5881ad6265SDimitry Andric void Unindent(uint32_t Amount = 0);
5981ad6265SDimitry Andric void NewLine();
6081ad6265SDimitry Andric
6181ad6265SDimitry Andric void printLine(const Twine &T);
6281ad6265SDimitry Andric void print(const Twine &T);
formatLine(const char * Fmt,Ts &&...Items)6381ad6265SDimitry Andric template <typename... Ts> void formatLine(const char *Fmt, Ts &&...Items) {
6481ad6265SDimitry Andric printLine(formatv(Fmt, std::forward<Ts>(Items)...));
6581ad6265SDimitry Andric }
format(const char * Fmt,Ts &&...Items)6681ad6265SDimitry Andric template <typename... Ts> void format(const char *Fmt, Ts &&...Items) {
6781ad6265SDimitry Andric print(formatv(Fmt, std::forward<Ts>(Items)...));
6881ad6265SDimitry Andric }
6981ad6265SDimitry Andric
7081ad6265SDimitry Andric void formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
7181ad6265SDimitry Andric uint64_t StartOffset);
7281ad6265SDimitry Andric void formatBinary(StringRef Label, ArrayRef<uint8_t> Data, uint64_t BaseAddr,
7381ad6265SDimitry Andric uint64_t StartOffset);
7481ad6265SDimitry Andric
7581ad6265SDimitry Andric void formatMsfStreamData(StringRef Label, PDBFile &File, uint32_t StreamIdx,
7681ad6265SDimitry Andric StringRef StreamPurpose, uint64_t Offset,
7781ad6265SDimitry Andric uint64_t Size);
7881ad6265SDimitry Andric void formatMsfStreamData(StringRef Label, PDBFile &File,
7981ad6265SDimitry Andric const msf::MSFStreamLayout &Stream,
8081ad6265SDimitry Andric BinarySubstreamRef Substream);
8181ad6265SDimitry Andric void formatMsfStreamBlocks(PDBFile &File, const msf::MSFStreamLayout &Stream);
8281ad6265SDimitry Andric
hasColor()8381ad6265SDimitry Andric bool hasColor() const { return UseColor; }
getStream()8481ad6265SDimitry Andric raw_ostream &getStream() { return OS; }
getIndentLevel()8581ad6265SDimitry Andric int getIndentLevel() const { return CurrentIndent; }
8681ad6265SDimitry Andric
8781ad6265SDimitry Andric bool IsClassExcluded(const ClassLayout &Class);
8881ad6265SDimitry Andric bool IsTypeExcluded(llvm::StringRef TypeName, uint64_t Size);
8981ad6265SDimitry Andric bool IsSymbolExcluded(llvm::StringRef SymbolName);
9081ad6265SDimitry Andric bool IsCompilandExcluded(llvm::StringRef CompilandName);
9181ad6265SDimitry Andric
getFilters()9281ad6265SDimitry Andric const FilterOptions &getFilters() const { return Filters; }
9381ad6265SDimitry Andric
9481ad6265SDimitry Andric private:
9581ad6265SDimitry Andric template <typename Iter>
SetFilters(std::list<Regex> & List,Iter Begin,Iter End)9681ad6265SDimitry Andric void SetFilters(std::list<Regex> &List, Iter Begin, Iter End) {
9781ad6265SDimitry Andric List.clear();
9881ad6265SDimitry Andric for (; Begin != End; ++Begin)
9981ad6265SDimitry Andric List.emplace_back(StringRef(*Begin));
10081ad6265SDimitry Andric }
10181ad6265SDimitry Andric
10281ad6265SDimitry Andric raw_ostream &OS;
10381ad6265SDimitry Andric int IndentSpaces;
10481ad6265SDimitry Andric int CurrentIndent;
10581ad6265SDimitry Andric bool UseColor;
10681ad6265SDimitry Andric const FilterOptions &Filters;
10781ad6265SDimitry Andric
10881ad6265SDimitry Andric std::list<Regex> ExcludeCompilandFilters;
10981ad6265SDimitry Andric std::list<Regex> ExcludeTypeFilters;
11081ad6265SDimitry Andric std::list<Regex> ExcludeSymbolFilters;
11181ad6265SDimitry Andric
11281ad6265SDimitry Andric std::list<Regex> IncludeCompilandFilters;
11381ad6265SDimitry Andric std::list<Regex> IncludeTypeFilters;
11481ad6265SDimitry Andric std::list<Regex> IncludeSymbolFilters;
11581ad6265SDimitry Andric };
11681ad6265SDimitry Andric
11781ad6265SDimitry Andric struct PrintScope {
PrintScopePrintScope11881ad6265SDimitry Andric explicit PrintScope(LinePrinter &P, uint32_t IndentLevel)
11981ad6265SDimitry Andric : P(P), IndentLevel(IndentLevel) {}
PrintScopePrintScope12081ad6265SDimitry Andric explicit PrintScope(const PrintScope &Other, uint32_t LabelWidth)
12181ad6265SDimitry Andric : P(Other.P), IndentLevel(Other.IndentLevel), LabelWidth(LabelWidth) {}
12281ad6265SDimitry Andric
12381ad6265SDimitry Andric LinePrinter &P;
12481ad6265SDimitry Andric uint32_t IndentLevel;
12581ad6265SDimitry Andric uint32_t LabelWidth = 0;
12681ad6265SDimitry Andric };
12781ad6265SDimitry Andric
withLabelWidth(const PrintScope & Scope,uint32_t W)12881ad6265SDimitry Andric inline PrintScope withLabelWidth(const PrintScope &Scope, uint32_t W) {
12981ad6265SDimitry Andric return PrintScope{Scope, W};
13081ad6265SDimitry Andric }
13181ad6265SDimitry Andric
13281ad6265SDimitry Andric struct AutoIndent {
13381ad6265SDimitry Andric explicit AutoIndent(LinePrinter &L, uint32_t Amount = 0)
13481ad6265SDimitry Andric : L(&L), Amount(Amount) {
13581ad6265SDimitry Andric L.Indent(Amount);
13681ad6265SDimitry Andric }
AutoIndentAutoIndent13781ad6265SDimitry Andric explicit AutoIndent(const PrintScope &Scope) {
13881ad6265SDimitry Andric L = &Scope.P;
13981ad6265SDimitry Andric Amount = Scope.IndentLevel;
14081ad6265SDimitry Andric }
~AutoIndentAutoIndent14181ad6265SDimitry Andric ~AutoIndent() {
14281ad6265SDimitry Andric if (L)
14381ad6265SDimitry Andric L->Unindent(Amount);
14481ad6265SDimitry Andric }
14581ad6265SDimitry Andric
14681ad6265SDimitry Andric LinePrinter *L = nullptr;
14781ad6265SDimitry Andric uint32_t Amount = 0;
14881ad6265SDimitry Andric };
14981ad6265SDimitry Andric
15081ad6265SDimitry Andric template <class T>
15181ad6265SDimitry Andric inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) {
15281ad6265SDimitry Andric return Printer.getStream() << Item;
15381ad6265SDimitry Andric }
15481ad6265SDimitry Andric
15581ad6265SDimitry Andric enum class PDB_ColorItem {
15681ad6265SDimitry Andric None,
15781ad6265SDimitry Andric Address,
15881ad6265SDimitry Andric Type,
15981ad6265SDimitry Andric Comment,
16081ad6265SDimitry Andric Padding,
16181ad6265SDimitry Andric Keyword,
16281ad6265SDimitry Andric Offset,
16381ad6265SDimitry Andric Identifier,
16481ad6265SDimitry Andric Path,
16581ad6265SDimitry Andric SectionHeader,
16681ad6265SDimitry Andric LiteralValue,
16781ad6265SDimitry Andric Register,
16881ad6265SDimitry Andric };
16981ad6265SDimitry Andric
17081ad6265SDimitry Andric class WithColor {
17181ad6265SDimitry Andric public:
17281ad6265SDimitry Andric WithColor(LinePrinter &P, PDB_ColorItem C);
17381ad6265SDimitry Andric ~WithColor();
17481ad6265SDimitry Andric
get()17581ad6265SDimitry Andric raw_ostream &get() { return OS; }
17681ad6265SDimitry Andric
17781ad6265SDimitry Andric private:
17881ad6265SDimitry Andric void applyColor(PDB_ColorItem C);
17981ad6265SDimitry Andric raw_ostream &OS;
18081ad6265SDimitry Andric bool UseColor;
18181ad6265SDimitry Andric };
18281ad6265SDimitry Andric } // namespace pdb
18381ad6265SDimitry Andric } // namespace llvm
18481ad6265SDimitry Andric
18581ad6265SDimitry Andric #endif
186