clang: lib/Analysis/FlowSensitive/FormulaSerialization.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/Allocator.h"
17#include "llvm/Support/Error.h"
18#include "llvm/Support/ErrorHandling.h"
19#include
20
22
23
24
26 switch (K) {
29
30 return '\0';
32 return '!';
34 return '&';
36 return '|';
38 return '>';
40 return '=';
41 }
42 llvm_unreachable("unhandled formula kind");
43}
44
47 case 0:
48 switch (F.kind()) {
51 break;
53 OS << (F.literal() ? 'T' : 'F');
54 break;
55 default:
56 llvm_unreachable("unhandled formula kind");
57 }
58 break;
59 case 1:
62 break;
63 case 2:
67 break;
68 default:
69 llvm_unreachable("unhandled formula arity");
70 }
71}
72
75 llvm::DenseMap<unsigned, Atom> &AtomMap) {
76 if (Str.empty())
77 return llvm::createStringError(llvm::inconvertibleErrorCode(),
78 "unexpected end of input");
79
80 char Prefix = Str[0];
81 Str = Str.drop_front();
82
83 switch (Prefix) {
84 case 'T':
86 case 'F':
88 case 'V': {
89 unsigned AtomID;
90 if (Str.consumeInteger(10, AtomID))
91 return llvm::createStringError(llvm::inconvertibleErrorCode(),
92 "expected atom id");
93 auto [It, Inserted] = AtomMap.try_emplace(AtomID, Atom());
94 if (Inserted)
97 }
98 case '!': {
99 auto OperandOrErr = parsePrefix(Str, A, AtomMap);
100 if (!OperandOrErr)
101 return OperandOrErr.takeError();
102 return &A.makeNot(**OperandOrErr);
103 }
104 case '&':
105 case '|':
106 case '>':
107 case '=': {
108 auto LeftOrErr = parsePrefix(Str, A, AtomMap);
109 if (!LeftOrErr)
110 return LeftOrErr.takeError();
111
112 auto RightOrErr = parsePrefix(Str, A, AtomMap);
113 if (!RightOrErr)
114 return RightOrErr.takeError();
115
116 const Formula &LHS = **LeftOrErr;
117 const Formula &RHS = **RightOrErr;
118
119 switch (Prefix) {
120 case '&':
121 return &A.makeAnd(LHS, RHS);
122 case '|':
123 return &A.makeOr(LHS, RHS);
124 case '>':
126 case '=':
128 default:
129 llvm_unreachable("unexpected binary op");
130 }
131 }
132 default:
133 return llvm::createStringError(llvm::inconvertibleErrorCode(),
134 "unexpected prefix character: %c", Prefix);
135 }
136}
137
140 llvm::DenseMap<unsigned, Atom> &AtomMap) {
141 size_t OriginalSize = Str.size();
143 if (!F)
144 return F.takeError();
145 if (!Str.empty())
146 return llvm::createStringError(llvm::inconvertibleErrorCode(),
147 ("unexpected suffix of length: " +
148 llvm::Twine(Str.size() - OriginalSize))
149 .str());
150 return F;
151}
152
153}
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.
ArrayRef< const Formula * > operands() const
@ Equal
True if LHS is false or RHS is true.
@ Implies
True if either LHS or RHS is true.
@ AtomRef
A reference to an atomic boolean variable.
@ Literal
Constant true or false.
@ Or
True if LHS and RHS are both true.
@ And
True if its only operand is false.
static unsigned numOperands(Kind K)
Count of operands (sub-formulas) associated with Formulas of kind K.
Dataflow Directional Tag Classes.
static llvm::Expected< const Formula * > parsePrefix(llvm::StringRef &Str, Arena &A, llvm::DenseMap< unsigned, Atom > &AtomMap)
Definition FormulaSerialization.cpp:74
Atom
Identifies an atomic boolean variable such as "V1".
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...
Definition FormulaSerialization.cpp:45
llvm::Expected< const Formula * > parseFormula(llvm::StringRef Str, Arena &A, llvm::DenseMap< unsigned, Atom > &AtomMap)
Parses Str to build a serialized Formula.
Definition FormulaSerialization.cpp:139
static char compactSigil(Formula::Kind K)
Definition FormulaSerialization.cpp:25