13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/Error.h"
16#include "llvm/Support/ErrorHandling.h"
43 llvm_unreachable(
"unhandled formula kind");
48 std::stack<const Formula *> WorkList;
50 while (!WorkList.empty()) {
51 const Formula *Current = WorkList.top();
55 switch (Current->
kind()) {
60 OS << (Current->
literal() ?
'T' :
'F');
63 llvm_unreachable(
"unhandled formula kind");
68 WorkList.push(Current->
operands()[0]);
72 WorkList.push(Current->
operands()[1]);
73 WorkList.push(Current->
operands()[0]);
76 llvm_unreachable(
"unhandled formula arity");
91 llvm::DenseMap<unsigned, Atom> &AtomMap) {
92 std::stack<Operation> ActiveOperations;
95 if (ActiveOperations.empty() ||
96 ActiveOperations.top().ExpectedNumOperands >
97 ActiveOperations.top().Operands.size()) {
99 return llvm::createStringError(llvm::inconvertibleErrorCode(),
100 "unexpected end of input");
102 char Prefix = Str[0];
103 Str = Str.drop_front();
110 const Formula *TerminalFormula;
120 if (Str.consumeInteger(10, AtomID))
121 return llvm::createStringError(llvm::inconvertibleErrorCode(),
123 auto [It, Inserted] = AtomMap.try_emplace(AtomID,
Atom());
130 llvm_unreachable(
"unexpected terminal character");
132 if (ActiveOperations.empty()) {
133 return TerminalFormula;
136 Op->
Operands.push_back(TerminalFormula);
154 return llvm::createStringError(llvm::inconvertibleErrorCode(),
155 "unexpected prefix character: %c",
158 }
else if (!ActiveOperations.empty() &&
159 ActiveOperations.top().ExpectedNumOperands ==
160 ActiveOperations.top().Operands.size()) {
162 const Formula *OpFormula =
nullptr;
180 return llvm::createStringError(llvm::inconvertibleErrorCode(),
181 "only unary and binary operations are "
182 "expected, but got Formula::Kind %u",
185 ActiveOperations.pop();
186 if (ActiveOperations.empty())
188 Op = &ActiveOperations.top();
192 "we should never have added more operands than expected");
199 llvm::DenseMap<unsigned, Atom> &AtomMap) {
200 size_t OriginalSize = Str.size();
203 return F.takeError();
205 return llvm::createStringError(llvm::inconvertibleErrorCode(),
206 (
"unexpected suffix of length: " +
207 llvm::Twine(Str.size() - OriginalSize))
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
The Arena owns the objects that model data within an analysis.
const Formula & makeEquals(const Formula &LHS, const Formula &RHS)
Returns a formula for LHS <=> RHS.
const Formula & makeAtomRef(Atom A)
Returns a formula for the variable A.
Atom makeAtom()
Returns a new atomic boolean variable, distinct from any other.
const Formula & makeNot(const Formula &Val)
Returns a formula for the negation of Val.
const Formula & makeOr(const Formula &LHS, const Formula &RHS)
Returns a formula for the disjunction of LHS and RHS.
const Formula & makeAnd(const Formula &LHS, const Formula &RHS)
Returns a formula for the conjunction of LHS and RHS.
const Formula & makeImplies(const Formula &LHS, const Formula &RHS)
Returns a formula for LHS => RHS.
const Formula & makeLiteral(bool Value)
Returns a formula for a literal true/false.
Dataflow Directional Tag Classes.
Atom
Identifies an atomic boolean variable such as "V1".
static llvm::Expected< const Formula * > parseFormulaInternal(llvm::StringRef &Str, Arena &A, llvm::DenseMap< unsigned, Atom > &AtomMap)
void serializeFormula(const Formula &F, llvm::raw_ostream &OS)
Prints F to OS in a compact format, optimized for easy parsing (deserialization) rather than human us...
llvm::Expected< const Formula * > parseFormula(llvm::StringRef Str, Arena &A, llvm::DenseMap< unsigned, Atom > &AtomMap)
Parses Str to build a serialized Formula.
static char compactSigil(Formula::Kind K)
const unsigned ExpectedNumOperands
Operation(Formula::Kind Kind)
std::vector< const Formula * > Operands