1 //===-- DataflowAnalysisContext.cpp -----------------------------*- C++ -*-===// 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 // This file defines a DataflowAnalysisContext class that owns objects that 10 // encompass the state of a program and stores context that is used during 11 // dataflow analysis. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" 16 #include "clang/Analysis/FlowSensitive/Value.h" 17 #include <cassert> 18 #include <memory> 19 #include <utility> 20 21 namespace clang { 22 namespace dataflow { 23 24 static std::pair<BoolValue *, BoolValue *> 25 makeCanonicalBoolValuePair(BoolValue &LHS, BoolValue &RHS) { 26 auto Res = std::make_pair(&LHS, &RHS); 27 if (&RHS < &LHS) 28 std::swap(Res.first, Res.second); 29 return Res; 30 } 31 32 BoolValue & 33 DataflowAnalysisContext::getOrCreateConjunctionValue(BoolValue &LHS, 34 BoolValue &RHS) { 35 if (&LHS == &RHS) 36 return LHS; 37 38 auto Res = ConjunctionVals.try_emplace(makeCanonicalBoolValuePair(LHS, RHS), 39 nullptr); 40 if (Res.second) 41 Res.first->second = 42 &takeOwnership(std::make_unique<ConjunctionValue>(LHS, RHS)); 43 return *Res.first->second; 44 } 45 46 BoolValue & 47 DataflowAnalysisContext::getOrCreateDisjunctionValue(BoolValue &LHS, 48 BoolValue &RHS) { 49 if (&LHS == &RHS) 50 return LHS; 51 52 auto Res = DisjunctionVals.try_emplace(makeCanonicalBoolValuePair(LHS, RHS), 53 nullptr); 54 if (Res.second) 55 Res.first->second = 56 &takeOwnership(std::make_unique<DisjunctionValue>(LHS, RHS)); 57 return *Res.first->second; 58 } 59 60 BoolValue &DataflowAnalysisContext::getOrCreateNegationValue(BoolValue &Val) { 61 auto Res = NegationVals.try_emplace(&Val, nullptr); 62 if (Res.second) 63 Res.first->second = &takeOwnership(std::make_unique<NegationValue>(Val)); 64 return *Res.first->second; 65 } 66 67 } // namespace dataflow 68 } // namespace clang 69