Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Logger.cpp
35266 views
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
9
#include "clang/Analysis/FlowSensitive/Logger.h"
10
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
11
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
12
#include "llvm/Support/WithColor.h"
13
14
namespace clang::dataflow {
15
16
Logger &Logger::null() {
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;
28
unsigned CurrentElementIndex;
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);
48
CurrentAnalysis = &Analysis;
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);
73
CurrentBlock = &Block;
74
CurrentElement = nullptr;
75
CurrentElementIndex = 0;
76
}
77
virtual void enterElement(const CFGElement &Element) override {
78
++CurrentElementIndex;
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
112
113