aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2023-02-24 14:50:00 +0100
committerSam McCall <sam.mccall@gmail.com>2023-03-23 11:36:21 +0100
commit48f97e5751372b4a64144605c5e9f7e5e13e382a (patch)
tree6e4c5225484d676eac5eb51259cb3e89ff75b7e8 /clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
parent8d16c6809a080947057ae21b9f6165105b4b2ad8 (diff)
downloadllvm-48f97e5751372b4a64144605c5e9f7e5e13e382a.zip
llvm-48f97e5751372b4a64144605c5e9f7e5e13e382a.tar.gz
llvm-48f97e5751372b4a64144605c5e9f7e5e13e382a.tar.bz2
[FlowSensitive] Log analysis progress for debugging purposes
The goal is to be able to understand how the analysis executes, and what its incremental and final findings are, by enabling logging and reading the logs. This should include both framework and analysis-specific information. Ad-hoc printf-debugging doesn't seem sufficient for my understanding, at least. Being able to check in logging, turn it on in a production binary, and quickly find particular analysis steps within complex functions seem important. This can be enabled programmatically through DataflowAnalysisOptions, or via the flag -dataflow-log. (Works in unittests, clang-tidy, standalone tools...) Important missing pieces here: - a logger implementation that produces an interactive report (HTML file) which can be navigated via timeline/code/CFG. (I think the Logger interface is sufficient for this, but need to prototype). - display of the application-specific lattice - more useful display for the built-in environment (e.g. meaningful & consistent names for values, hiding redundant variables in the flow condition, hiding unreachable expressions) Differential Revision: https://reviews.llvm.org/D144730
Diffstat (limited to 'clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp')
-rw-r--r--clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
index a1b8139..57169ba 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -15,13 +15,20 @@
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Analysis/FlowSensitive/DebugSupport.h"
+#include "clang/Analysis/FlowSensitive/Logger.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/SetOperations.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include <cassert>
#include <memory>
#include <utility>
+static llvm::cl::opt<std::string>
+ DataflowLog("dataflow-log", llvm::cl::Hidden, llvm::cl::ValueOptional,
+ llvm::cl::desc("Emit log of dataflow analysis. With no arg, "
+ "writes textual log to stderr."));
+
namespace clang {
namespace dataflow {
@@ -375,6 +382,27 @@ DataflowAnalysisContext::getControlFlowContext(const FunctionDecl *F) {
return nullptr;
}
+DataflowAnalysisContext::DataflowAnalysisContext(std::unique_ptr<Solver> S,
+ Options Opts)
+ : S(std::move(S)), TrueVal(createAtomicBoolValue()),
+ FalseVal(createAtomicBoolValue()), Opts(Opts) {
+ assert(this->S != nullptr);
+ // If the -dataflow-log command-line flag was set, synthesize a logger.
+ // This is ugly but provides a uniform method for ad-hoc debugging dataflow-
+ // based tools.
+ if (Opts.Log == nullptr) {
+ if (DataflowLog.getNumOccurrences() > 0) {
+ LogOwner = Logger::textual(llvm::errs());
+ this->Opts.Log = LogOwner.get();
+ // FIXME: if the flag is given a value, write an HTML log to a file.
+ } else {
+ this->Opts.Log = &Logger::null();
+ }
+ }
+}
+
+DataflowAnalysisContext::~DataflowAnalysisContext() = default;
+
} // namespace dataflow
} // namespace clang