1 //===-- Arena.cpp ---------------------------------------------------------===// 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 #include "clang/Analysis/FlowSensitive/Arena.h" 10 #include "clang/Analysis/FlowSensitive/Value.h" 11 12 namespace clang::dataflow { 13 14 static std::pair<const Formula *, const Formula *> 15 canonicalFormulaPair(const Formula &LHS, const Formula &RHS) { 16 auto Res = std::make_pair(&LHS, &RHS); 17 if (&RHS < &LHS) // FIXME: use a deterministic order instead 18 std::swap(Res.first, Res.second); 19 return Res; 20 } 21 22 const Formula &Arena::makeAtomRef(Atom A) { 23 auto [It, Inserted] = AtomRefs.try_emplace(A); 24 if (Inserted) 25 It->second = 26 &Formula::create(Alloc, Formula::AtomRef, {}, static_cast<unsigned>(A)); 27 return *It->second; 28 } 29 30 const Formula &Arena::makeAnd(const Formula &LHS, const Formula &RHS) { 31 if (&LHS == &RHS) 32 return LHS; 33 34 auto [It, Inserted] = 35 Ands.try_emplace(canonicalFormulaPair(LHS, RHS), nullptr); 36 if (Inserted) 37 It->second = &Formula::create(Alloc, Formula::And, {&LHS, &RHS}); 38 return *It->second; 39 } 40 41 const Formula &Arena::makeOr(const Formula &LHS, const Formula &RHS) { 42 if (&LHS == &RHS) 43 return LHS; 44 45 auto [It, Inserted] = 46 Ors.try_emplace(canonicalFormulaPair(LHS, RHS), nullptr); 47 if (Inserted) 48 It->second = &Formula::create(Alloc, Formula::Or, {&LHS, &RHS}); 49 return *It->second; 50 } 51 52 const Formula &Arena::makeNot(const Formula &Val) { 53 auto [It, Inserted] = Nots.try_emplace(&Val, nullptr); 54 if (Inserted) 55 It->second = &Formula::create(Alloc, Formula::Not, {&Val}); 56 return *It->second; 57 } 58 59 const Formula &Arena::makeImplies(const Formula &LHS, const Formula &RHS) { 60 if (&LHS == &RHS) 61 return makeLiteral(true); 62 63 auto [It, Inserted] = 64 Implies.try_emplace(std::make_pair(&LHS, &RHS), nullptr); 65 if (Inserted) 66 It->second = &Formula::create(Alloc, Formula::Implies, {&LHS, &RHS}); 67 return *It->second; 68 } 69 70 const Formula &Arena::makeEquals(const Formula &LHS, const Formula &RHS) { 71 if (&LHS == &RHS) 72 return makeLiteral(true); 73 74 auto [It, Inserted] = 75 Equals.try_emplace(canonicalFormulaPair(LHS, RHS), nullptr); 76 if (Inserted) 77 It->second = &Formula::create(Alloc, Formula::Equal, {&LHS, &RHS}); 78 return *It->second; 79 } 80 81 IntegerValue &Arena::makeIntLiteral(llvm::APInt Value) { 82 auto [It, Inserted] = IntegerLiterals.try_emplace(Value, nullptr); 83 84 if (Inserted) 85 It->second = &create<IntegerValue>(); 86 return *It->second; 87 } 88 89 BoolValue &Arena::makeBoolValue(const Formula &F) { 90 auto [It, Inserted] = FormulaValues.try_emplace(&F); 91 if (Inserted) 92 It->second = (F.kind() == Formula::AtomRef) 93 ? (BoolValue *)&create<AtomicBoolValue>(F) 94 : &create<FormulaBoolValue>(F); 95 return *It->second; 96 } 97 98 } // namespace clang::dataflow 99