12#include "llvm/Support/Error.h"
17static std::pair<const Formula *, const Formula *>
19 auto Res = std::make_pair(&LHS, &RHS);
21 std::swap(Res.first, Res.second);
26 auto [It, Inserted] = AtomRefs.try_emplace(A);
56 auto [It, Inserted] = Nots.try_emplace(&Val,
nullptr);
67 Implies.try_emplace(std::make_pair(&LHS, &RHS),
nullptr);
85 auto [It, Inserted] = IntegerLiterals.try_emplace(
Value,
nullptr);
88 It->second = &create<IntegerValue>();
93 auto [It, Inserted] = FormulaValues.try_emplace(&F);
96 ? (
BoolValue *)&create<AtomicBoolValue>(F)
97 : &create<FormulaBoolValue>(F);
103 auto EatSpaces = [&] { In = In.ltrim(
' '); };
106 if (In.consume_front(
"!")) {
107 if (
auto *Arg = parse(A, In))
112 if (In.consume_front(
"(")) {
113 auto *Arg1 = parse(A, In);
119 if (In.consume_front(
"|"))
121 else if (In.consume_front(
"&"))
123 else if (In.consume_front(
"=>"))
125 else if (In.consume_front(
"="))
130 auto *Arg2 = parse(A, In);
135 if (!In.consume_front(
")"))
138 return &(A.*Op)(*Arg1, *Arg2);
143 if (In.consume_front(
"V")) {
144 std::underlying_type_t<Atom> At;
145 if (In.consumeInteger(10, At))
150 if (In.consume_front(
"true"))
152 if (In.consume_front(
"false"))
158class FormulaParseError :
public llvm::ErrorInfo<FormulaParseError> {
164 FormulaParseError(llvm::StringRef Formula,
unsigned Offset)
165 : Formula(Formula), Offset(Offset) {}
167 void log(raw_ostream &OS)
const override {
168 OS <<
"bad formula at offset " << Offset <<
"\n";
169 OS << Formula <<
"\n";
170 OS.indent(Offset) <<
"^";
173 std::error_code convertToErrorCode()
const override {
174 return std::make_error_code(std::errc::invalid_argument);
178char FormulaParseError::ID = 0;
183 llvm::StringRef Rest = In;
184 auto *
Result = parse(*
this, Rest);
186 return llvm::make_error<FormulaParseError>(In, In.size() - Rest.size());
189 return llvm::make_error<FormulaParseError>(In, In.size() - Rest.size());
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.
IntegerValue & makeIntLiteral(llvm::APInt Value)
Returns a symbolic integer value that models an integer literal equal to Value.
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.
BoolValue & makeBoolValue(const Formula &)
Creates a BoolValue wrapping a particular formula.
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.
llvm::Expected< const Formula & > parseFormula(llvm::StringRef)
Base class for all values computed by abstract interpretation.
Dataflow Directional Tag Classes.
Atom
Identifies an atomic boolean variable such as "V1".
static std::pair< const Formula *, const Formula * > canonicalFormulaPair(const Formula &LHS, const Formula &RHS)
@ Result
The result type of a method or function.