xref: /freebsd/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp (revision a2fda816eb054d5873be223ef2461741dfcc253c)
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::Pointer:
30      return "Pointer";
31    case Value::Kind::Record:
32      return "Record";
33    case Value::Kind::AtomicBool:
34      return "AtomicBool";
35    case Value::Kind::TopBool:
36      return "TopBool";
37    case Value::Kind::FormulaBool:
38      return "FormulaBool";
39    }
40    llvm_unreachable("Unhandled value kind");
41  }
42  
43  llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
44                                Solver::Result::Assignment Assignment) {
45    switch (Assignment) {
46    case Solver::Result::Assignment::AssignedFalse:
47      return OS << "False";
48    case Solver::Result::Assignment::AssignedTrue:
49      return OS << "True";
50    }
51    llvm_unreachable("Booleans can only be assigned true/false");
52  }
53  
54  llvm::StringRef debugString(Solver::Result::Status Status) {
55    switch (Status) {
56    case Solver::Result::Status::Satisfiable:
57      return "Satisfiable";
58    case Solver::Result::Status::Unsatisfiable:
59      return "Unsatisfiable";
60    case Solver::Result::Status::TimedOut:
61      return "TimedOut";
62    }
63    llvm_unreachable("Unhandled SAT check result status");
64  }
65  
66  llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Solver::Result &R) {
67    OS << debugString(R.getStatus()) << "\n";
68    if (auto Solution = R.getSolution()) {
69      std::vector<std::pair<Atom, Solver::Result::Assignment>> Sorted = {
70          Solution->begin(), Solution->end()};
71      llvm::sort(Sorted);
72      for (const auto &Entry : Sorted)
73        OS << Entry.first << " = " << Entry.second << "\n";
74    }
75    return OS;
76  }
77  
78  } // namespace dataflow
79  } // namespace clang
80