blob: 6dc3343b1cf53496db1a7f35808ba13e371f663c [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
Luca Versari99fddff2022-05-25 10:22:32 -07007#include <string>
Luca Versari99fddff2022-05-25 10:22:32 -07008#include <utility>
9
Luca Versari53a2f582023-01-16 10:09:29 -080010#include "lifetime_analysis/lifetime_constraints.h"
11#include "lifetime_analysis/object_set.h"
12#include "lifetime_analysis/points_to_map.h"
Luca Versari99fddff2022-05-25 10:22:32 -070013#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
Dmitri Gribenkoa087d232023-07-10 08:03:46 -070014#include "llvm/ADT/StringRef.h"
Luca Versari99fddff2022-05-25 10:22:32 -070015
16namespace clang {
17namespace tidy {
18namespace lifetimes {
19
20std::string LifetimeLattice::ToString() const {
21 if (IsError()) {
22 return Error().str();
23 }
24 return PointsTo().DebugString();
25}
26
27PointsToMap& LifetimeLattice::PointsTo() {
Luca Versari53a2f582023-01-16 10:09:29 -080028 return std::get<PointsToMap>(std::get<0>(var_));
Luca Versari99fddff2022-05-25 10:22:32 -070029}
30
31const PointsToMap& LifetimeLattice::PointsTo() const {
Luca Versari53a2f582023-01-16 10:09:29 -080032 return std::get<PointsToMap>(std::get<0>(var_));
Luca Versari81222852022-08-05 06:36:10 -070033}
34
35LifetimeConstraints& LifetimeLattice::Constraints() {
Luca Versari53a2f582023-01-16 10:09:29 -080036 return std::get<LifetimeConstraints>(std::get<0>(var_));
Luca Versari81222852022-08-05 06:36:10 -070037}
38
39const LifetimeConstraints& LifetimeLattice::Constraints() const {
Luca Versari53a2f582023-01-16 10:09:29 -080040 return std::get<LifetimeConstraints>(std::get<0>(var_));
41}
42
43ObjectSet& LifetimeLattice::SingleValuedObjects() {
44 return std::get<ObjectSet>(std::get<0>(var_));
45}
46
47const ObjectSet& LifetimeLattice::SingleValuedObjects() const {
48 return std::get<ObjectSet>(std::get<0>(var_));
Luca Versari99fddff2022-05-25 10:22:32 -070049}
50
51llvm::StringRef LifetimeLattice::Error() const {
Luca Versari99fddff2022-05-25 10:22:32 -070052 return std::get<std::string>(var_);
53}
54
55clang::dataflow::LatticeJoinEffect LifetimeLattice::join(
56 const LifetimeLattice& other) {
57 if (IsError()) {
58 return clang::dataflow::LatticeJoinEffect::Unchanged;
59 }
60 if (other.IsError()) {
61 *this = other;
62 return clang::dataflow::LatticeJoinEffect::Changed;
63 }
64
Luca Versari53a2f582023-01-16 10:09:29 -080065 auto effect = Constraints().join(other.Constraints());
Luca Versari81222852022-08-05 06:36:10 -070066
Luca Versari99fddff2022-05-25 10:22:32 -070067 PointsToMap joined_points_to_map = PointsTo().Union(other.PointsTo());
Luca Versari53a2f582023-01-16 10:09:29 -080068 if (PointsTo() != joined_points_to_map) {
69 PointsTo() = std::move(joined_points_to_map);
70 effect = clang::dataflow::LatticeJoinEffect::Changed;
Luca Versari99fddff2022-05-25 10:22:32 -070071 }
72
Luca Versari53a2f582023-01-16 10:09:29 -080073 ObjectSet joined_single_valued_objects =
74 SingleValuedObjects().Intersection(other.SingleValuedObjects());
75 if (SingleValuedObjects() != joined_single_valued_objects) {
76 SingleValuedObjects() = std::move(joined_single_valued_objects);
77 effect = clang::dataflow::LatticeJoinEffect::Changed;
78 }
79
80 return effect;
Luca Versari99fddff2022-05-25 10:22:32 -070081}
82
83bool LifetimeLattice::operator==(const LifetimeLattice& other) const {
84 if (IsError() || other.IsError()) {
85 // Any error compares equal to any other error.
86 return IsError() && other.IsError();
87 }
Luca Versari91a56ff2022-08-22 01:58:33 -070088 return PointsTo() == other.PointsTo() && Constraints() == other.Constraints();
Luca Versari99fddff2022-05-25 10:22:32 -070089}
90
91} // namespace lifetimes
92} // namespace tidy
93} // namespace clang