Path: blob/main/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/Logger.cpp
35266 views
//===-- Logger.cpp --------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "clang/Analysis/FlowSensitive/Logger.h"9#include "clang/Analysis/FlowSensitive/AdornedCFG.h"10#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"11#include "llvm/Support/WithColor.h"1213namespace clang::dataflow {1415Logger &Logger::null() {16struct NullLogger final : Logger {};17static auto *Instance = new NullLogger();18return *Instance;19}2021namespace {22struct TextualLogger final : Logger {23llvm::raw_ostream &OS;24const CFG *CurrentCFG;25const CFGBlock *CurrentBlock;26const CFGElement *CurrentElement;27unsigned CurrentElementIndex;28bool ShowColors;29llvm::DenseMap<const CFGBlock *, unsigned> VisitCount;30TypeErasedDataflowAnalysis *CurrentAnalysis;3132TextualLogger(llvm::raw_ostream &OS)33: OS(OS), ShowColors(llvm::WithColor::defaultAutoDetectFunction()(OS)) {}3435virtual void beginAnalysis(const AdornedCFG &ACFG,36TypeErasedDataflowAnalysis &Analysis) override {37{38llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);39OS << "=== Beginning data flow analysis ===\n";40}41auto &D = ACFG.getDecl();42D.print(OS);43OS << "\n";44D.dump(OS);45CurrentCFG = &ACFG.getCFG();46CurrentCFG->print(OS, Analysis.getASTContext().getLangOpts(), ShowColors);47CurrentAnalysis = &Analysis;48}49virtual void endAnalysis() override {50llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);51unsigned Blocks = 0, Steps = 0;52for (const auto &E : VisitCount) {53++Blocks;54Steps += E.second;55}56llvm::errs() << "=== Finished analysis: " << Blocks << " blocks in "57<< Steps << " total steps ===\n";58}59virtual void enterBlock(const CFGBlock &Block, bool PostVisit) override {60unsigned Count = ++VisitCount[&Block];61{62llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);63OS << "=== Entering block B" << Block.getBlockID();64if (PostVisit)65OS << " (post-visit)";66else67OS << " (iteration " << Count << ")";68OS << " ===\n";69}70Block.print(OS, CurrentCFG, CurrentAnalysis->getASTContext().getLangOpts(),71ShowColors);72CurrentBlock = &Block;73CurrentElement = nullptr;74CurrentElementIndex = 0;75}76virtual void enterElement(const CFGElement &Element) override {77++CurrentElementIndex;78CurrentElement = ∈79{80llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,81/*Bold=*/true);82OS << "Processing element B" << CurrentBlock->getBlockID() << "."83<< CurrentElementIndex << ": ";84Element.dumpToStream(OS);85}86}87void recordState(TypeErasedDataflowAnalysisState &State) override {88{89llvm::WithColor Subheader(OS, llvm::raw_ostream::Colors::CYAN,90/*Bold=*/true);91OS << "Computed state for B" << CurrentBlock->getBlockID() << "."92<< CurrentElementIndex << ":\n";93}94// FIXME: currently the environment dump is verbose and unenlightening.95// FIXME: dump the user-defined lattice, too.96State.Env.dump(OS);97OS << "\n";98}99void blockConverged() override {100OS << "B" << CurrentBlock->getBlockID() << " has converged!\n";101}102virtual void logText(llvm::StringRef S) override { OS << S << "\n"; }103};104} // namespace105106std::unique_ptr<Logger> Logger::textual(llvm::raw_ostream &OS) {107return std::make_unique<TextualLogger>(OS);108}109110} // namespace clang::dataflow111112113