//===-- HTMLLogger.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the HTML logger. Given a directory dir/, we write // dir/0.html for the first analysis, etc. // These files contain a visualization that allows inspecting the CFG and the // state of the analysis at each point. // Static assets (HTMLLogger.js, HTMLLogger.css) and SVG graphs etc are embedded // so each output file is self-contained. // // VIEWS // // The timeline and function view are always shown. These allow selecting basic // blocks, statements within them, and processing iterations (BBs are visited // multiple times when e.g. loops are involved). // These are written directly into the HTML body. // // There are also listings of particular basic blocks, and dumps of the state // at particular analysis points (i.e. BB2 iteration 3 statement 2). // These are only shown when the relevant BB/analysis point is *selected*. // // DATA AND TEMPLATES // // The HTML proper is mostly static. // The analysis data is in a JSON object HTMLLoggerData which is embedded as // a <script> in the <head>. // This gets rendered into DOM by a simple template processor which substitutes // the data into <template> tags embedded in the HTML. (see inflate() in JS). // // SELECTION // // This is the only real interactive mechanism. // // At any given time, there are several named selections, e.g.: // bb: B2 (basic block 0 is selected) // elt: B2.4 (statement 4 is selected) // iter: B2:1 (iteration 1 of the basic block is selected) // hover: B3 (hovering over basic block 3) // // The selection is updated by mouse events: hover by moving the mouse and // others by clicking. Elements that are click targets generally have attributes // (id or data-foo) that define what they should select. // See watchSelection() in JS for the exact logic. // // When the "bb" selection is set to "B2": // - sections <section data-selection="bb"> get shown // - templates under such sections get re-rendered // - elements with class/id "B2" get class "bb-select" // //===----------------------------------------------------------------------===// #include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DebugSupport.h" #include "clang/Analysis/FlowSensitive/Logger.h" #include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" #include "clang/Analysis/FlowSensitive/Value.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/JSON.h" #include "llvm/Support/Program.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" // Defines assets: HTMLLogger_{html_js,css} #include "HTMLLogger.inc" namespace clang::dataflow { namespace { // Render a graphviz graph specification to SVG using the `dot` tool. llvm::Expected<std::string> renderSVG(llvm::StringRef DotGraph); StreamFactory; // Recursively dumps Values/StorageLocations as JSON class ModelDumper { … }; class HTMLLogger : public Logger { … }; // Nothing interesting here, just subprocess/temp-file plumbing. llvm::Expected<std::string> renderSVG(llvm::StringRef DotGraph) { … } } // namespace std::unique_ptr<Logger> Logger::html(std::function<std::unique_ptr<llvm::raw_ostream>()> Streams) { … } } // namespace clang::dataflow