clang: lib/Analysis/FlowSensitive/Logger.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
12#include "llvm/Support/WithColor.h"
13
15
17 struct NullLogger final : Logger {};
18 static auto *Instance = new NullLogger();
19 return *Instance;
20}
21
22namespace {
23struct TextualLogger final : Logger {
24 llvm::raw_ostream &OS;
30 llvm::DenseMap<const CFGBlock *, unsigned> VisitCount;
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, 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);
47 CurrentCFG->print(OS, Analysis.getASTContext().getLangOpts(), ShowColors);
49 }
50 virtual void endAnalysis() override {
51 llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, 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 {
62 {
63 llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, true);
64 OS << "=== Entering block B" << Block.getBlockID();
66 OS << " (post-visit)";
67 else
68 OS << " (iteration " << Count << ")";
69 OS << " ===\n";
70 }
72 ShowColors);
76 }
77 virtual void enterElement(const CFGElement &Element) override {
80 {
81 llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,
82 true);
83 OS << "Processing element B" << CurrentBlock->getBlockID() << "."
85 Element.dumpToStream(OS);
86 }
87 }
88 void recordState(TypeErasedDataflowAnalysisState &State) override {
89 {
90 llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,
91 true);
92 OS << "Computed state for B" << CurrentBlock->getBlockID() << "."
94 }
95
96
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}
106
108 return std::make_unique(OS);
109}
110
111}
llvm::DenseMap< const CFGBlock *, unsigned > VisitCount
const CFGElement * CurrentElement
const CFGBlock * CurrentBlock
TypeErasedDataflowAnalysis * CurrentAnalysis
unsigned CurrentElementIndex
TypeErasedDataflowAnalysis & Analysis
The analysis to be run.
A logger is notified as the analysis progresses.
static std::unique_ptr< Logger > textual(llvm::raw_ostream &)
A logger that simply writes messages to the specified ostream in real time.
static Logger & null()
Returns a dummy logger that does nothing.
Dataflow Directional Tag Classes.
Diagnostic wrappers for TextAPI types for error reporting.