| // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| // Exceptions. See /LICENSE for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| #include "lifetime_analysis/lifetime_lattice.h" |
| |
| #include <string> |
| #include <utility> |
| |
| #include "lifetime_analysis/lifetime_constraints.h" |
| #include "lifetime_analysis/object_set.h" |
| #include "lifetime_analysis/points_to_map.h" |
| #include "clang/Analysis/FlowSensitive/DataflowLattice.h" |
| #include "llvm/ADT/StringRef.h" |
| |
| namespace clang { |
| namespace tidy { |
| namespace lifetimes { |
| |
| std::string LifetimeLattice::ToString() const { |
| if (IsError()) { |
| return Error().str(); |
| } |
| return PointsTo().DebugString(); |
| } |
| |
| PointsToMap& LifetimeLattice::PointsTo() { |
| return std::get<PointsToMap>(std::get<0>(var_)); |
| } |
| |
| const PointsToMap& LifetimeLattice::PointsTo() const { |
| return std::get<PointsToMap>(std::get<0>(var_)); |
| } |
| |
| LifetimeConstraints& LifetimeLattice::Constraints() { |
| return std::get<LifetimeConstraints>(std::get<0>(var_)); |
| } |
| |
| const LifetimeConstraints& LifetimeLattice::Constraints() const { |
| return std::get<LifetimeConstraints>(std::get<0>(var_)); |
| } |
| |
| ObjectSet& LifetimeLattice::SingleValuedObjects() { |
| return std::get<ObjectSet>(std::get<0>(var_)); |
| } |
| |
| const ObjectSet& LifetimeLattice::SingleValuedObjects() const { |
| return std::get<ObjectSet>(std::get<0>(var_)); |
| } |
| |
| llvm::StringRef LifetimeLattice::Error() const { |
| return std::get<std::string>(var_); |
| } |
| |
| clang::dataflow::LatticeJoinEffect LifetimeLattice::join( |
| const LifetimeLattice& other) { |
| if (IsError()) { |
| return clang::dataflow::LatticeJoinEffect::Unchanged; |
| } |
| if (other.IsError()) { |
| *this = other; |
| return clang::dataflow::LatticeJoinEffect::Changed; |
| } |
| |
| auto effect = Constraints().join(other.Constraints()); |
| |
| PointsToMap joined_points_to_map = PointsTo().Union(other.PointsTo()); |
| if (PointsTo() != joined_points_to_map) { |
| PointsTo() = std::move(joined_points_to_map); |
| effect = clang::dataflow::LatticeJoinEffect::Changed; |
| } |
| |
| ObjectSet joined_single_valued_objects = |
| SingleValuedObjects().Intersection(other.SingleValuedObjects()); |
| if (SingleValuedObjects() != joined_single_valued_objects) { |
| SingleValuedObjects() = std::move(joined_single_valued_objects); |
| effect = clang::dataflow::LatticeJoinEffect::Changed; |
| } |
| |
| return effect; |
| } |
| |
| bool LifetimeLattice::operator==(const LifetimeLattice& other) const { |
| if (IsError() || other.IsError()) { |
| // Any error compares equal to any other error. |
| return IsError() && other.IsError(); |
| } |
| return PointsTo() == other.PointsTo() && Constraints() == other.Constraints(); |
| } |
| |
| } // namespace lifetimes |
| } // namespace tidy |
| } // namespace clang |