clang  19.0.0git
Logger.cpp
Go to the documentation of this file.
1 //===-- Logger.cpp --------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
12 #include "llvm/Support/WithColor.h"
13 
14 namespace clang::dataflow {
15 
17  struct NullLogger final : Logger {};
18  static auto *Instance = new NullLogger();
19  return *Instance;
20 }
21 
22 namespace {
23 struct TextualLogger final : Logger {
24  llvm::raw_ostream &OS;
25  const CFG *CurrentCFG;
26  const CFGBlock *CurrentBlock;
27  const CFGElement *CurrentElement;
29  bool ShowColors;
30  llvm::DenseMap<const CFGBlock *, unsigned> VisitCount;
31  TypeErasedDataflowAnalysis *CurrentAnalysis;
32 
33  TextualLogger(llvm::raw_ostream &OS)
34  : OS(OS), ShowColors(llvm::WithColor::defaultAutoDetectFunction()(OS)) {}
35 
36  virtual void beginAnalysis(const AdornedCFG &ACFG,
37  TypeErasedDataflowAnalysis &Analysis) override {
38  {
39  llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);
40  OS << "=== Beginning data flow analysis ===\n";
41  }
42  auto &D = ACFG.getDecl();
43  D.print(OS);
44  OS << "\n";
45  D.dump(OS);
46  CurrentCFG = &ACFG.getCFG();
47  CurrentCFG->print(OS, Analysis.getASTContext().getLangOpts(), ShowColors);
49  }
50  virtual void endAnalysis() override {
51  llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);
52  unsigned Blocks = 0, Steps = 0;
53  for (const auto &E : VisitCount) {
54  ++Blocks;
55  Steps += E.second;
56  }
57  llvm::errs() << "=== Finished analysis: " << Blocks << " blocks in "
58  << Steps << " total steps ===\n";
59  }
60  virtual void enterBlock(const CFGBlock &Block, bool PostVisit) override {
61  unsigned Count = ++VisitCount[&Block];
62  {
63  llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);
64  OS << "=== Entering block B" << Block.getBlockID();
65  if (PostVisit)
66  OS << " (post-visit)";
67  else
68  OS << " (iteration " << Count << ")";
69  OS << " ===\n";
70  }
71  Block.print(OS, CurrentCFG, CurrentAnalysis->getASTContext().getLangOpts(),
72  ShowColors);
74  CurrentElement = nullptr;
76  }
77  virtual void enterElement(const CFGElement &Element) override {
79  CurrentElement = &Element;
80  {
81  llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,
82  /*Bold=*/true);
83  OS << "Processing element B" << CurrentBlock->getBlockID() << "."
84  << CurrentElementIndex << ": ";
85  Element.dumpToStream(OS);
86  }
87  }
88  void recordState(TypeErasedDataflowAnalysisState &State) override {
89  {
90  llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,
91  /*Bold=*/true);
92  OS << "Computed state for B" << CurrentBlock->getBlockID() << "."
93  << CurrentElementIndex << ":\n";
94  }
95  // FIXME: currently the environment dump is verbose and unenlightening.
96  // FIXME: dump the user-defined lattice, too.
97  State.Env.dump(OS);
98  OS << "\n";
99  }
100  void blockConverged() override {
101  OS << "B" << CurrentBlock->getBlockID() << " has converged!\n";
102  }
103  virtual void logText(llvm::StringRef S) override { OS << S << "\n"; }
104 };
105 } // namespace
106 
107 std::unique_ptr<Logger> Logger::textual(llvm::raw_ostream &OS) {
108  return std::make_unique<TextualLogger>(OS);
109 }
110 
111 } // namespace clang::dataflow
const CFGBlock * Block
Definition: HTMLLogger.cpp:153
bool PostVisit
Definition: HTMLLogger.cpp:155
bool ShowColors
Definition: Logger.cpp:29
llvm::DenseMap< const CFGBlock *, unsigned > VisitCount
Definition: Logger.cpp:30
const CFGElement * CurrentElement
Definition: Logger.cpp:27
const CFGBlock * CurrentBlock
Definition: Logger.cpp:26
const CFG * CurrentCFG
Definition: Logger.cpp:25
TypeErasedDataflowAnalysis * CurrentAnalysis
Definition: Logger.cpp:31
unsigned CurrentElementIndex
Definition: Logger.cpp:28
TypeErasedDataflowAnalysis & Analysis
The analysis to be run.
const AdornedCFG & ACFG
Contains the CFG being analyzed.
LineState State
A logger is notified as the analysis progresses.
Definition: Logger.h:27
static std::unique_ptr< Logger > textual(llvm::raw_ostream &)
A logger that simply writes messages to the specified ostream in real time.
Definition: Logger.cpp:107
static Logger & null()
Returns a dummy logger that does nothing.
Definition: Logger.cpp:16
Dataflow Directional Tag Classes.
Definition: AdornedCFG.h:28
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30