1//===-- Logger.h ------------------------------------------------*- C++ -*-===//
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#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_LOGGER_H
10#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_LOGGER_H
11
12#include "clang/Analysis/CFG.h"
13#include "llvm/Support/raw_ostream.h"
14#include <memory>
15
16namespace clang::dataflow {
17// Forward declarations so we can use Logger anywhere in the framework.
18class AdornedCFG;
19class TypeErasedDataflowAnalysis;
20struct TypeErasedDataflowAnalysisState;
21
22/// A logger is notified as the analysis progresses.
23/// It can produce a report of the analysis's findings and how it came to them.
24///
25/// The framework reports key structural events (e.g. traversal of blocks).
26/// The specific analysis can add extra details to be presented in context.
27class Logger {
28public:
29 /// Returns a dummy logger that does nothing.
30 static Logger &null();
31 /// A logger that simply writes messages to the specified ostream in real
32 /// time.
33 static std::unique_ptr<Logger> textual(llvm::raw_ostream &);
34 /// A logger that builds an HTML UI to inspect the analysis results.
35 /// Each function's analysis is written to a stream obtained from the factory.
36 static std::unique_ptr<Logger>
37 html(std::function<std::unique_ptr<llvm::raw_ostream>()>);
38
39 virtual ~Logger() = default;
40
41 /// Called by the framework as we start analyzing a new function or statement.
42 /// Forms a pair with endAnalysis().
43 virtual void beginAnalysis(const AdornedCFG &, TypeErasedDataflowAnalysis &) {
44 }
45 virtual void endAnalysis() {}
46
47 // At any time during the analysis, we're computing the state for some target
48 // program point.
49
50 /// Called when we start (re-)processing a block in the CFG.
51 /// The target program point is the entry to the specified block.
52 /// Calls to log() describe transferBranch(), join() etc.
53 /// `PostVisit` specifies whether we're processing the block for the
54 /// post-visit callback.
55 virtual void enterBlock(const CFGBlock &, bool PostVisit) {}
56 /// Called when we start processing an element in the current CFG block.
57 /// The target program point is after the specified element.
58 /// Calls to log() describe the transfer() function.
59 virtual void enterElement(const CFGElement &) {}
60
61 /// Records the analysis state computed for the current program point.
62 virtual void recordState(TypeErasedDataflowAnalysisState &) {}
63 /// Records that the analysis state for the current block is now final.
64 virtual void blockConverged() {}
65
66 /// Called by the framework or user code to report some event.
67 /// The event is associated with the current context (program point).
68 /// The Emit function produces the log message. It may or may not be called,
69 /// depending on if the logger is interested; it should have no side effects.
70 void log(llvm::function_ref<void(llvm::raw_ostream &)> Emit) {
71 if (!ShouldLogText)
72 return;
73 std::string S;
74 llvm::raw_string_ostream OS(S);
75 Emit(OS);
76 logText(S);
77 }
78
79protected:
80 /// ShouldLogText should be false for trivial loggers that ignore logText().
81 /// This allows log() to skip evaluating its Emit function.
82 Logger(bool ShouldLogText = true) : ShouldLogText(ShouldLogText) {}
83
84private:
85 bool ShouldLogText;
86 virtual void logText(llvm::StringRef) {}
87};
88
89} // namespace clang::dataflow
90
91#endif
92

source code of clang/include/clang/Analysis/FlowSensitive/Logger.h