blob: 5fe7fd8fee1d1d7e35984f4591cdf6ecbf5a4f53 [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#ifndef DEVTOOLS_RUST_CC_INTEROP_LIFETIME_ANALYSIS_POINTS_TO_MAP_H_
6#define DEVTOOLS_RUST_CC_INTEROP_LIFETIME_ANALYSIS_POINTS_TO_MAP_H_
7
8#include <string>
9
10#include "lifetime_analysis/object_set.h"
11#include "clang/AST/Expr.h"
12#include "llvm/ADT/DenseMap.h"
13
14namespace clang {
15namespace tidy {
16namespace lifetimes {
17
18// Maintains the points-to sets needed for the analysis of a function.
19// A `PointsToMap` stores points-to sets for
20// - Objects of reference-like type
21// - Expressions that are prvalues of pointer type or glvalues (glvalues are,
22// in spirit, references to the object they refer to.)
23// - The function's return value, if it is of reference-like type
24//
25// Note that the relationship between an expression's type and the type of the
26// objects associated with it depends on whether the expression is a glvalue or
27// prvalue:
28// - glvalue expressions are associated with the object that is identified by
29// the glvalue. This means that the object has the same type as the glvalue
30// expression.
31// - prvalue expressions of pointer type as are associated with the object that
32// the pointer points to. This means that if the prvalue expression has type
33// `T *`, the object has type `T`.
34// The PointsToMap class does not enforce these type relationships because we
35// intend to allow type punning (at least within the implementations of
36// functions).
37class PointsToMap {
38 public:
39 PointsToMap() = default;
40
41 PointsToMap(const PointsToMap&) = default;
42 PointsToMap(PointsToMap&&) = default;
43 PointsToMap& operator=(const PointsToMap&) = default;
44 PointsToMap& operator=(PointsToMap&&) = default;
45
46 bool operator==(const PointsToMap& other) const;
47 bool operator!=(const PointsToMap& other) const { return !(*this == other); }
48
49 // Returns a human-readable representation of this object.
50 std::string DebugString() const;
51
Martin Brænnea5098e12022-07-01 06:22:28 -070052 const llvm::DenseMap<const Object*, ObjectSet>& PointerPointsTos() const {
Luca Versari99fddff2022-05-25 10:22:32 -070053 return pointer_points_tos_;
54 }
55
56 // Returns a `PointsToMap` containing the union of mappings from this map and
57 // `other`.
58 // If both this map and `other` associate a points-to set with the same
59 // entity, the returned map associates that entity with the union of the
60 // corresponding points-to sets.
61 PointsToMap Union(const PointsToMap& other) const;
62
63 // Returns the points-to set associated with `pointer`, or an empty set if
64 // `pointer` is not associated with a points-to set.
Martin Brænnea5098e12022-07-01 06:22:28 -070065 ObjectSet GetPointerPointsToSet(const Object* pointer) const;
Luca Versari99fddff2022-05-25 10:22:32 -070066
67 // Associates `pointer` with the given points-to set.
Martin Brænnea5098e12022-07-01 06:22:28 -070068 void SetPointerPointsToSet(const Object* pointer, ObjectSet points_to);
Luca Versari99fddff2022-05-25 10:22:32 -070069
70 // Associates all `pointers` with the given points-to set.
71 void SetPointerPointsToSet(const ObjectSet& pointers,
72 const ObjectSet& points_to);
73
74 // Extends a single `pointer`'s points-to set with the given points-to set.
Martin Brænneb8916772022-07-01 02:28:09 -070075 void ExtendPointerPointsToSet(const Object* pointer,
Martin Brænnea5098e12022-07-01 06:22:28 -070076 const ObjectSet& points_to);
Luca Versari99fddff2022-05-25 10:22:32 -070077
78 // Returns the union of the points-to sets associated with the given pointers,
79 // or an empty set if none of the pointers is associated with a points-to set.
80 ObjectSet GetPointerPointsToSet(const ObjectSet& pointers) const;
81
82 // Returns the object set associated with `expr`.
83 // `expr` must previously have been associated with an object set through
84 // a call to SetExprObjectSet(), and the function asserts that this is the
85 // case. We intentionally don't return an empty object set in this case
86 // because we want to notice if we're not propagating object sets through
87 // expressions.
88 ObjectSet GetExprObjectSet(const clang::Expr* expr) const;
89
90 // Associates `expr` with the given object set.
91 void SetExprObjectSet(const clang::Expr* expr, ObjectSet objects);
92
Kinuko Yasuda45fd4be2023-05-03 02:11:57 -070093 // Returns if `expr` has an object set.
94 bool ExprHasObjectSet(const clang::Expr* expr) const;
95
Luca Versari99fddff2022-05-25 10:22:32 -070096 // Returns all the pointers (not objects) with the given `lifetime`.
Martin Brænnea5098e12022-07-01 06:22:28 -070097 std::vector<const Object*> GetAllPointersWithLifetime(
98 Lifetime lifetime) const;
Luca Versari99fddff2022-05-25 10:22:32 -070099
100 private:
Martin Brænnea5098e12022-07-01 06:22:28 -0700101 llvm::DenseMap<const Object*, ObjectSet> pointer_points_tos_;
Luca Versari99fddff2022-05-25 10:22:32 -0700102 llvm::DenseMap<const clang::Expr*, ObjectSet> expr_objects_;
103};
104
105} // namespace lifetimes
106} // namespace tidy
107} // namespace clang
108
109#endif // DEVTOOLS_RUST_CC_INTEROP_LIFETIME_ANALYSIS_POINTS_TO_MAP_H_