1 //===- DebugSupport.cpp -----------------------------------------*- 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 // This file defines functions which generate more readable forms of data 10 // structures used in the dataflow analyses, for debugging purposes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include <utility> 15 16 #include "clang/Analysis/FlowSensitive/DebugSupport.h" 17 #include "clang/Analysis/FlowSensitive/Solver.h" 18 #include "clang/Analysis/FlowSensitive/Value.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Support/ErrorHandling.h" 21 22 namespace clang { 23 namespace dataflow { 24 25 llvm::StringRef debugString(Value::Kind Kind) { 26 switch (Kind) { 27 case Value::Kind::Integer: 28 return "Integer"; 29 case Value::Kind::Reference: 30 return "Reference"; 31 case Value::Kind::Pointer: 32 return "Pointer"; 33 case Value::Kind::Struct: 34 return "Struct"; 35 case Value::Kind::AtomicBool: 36 return "AtomicBool"; 37 case Value::Kind::TopBool: 38 return "TopBool"; 39 case Value::Kind::Conjunction: 40 return "Conjunction"; 41 case Value::Kind::Disjunction: 42 return "Disjunction"; 43 case Value::Kind::Negation: 44 return "Negation"; 45 case Value::Kind::Implication: 46 return "Implication"; 47 case Value::Kind::Biconditional: 48 return "Biconditional"; 49 } 50 llvm_unreachable("Unhandled value kind"); 51 } 52 53 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 54 Solver::Result::Assignment Assignment) { 55 switch (Assignment) { 56 case Solver::Result::Assignment::AssignedFalse: 57 return OS << "False"; 58 case Solver::Result::Assignment::AssignedTrue: 59 return OS << "True"; 60 } 61 llvm_unreachable("Booleans can only be assigned true/false"); 62 } 63 64 llvm::StringRef debugString(Solver::Result::Status Status) { 65 switch (Status) { 66 case Solver::Result::Status::Satisfiable: 67 return "Satisfiable"; 68 case Solver::Result::Status::Unsatisfiable: 69 return "Unsatisfiable"; 70 case Solver::Result::Status::TimedOut: 71 return "TimedOut"; 72 } 73 llvm_unreachable("Unhandled SAT check result status"); 74 } 75 76 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Solver::Result &R) { 77 OS << debugString(R.getStatus()) << "\n"; 78 if (auto Solution = R.getSolution()) { 79 std::vector<std::pair<Atom, Solver::Result::Assignment>> Sorted = { 80 Solution->begin(), Solution->end()}; 81 llvm::sort(Sorted); 82 for (const auto &Entry : Sorted) 83 OS << Entry.first << " = " << Entry.second << "\n"; 84 } 85 return OS; 86 } 87 88 } // namespace dataflow 89 } // namespace clang 90