xref: /src/contrib/llvm-project/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
11f917f69SDimitry Andric //===- DebugSupport.cpp -----------------------------------------*- C++ -*-===//
21f917f69SDimitry Andric //
31f917f69SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41f917f69SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
51f917f69SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61f917f69SDimitry Andric //
71f917f69SDimitry Andric //===----------------------------------------------------------------------===//
81f917f69SDimitry Andric //
91f917f69SDimitry Andric //  This file defines functions which generate more readable forms of data
101f917f69SDimitry Andric //  structures used in the dataflow analyses, for debugging purposes.
111f917f69SDimitry Andric //
121f917f69SDimitry Andric //===----------------------------------------------------------------------===//
131f917f69SDimitry Andric 
141f917f69SDimitry Andric #include <utility>
151f917f69SDimitry Andric 
161f917f69SDimitry Andric #include "clang/Analysis/FlowSensitive/DebugSupport.h"
171f917f69SDimitry Andric #include "clang/Analysis/FlowSensitive/Solver.h"
181f917f69SDimitry Andric #include "clang/Analysis/FlowSensitive/Value.h"
19e3b55780SDimitry Andric #include "llvm/ADT/StringRef.h"
201f917f69SDimitry Andric #include "llvm/Support/ErrorHandling.h"
211f917f69SDimitry Andric 
221f917f69SDimitry Andric namespace clang {
231f917f69SDimitry Andric namespace dataflow {
241f917f69SDimitry Andric 
debugString(Value::Kind Kind)25e3b55780SDimitry Andric llvm::StringRef debugString(Value::Kind Kind) {
26e3b55780SDimitry Andric   switch (Kind) {
27e3b55780SDimitry Andric   case Value::Kind::Integer:
28e3b55780SDimitry Andric     return "Integer";
29e3b55780SDimitry Andric   case Value::Kind::Pointer:
30e3b55780SDimitry Andric     return "Pointer";
31e3b55780SDimitry Andric   case Value::Kind::AtomicBool:
32e3b55780SDimitry Andric     return "AtomicBool";
33e3b55780SDimitry Andric   case Value::Kind::TopBool:
34e3b55780SDimitry Andric     return "TopBool";
357fa27ce4SDimitry Andric   case Value::Kind::FormulaBool:
367fa27ce4SDimitry Andric     return "FormulaBool";
37e3b55780SDimitry Andric   }
38e3b55780SDimitry Andric   llvm_unreachable("Unhandled value kind");
39e3b55780SDimitry Andric }
40e3b55780SDimitry Andric 
operator <<(llvm::raw_ostream & OS,Solver::Result::Assignment Assignment)417fa27ce4SDimitry Andric llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
427fa27ce4SDimitry Andric                               Solver::Result::Assignment Assignment) {
434b4fe385SDimitry Andric   switch (Assignment) {
444b4fe385SDimitry Andric   case Solver::Result::Assignment::AssignedFalse:
457fa27ce4SDimitry Andric     return OS << "False";
464b4fe385SDimitry Andric   case Solver::Result::Assignment::AssignedTrue:
477fa27ce4SDimitry Andric     return OS << "True";
484b4fe385SDimitry Andric   }
494b4fe385SDimitry Andric   llvm_unreachable("Booleans can only be assigned true/false");
504b4fe385SDimitry Andric }
514b4fe385SDimitry Andric 
debugString(Solver::Result::Status Status)52e3b55780SDimitry Andric llvm::StringRef debugString(Solver::Result::Status Status) {
534b4fe385SDimitry Andric   switch (Status) {
544b4fe385SDimitry Andric   case Solver::Result::Status::Satisfiable:
554b4fe385SDimitry Andric     return "Satisfiable";
564b4fe385SDimitry Andric   case Solver::Result::Status::Unsatisfiable:
574b4fe385SDimitry Andric     return "Unsatisfiable";
584b4fe385SDimitry Andric   case Solver::Result::Status::TimedOut:
594b4fe385SDimitry Andric     return "TimedOut";
604b4fe385SDimitry Andric   }
614b4fe385SDimitry Andric   llvm_unreachable("Unhandled SAT check result status");
624b4fe385SDimitry Andric }
634b4fe385SDimitry Andric 
operator <<(llvm::raw_ostream & OS,const Solver::Result & R)647fa27ce4SDimitry Andric llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Solver::Result &R) {
657fa27ce4SDimitry Andric   OS << debugString(R.getStatus()) << "\n";
667fa27ce4SDimitry Andric   if (auto Solution = R.getSolution()) {
677fa27ce4SDimitry Andric     std::vector<std::pair<Atom, Solver::Result::Assignment>> Sorted = {
687fa27ce4SDimitry Andric         Solution->begin(), Solution->end()};
697fa27ce4SDimitry Andric     llvm::sort(Sorted);
707fa27ce4SDimitry Andric     for (const auto &Entry : Sorted)
717fa27ce4SDimitry Andric       OS << Entry.first << " = " << Entry.second << "\n";
721f917f69SDimitry Andric   }
737fa27ce4SDimitry Andric   return OS;
741f917f69SDimitry Andric }
751f917f69SDimitry Andric 
761f917f69SDimitry Andric } // namespace dataflow
771f917f69SDimitry Andric } // namespace clang
78