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