blob: 779dad136c000c1dda19b9721e39da7104454de8 [file] [log] [blame]
Luca Versari99fddff2022-05-25 10:22:32 -07001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#include "lifetime_analysis/lifetime_lattice.h"
6
7#include <assert.h>
8
9#include <string>
10#include <tuple>
11#include <utility>
12
Luca Versari53a2f582023-01-16 10:09:29 -080013#include "lifetime_analysis/lifetime_constraints.h"
14#include "lifetime_analysis/object_set.h"
15#include "lifetime_analysis/points_to_map.h"
Luca Versari99fddff2022-05-25 10:22:32 -070016#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
Luca Versari99fddff2022-05-25 10:22:32 -070017
18namespace clang {
19namespace tidy {
20namespace lifetimes {
21
22std::string LifetimeLattice::ToString() const {
23 if (IsError()) {
24 return Error().str();
25 }
26 return PointsTo().DebugString();
27}
28
29PointsToMap& LifetimeLattice::PointsTo() {
Luca Versari53a2f582023-01-16 10:09:29 -080030 return std::get<PointsToMap>(std::get<0>(var_));
Luca Versari99fddff2022-05-25 10:22:32 -070031}
32
33const PointsToMap& LifetimeLattice::PointsTo() const {
Luca Versari53a2f582023-01-16 10:09:29 -080034 return std::get<PointsToMap>(std::get<0>(var_));
Luca Versari81222852022-08-05 06:36:10 -070035}
36
37LifetimeConstraints& LifetimeLattice::Constraints() {
Luca Versari53a2f582023-01-16 10:09:29 -080038 return std::get<LifetimeConstraints>(std::get<0>(var_));
Luca Versari81222852022-08-05 06:36:10 -070039}
40
41const LifetimeConstraints& LifetimeLattice::Constraints() const {
Luca Versari53a2f582023-01-16 10:09:29 -080042 return std::get<LifetimeConstraints>(std::get<0>(var_));
43}
44
45ObjectSet& LifetimeLattice::SingleValuedObjects() {
46 return std::get<ObjectSet>(std::get<0>(var_));
47}
48
49const ObjectSet& LifetimeLattice::SingleValuedObjects() const {
50 return std::get<ObjectSet>(std::get<0>(var_));
Luca Versari99fddff2022-05-25 10:22:32 -070051}
52
53llvm::StringRef LifetimeLattice::Error() const {
Luca Versari99fddff2022-05-25 10:22:32 -070054 return std::get<std::string>(var_);
55}
56
57clang::dataflow::LatticeJoinEffect LifetimeLattice::join(
58 const LifetimeLattice& other) {
59 if (IsError()) {
60 return clang::dataflow::LatticeJoinEffect::Unchanged;
61 }
62 if (other.IsError()) {
63 *this = other;
64 return clang::dataflow::LatticeJoinEffect::Changed;
65 }
66
Luca Versari53a2f582023-01-16 10:09:29 -080067 auto effect = Constraints().join(other.Constraints());
Luca Versari81222852022-08-05 06:36:10 -070068
Luca Versari99fddff2022-05-25 10:22:32 -070069 PointsToMap joined_points_to_map = PointsTo().Union(other.PointsTo());
Luca Versari53a2f582023-01-16 10:09:29 -080070 if (PointsTo() != joined_points_to_map) {
71 PointsTo() = std::move(joined_points_to_map);
72 effect = clang::dataflow::LatticeJoinEffect::Changed;
Luca Versari99fddff2022-05-25 10:22:32 -070073 }
74
Luca Versari53a2f582023-01-16 10:09:29 -080075 ObjectSet joined_single_valued_objects =
76 SingleValuedObjects().Intersection(other.SingleValuedObjects());
77 if (SingleValuedObjects() != joined_single_valued_objects) {
78 SingleValuedObjects() = std::move(joined_single_valued_objects);
79 effect = clang::dataflow::LatticeJoinEffect::Changed;
80 }
81
82 return effect;
Luca Versari99fddff2022-05-25 10:22:32 -070083}
84
85bool LifetimeLattice::operator==(const LifetimeLattice& other) const {
86 if (IsError() || other.IsError()) {
87 // Any error compares equal to any other error.
88 return IsError() && other.IsError();
89 }
Luca Versari91a56ff2022-08-22 01:58:33 -070090 return PointsTo() == other.PointsTo() && Constraints() == other.Constraints();
Luca Versari99fddff2022-05-25 10:22:32 -070091}
92
93} // namespace lifetimes
94} // namespace tidy
95} // namespace clang