Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Analysis/FlowSensitive/Logger.cpp
Line
Count
Source (jump to first uncovered line)
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/ControlFlowContext.h"
11
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
12
#include "llvm/Support/WithColor.h"
13
14
namespace clang::dataflow {
15
16
670
Logger &Logger::null() {
17
670
  struct NullLogger final : Logger {};
18
670
  static auto *Instance = new NullLogger();
19
670
  return *Instance;
20
670
}
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
0
      : OS(OS), ShowColors(llvm::WithColor::defaultAutoDetectFunction()(OS)) {}
35
36
  virtual void beginAnalysis(const ControlFlowContext &CFG,
37
0
                             TypeErasedDataflowAnalysis &Analysis) override {
38
0
    {
39
0
      llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);
40
0
      OS << "=== Beginning data flow analysis ===\n";
41
0
    }
42
0
    auto &D = CFG.getDecl();
43
0
    D.print(OS);
44
0
    OS << "\n";
45
0
    D.dump(OS);
46
0
    CurrentCFG = &CFG.getCFG();
47
0
    CurrentCFG->print(OS, Analysis.getASTContext().getLangOpts(), ShowColors);
48
0
    CurrentAnalysis = &Analysis;
49
0
  }
50
0
  virtual void endAnalysis() override {
51
0
    llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);
52
0
    unsigned Blocks = 0, Steps = 0;
53
0
    for (const auto &E : VisitCount) {
54
0
      ++Blocks;
55
0
      Steps += E.second;
56
0
    }
57
0
    llvm::errs() << "=== Finished analysis: " << Blocks << " blocks in "
58
0
                 << Steps << " total steps ===\n";
59
0
  }
60
0
  virtual void enterBlock(const CFGBlock &Block, bool PostVisit) override {
61
0
    unsigned Count = ++VisitCount[&Block];
62
0
    {
63
0
      llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);
64
0
      OS << "=== Entering block B" << Block.getBlockID();
65
0
      if (PostVisit)
66
0
        OS << " (post-visit)";
67
0
      else
68
0
        OS << " (iteration " << Count << ")";
69
0
      OS << " ===\n";
70
0
    }
71
0
    Block.print(OS, CurrentCFG, CurrentAnalysis->getASTContext().getLangOpts(),
72
0
                ShowColors);
73
0
    CurrentBlock = &Block;
74
0
    CurrentElement = nullptr;
75
0
    CurrentElementIndex = 0;
76
0
  }
77
0
  virtual void enterElement(const CFGElement &Element) override {
78
0
    ++CurrentElementIndex;
79
0
    CurrentElement = &Element;
80
0
    {
81
0
      llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,
82
0
                                /*Bold=*/true);
83
0
      OS << "Processing element B" << CurrentBlock->getBlockID() << "."
84
0
         << CurrentElementIndex << ": ";
85
0
      Element.dumpToStream(OS);
86
0
    }
87
0
  }
88
0
  void recordState(TypeErasedDataflowAnalysisState &State) override {
89
0
    {
90
0
      llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,
91
0
                                /*Bold=*/true);
92
0
      OS << "Computed state for B" << CurrentBlock->getBlockID() << "."
93
0
         << CurrentElementIndex << ":\n";
94
0
    }
95
    // FIXME: currently the environment dump is verbose and unenlightening.
96
    // FIXME: dump the user-defined lattice, too.
97
0
    State.Env.dump(OS);
98
0
    OS << "\n";
99
0
  }
100
0
  void blockConverged() override {
101
0
    OS << "B" << CurrentBlock->getBlockID() << " has converged!\n";
102
0
  }
103
0
  virtual void logText(llvm::StringRef S) override { OS << S << "\n"; }
104
};
105
} // namespace
106
107
0
std::unique_ptr<Logger> Logger::textual(llvm::raw_ostream &OS) {
108
0
  return std::make_unique<TextualLogger>(OS);
109
0
}
110
111
} // namespace clang::dataflow