Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 1 | // 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_OBJECT_REPOSITORY_H_ |
| 6 | #define DEVTOOLS_RUST_CC_INTEROP_LIFETIME_ANALYSIS_OBJECT_REPOSITORY_H_ |
| 7 | |
Dmitri Gribenko | a087d23 | 2023-07-10 08:03:46 -0700 | [diff] [blame] | 8 | #include <cstddef> |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 9 | #include <optional> |
| 10 | #include <string> |
Dmitri Gribenko | a087d23 | 2023-07-10 08:03:46 -0700 | [diff] [blame] | 11 | #include <utility> |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 12 | |
| 13 | #include "lifetime_analysis/object.h" |
| 14 | #include "lifetime_analysis/object_set.h" |
| 15 | #include "lifetime_analysis/points_to_map.h" |
Dmitri Gribenko | a087d23 | 2023-07-10 08:03:46 -0700 | [diff] [blame] | 16 | #include "lifetime_annotations/function_lifetimes.h" |
| 17 | #include "lifetime_annotations/lifetime.h" |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 18 | #include "lifetime_annotations/type_lifetimes.h" |
| 19 | #include "clang/AST/Decl.h" |
| 20 | #include "clang/AST/Expr.h" |
| 21 | #include "clang/AST/ExprCXX.h" |
Dmitri Gribenko | a087d23 | 2023-07-10 08:03:46 -0700 | [diff] [blame] | 22 | #include "clang/AST/Type.h" |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 23 | #include "llvm/ADT/DenseMap.h" |
Martin Brænne | 4a1231d | 2022-07-01 01:45:44 -0700 | [diff] [blame] | 24 | #include "llvm/Support/Allocator.h" |
Dmitri Gribenko | a087d23 | 2023-07-10 08:03:46 -0700 | [diff] [blame] | 25 | #include "llvm/Support/Error.h" |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 26 | |
| 27 | namespace clang { |
| 28 | namespace tidy { |
| 29 | namespace lifetimes { |
| 30 | |
| 31 | // A record-type expression has 2 modes: |
| 32 | // 1. If it's being assigned to a reference, then the contents of the expression |
| 33 | // are a glvalue. This is because references require an object to point to. |
| 34 | // 2. If it's being assigned to a record object, then the expression itself is |
| 35 | // not creating an object, but initializing it. So the expression's type is |
| 36 | // a pure value, and it acts _on_ the initializing object instead of |
| 37 | // producing an object. |
| 38 | inline bool IsInitExprInitializingARecordObject(const clang::Expr* expr) { |
| 39 | return expr->getType()->isRecordType() && expr->isPRValue(); |
| 40 | } |
| 41 | |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 42 | // Returns the lifetimes of the given FunctionDecl, or an error if they are |
| 43 | // unknown or analysis failed on that FunctionDecl. |
| 44 | FunctionLifetimesOrError GetFunctionLifetimes( |
| 45 | const FunctionDecl* decl, |
| 46 | const llvm::DenseMap<const FunctionDecl*, FunctionLifetimesOrError>& |
| 47 | known_lifetimes); |
| 48 | |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 49 | // A repository for the objects used in the lifetime analysis of a single |
| 50 | // function. |
Martin Brænne | fb8153d | 2022-06-28 04:05:14 -0700 | [diff] [blame] | 51 | // This class establishes a relationship between AST nodes (e.g. variable |
| 52 | // declarations) and the objects that represent them. It also stores additional |
| 53 | // information about objects that does not change during the analysis. |
| 54 | // The `ObjectRepository` only stores state that does not change during the |
| 55 | // analysis; it is therefore not part of the lattice. |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 56 | class ObjectRepository { |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 57 | private: |
Martin Brænne | e9a4a47 | 2022-07-01 02:26:55 -0700 | [diff] [blame] | 58 | using MapType = llvm::DenseMap<const clang::ValueDecl*, const Object*>; |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 59 | |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 60 | public: |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 61 | // Tag struct for InitializedObject: the object being initialized is the |
| 62 | // return value of the function. |
| 63 | struct ReturnValue {}; |
| 64 | |
| 65 | // Maps a given struct-Object to the Object for each of its fields. |
| 66 | // TODO(veluca): this approach does not produce correct results when |
| 67 | // diamond-problem-style multiple inheritance happens. |
| 68 | using FieldObjects = |
Martin Brænne | 1b98ac6 | 2022-07-01 06:24:52 -0700 | [diff] [blame] | 69 | llvm::DenseMap<std::pair<const Object*, const clang::FieldDecl*>, |
| 70 | const Object*>; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 71 | |
| 72 | // Maps a given struct-Object to the Object for each of its bases. |
| 73 | using BaseObjects = |
Martin Brænne | 1b98ac6 | 2022-07-01 06:24:52 -0700 | [diff] [blame] | 74 | llvm::DenseMap<std::pair<const Object*, const clang::Type*>, |
| 75 | const Object*>; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 76 | |
Martin Brænne | d7f2009 | 2022-06-28 04:04:33 -0700 | [diff] [blame] | 77 | // Iterator refers to a pair consisting of a variable declaration and the |
| 78 | // object representing that variable. |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 79 | using const_iterator = MapType::const_iterator; |
| 80 | using value_type = MapType::value_type; |
| 81 | |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 82 | // Creates an ObjectRepository with all relevant objects for the analysis |
| 83 | // of `func`. This includes: |
| 84 | // - Variables that are declared or referenced in `func`. |
| 85 | // - Functions that have their address taken in `func`. |
| 86 | // - String literals. |
| 87 | static llvm::Expected<ObjectRepository> Create( |
| 88 | const clang::FunctionDecl* func, |
| 89 | const llvm::DenseMap<const clang::FunctionDecl*, |
| 90 | FunctionLifetimesOrError>& callee_lifetimes); |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 91 | |
| 92 | // Move-only. |
| 93 | ObjectRepository(ObjectRepository&&) = default; |
| 94 | ObjectRepository& operator=(ObjectRepository&&) = default; |
| 95 | |
| 96 | // Returns a human-readable representation of the mapping. |
| 97 | std::string DebugString() const; |
| 98 | |
| 99 | const_iterator begin() const { return object_repository_.begin(); } |
| 100 | const_iterator end() const { return object_repository_.end(); } |
| 101 | |
| 102 | // Returns the object associated with a variable or function. |
Martin Brænne | 46b5f07 | 2022-07-01 02:29:16 -0700 | [diff] [blame] | 103 | const Object* GetDeclObject(const clang::ValueDecl* decl) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 104 | |
| 105 | // Returns the object associated with a materialize temporary expression. |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 106 | const Object* GetTemporaryObject( |
| 107 | const clang::MaterializeTemporaryExpr* expr) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 108 | |
| 109 | // Returns the object representing the value of a function parameter at |
| 110 | // function entry. |
| 111 | // Note: This `Object` does not represent the parameter variable itself; |
| 112 | // use GetDeclObject() to retrieve that. We're using an `Object` here |
| 113 | // because we don't have a dedicated "value" class, but you should not |
| 114 | // use this object's identity in any way; i.e. no other `Object` in the |
| 115 | // points-to map should ever point to the object returned by this |
| 116 | // function. |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 117 | const Object* GetOriginalParameterValue( |
| 118 | const clang::ParmVarDecl* var_decl) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 119 | |
Luca Versari | 91a56ff | 2022-08-22 01:58:33 -0700 | [diff] [blame] | 120 | // Synthetizes a FunctionLifetimes that has as lifetimes the initial lifetimes |
| 121 | // of the function currently being analyzed, before any analysis runs. |
| 122 | FunctionLifetimes GetOriginalFunctionLifetimes() const; |
| 123 | |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 124 | // Returns the object associated with an argument to a CallExpr. |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 125 | const Object* GetCallExprArgumentObject(const clang::CallExpr* expr, |
| 126 | size_t arg_index) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 127 | |
Luca Versari | efeaf27 | 2023-01-16 10:19:28 -0800 | [diff] [blame] | 128 | // Returns the object associated with the return value of a CallExpr. |
| 129 | const Object* GetCallExprRetObject(const clang::Expr* expr) const; |
| 130 | |
| 131 | // Returns the "virtual" lifetimes for a given function call. |
| 132 | const FunctionLifetimes& GetCallExprVirtualLifetimes( |
| 133 | const clang::Expr* expr) const; |
| 134 | |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 135 | // Returns the object associated with the `this` argument to a CallExpr that |
| 136 | // represents a method call. Note that this object represents the `this` |
| 137 | // pointer, not the object that the method is being called on. |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 138 | const Object* GetCallExprThisPointer(const clang::CallExpr* expr) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 139 | |
| 140 | // Returns the object associated with an argument to a CXXConstructExpr. |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 141 | const Object* GetCXXConstructExprArgumentObject( |
| 142 | const clang::CXXConstructExpr* expr, size_t arg_index) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 143 | |
| 144 | // Returns the object associated with the `this` argument to a |
| 145 | // CXXConstructExpr. Note that this object represents the `this` pointer, not |
Martin Brænne | 7b0a9d1 | 2023-07-10 06:07:50 -0700 | [diff] [blame] | 146 | // the object that the method is being called on (which is represented by the |
| 147 | // object from GetResultObject()). |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 148 | const Object* GetCXXConstructExprThisPointer( |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 149 | const clang::CXXConstructExpr* expr) const; |
| 150 | |
| 151 | // Returns the object associated with, and initialized by, a constructor call |
| 152 | // (CXXConstructExpr) or a initializer list (CXXInitListExpr). Note that this |
| 153 | // represents the actual class object being initialized, not the `this` |
| 154 | // pointer to it that is passed to methods of the class, and which is |
| 155 | // represented by the object from GetCXXConstructExprThisPointer(). |
Martin Brænne | 7b0a9d1 | 2023-07-10 06:07:50 -0700 | [diff] [blame] | 156 | const Object* GetResultObject(const clang::Expr* initializer_expr) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 157 | |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 158 | // Returns the object that represents `*this`, if in a member function. |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 159 | std::optional<const Object*> GetThisObject() const { return this_object_; } |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 160 | |
| 161 | // Returns the `Object` associated with the return value of the function. |
| 162 | // Unlike the `Object`s for variables, the "return value object" is a fiction |
| 163 | // -- there is not, in general, going to be a single object associated with |
| 164 | // the return value, and it will not, in general, be possible to take the |
| 165 | // address of the return value object. It's still a useful fiction, however, |
| 166 | // because it allows us to treat return values the same way as other values. |
Martin Brænne | d7c0d0b | 2022-07-01 05:43:00 -0700 | [diff] [blame] | 167 | const Object* GetReturnObject() const { return return_object_; } |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 168 | |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 169 | // Returns an object that represents (the lifetimes of) any string literal. |
| 170 | const Object* GetStringLiteralObject() const { |
| 171 | return string_literal_object_; |
| 172 | } |
| 173 | |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 174 | // Returns the object associated with a given field in the struct |
| 175 | // represented by `struct_object`. |
Martin Brænne | af59468 | 2022-07-01 06:12:16 -0700 | [diff] [blame] | 176 | const Object* GetFieldObject(const Object* struct_object, |
Martin Brænne | 1b98ac6 | 2022-07-01 06:24:52 -0700 | [diff] [blame] | 177 | const clang::FieldDecl* field) const; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 178 | |
| 179 | // Returns the objects associated with a given field in the structs |
| 180 | // represented by `struct_objects`. |
| 181 | ObjectSet GetFieldObject(const ObjectSet& struct_objects, |
| 182 | const clang::FieldDecl* field) const; |
| 183 | |
| 184 | // Returns FieldObjects; useful for producing debugging output. |
| 185 | const FieldObjects& GetFieldObjects() const { return field_object_map_; } |
| 186 | |
| 187 | // Returns the object associated with a given base of the struct |
| 188 | // represented by `struct_object`. |
Martin Brænne | 1b98ac6 | 2022-07-01 06:24:52 -0700 | [diff] [blame] | 189 | const Object* GetBaseClassObject(const Object* struct_object, |
Martin Brænne | e08ac88 | 2022-07-01 02:24:49 -0700 | [diff] [blame] | 190 | const clang::Type* base) const; |
Martin Brænne | af59468 | 2022-07-01 06:12:16 -0700 | [diff] [blame] | 191 | const Object* GetBaseClassObject(const Object* struct_object, |
Martin Brænne | e08ac88 | 2022-07-01 02:24:49 -0700 | [diff] [blame] | 192 | const clang::QualType base) const { |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 193 | return GetBaseClassObject(struct_object, base.getTypePtr()); |
| 194 | } |
| 195 | |
| 196 | // Returns the objects associated with a given base of the structs |
| 197 | // represented by `struct_object`. |
| 198 | ObjectSet GetBaseClassObject(const ObjectSet& struct_objects, |
| 199 | const clang::Type* base) const; |
Luca Versari | 1f9fc2e | 2022-08-17 07:06:00 -0700 | [diff] [blame] | 200 | ObjectSet GetBaseClassObject(const ObjectSet& struct_objects, |
| 201 | const clang::QualType base) const { |
| 202 | return GetBaseClassObject(struct_objects, base.getTypePtr()); |
| 203 | } |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 204 | |
| 205 | // Returns BaseObjects; useful for producing debugging output. |
| 206 | const BaseObjects& GetBaseObjects() const { return base_object_map_; } |
| 207 | |
| 208 | // Returns the PointsToMap implied by variable declarations, i.e. assuming |
| 209 | // that no code has been executed yet. |
| 210 | const PointsToMap& InitialPointsToMap() const { |
| 211 | return initial_points_to_map_; |
| 212 | } |
| 213 | |
Luca Versari | 53a2f58 | 2023-01-16 10:09:29 -0800 | [diff] [blame] | 214 | // Returns the single-valued object set implied by variable declarations, i.e. |
| 215 | // assuming that no code has been executed yet. |
| 216 | const ObjectSet& InitialSingleValuedObjects() const { |
| 217 | return initial_single_valued_objects_; |
| 218 | } |
| 219 | |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 220 | // Creates an object (and its related objects, such as objects for its fields, |
| 221 | // bases or pointees) with the given lifetimes. Points-to relations will be |
| 222 | // added to the given points_to_map. |
Luca Versari | efeaf27 | 2023-01-16 10:19:28 -0800 | [diff] [blame] | 223 | // The returned Object will live as long as this ObjectRepository. |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 224 | // TODO(veluca): this is currently public just because of |
| 225 | // TransferDefaultConstructor in analyze.cc; in principle such objects |
| 226 | // could/should be created in advance. |
| 227 | const Object* CreateObject(const ObjectLifetimes& object_lifetimes, |
| 228 | PointsToMap& points_to_map); |
Luca Versari | efeaf27 | 2023-01-16 10:19:28 -0800 | [diff] [blame] | 229 | |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 230 | private: |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 231 | ObjectRepository() = default; |
| 232 | |
| 233 | // Creates an object (and related objects) for a given `type`; lifetimes of |
| 234 | // created objects are defined by the given |
| 235 | // `lifetime_factory`/`root_object_lifetime`, and the |
| 236 | // resulting points-to relations are stored in the ObjectRepository's |
| 237 | // initial_points_to_map_. |
| 238 | const Object* CreateObject(clang::QualType type, |
| 239 | Lifetime root_object_lifetime, |
| 240 | LifetimeFactory lifetime_factory); |
| 241 | |
| 242 | template <typename... Args> |
| 243 | const Object* ConstructObject(Args&&... args); |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 244 | |
Martin Brænne | d8e3214 | 2022-07-01 01:54:41 -0700 | [diff] [blame] | 245 | const Object* CloneObject(const Object* object); |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 246 | |
Martin Brænne | 46f1a57 | 2022-07-01 02:07:07 -0700 | [diff] [blame] | 247 | std::optional<const Object*> GetFieldObjectInternal( |
Martin Brænne | 1b98ac6 | 2022-07-01 06:24:52 -0700 | [diff] [blame] | 248 | const Object* struct_object, const clang::FieldDecl* field) const; |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 249 | |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 250 | // Owns all the `const Object*` members of the object repository. |
Martin Brænne | 4a1231d | 2022-07-01 01:45:44 -0700 | [diff] [blame] | 251 | llvm::SpecificBumpPtrAllocator<Object> object_allocator_; |
| 252 | |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 253 | // Map from each variable declaration to the object which it declares. |
| 254 | MapType object_repository_; |
| 255 | |
| 256 | // Map from each materialized temporary to the object which it declares. |
Martin Brænne | 8f8e4fe | 2022-07-01 01:53:28 -0700 | [diff] [blame] | 257 | llvm::DenseMap<const clang::MaterializeTemporaryExpr*, const Object*> |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 258 | temporary_objects_; |
| 259 | |
| 260 | // Map from each function parameter to an object representing its initial |
| 261 | // value at function entry. |
Martin Brænne | d8e3214 | 2022-07-01 01:54:41 -0700 | [diff] [blame] | 262 | llvm::DenseMap<const clang::ParmVarDecl*, const Object*> |
| 263 | initial_parameter_object_; |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 264 | |
Martin Brænne | 7b0a9d1 | 2023-07-10 06:07:50 -0700 | [diff] [blame] | 265 | // Map from each initializer (constructors or initializer lists) to the result |
| 266 | // object which it initializes. |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 267 | // |
| 268 | // An object in this map may occur in other places too: `object_repository_` |
| 269 | // if it is an lvalue, or `return_object_`. Or it may be a temporary in which |
| 270 | // case it is only found in this map. |
Martin Brænne | 7b0a9d1 | 2023-07-10 06:07:50 -0700 | [diff] [blame] | 271 | llvm::DenseMap<const clang::Expr*, const Object*> result_objects_; |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 272 | |
Martin Brænne | 04fb3a4 | 2022-07-01 01:52:21 -0700 | [diff] [blame] | 273 | std::optional<const Object*> this_object_; |
| 274 | const Object* return_object_; |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 275 | |
Luca Versari | 53a2f58 | 2023-01-16 10:09:29 -0800 | [diff] [blame] | 276 | ObjectSet initial_single_valued_objects_; |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 277 | |
| 278 | class VarDeclVisitor; |
| 279 | |
| 280 | PointsToMap initial_points_to_map_; |
| 281 | FieldObjects field_object_map_; |
| 282 | BaseObjects base_object_map_; |
| 283 | |
Martin Brænne | 982a115 | 2022-07-01 01:55:53 -0700 | [diff] [blame] | 284 | llvm::DenseMap<std::pair<const clang::Expr*, size_t>, const Object*> |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 285 | call_expr_args_objects_; |
| 286 | |
Martin Brænne | 982a115 | 2022-07-01 01:55:53 -0700 | [diff] [blame] | 287 | llvm::DenseMap<const clang::Expr*, const Object*> call_expr_this_pointers_; |
Martin Brænne | 5740582 | 2022-07-01 01:36:46 -0700 | [diff] [blame] | 288 | |
Luca Versari | efeaf27 | 2023-01-16 10:19:28 -0800 | [diff] [blame] | 289 | llvm::DenseMap<const clang::Expr*, const Object*> call_expr_ret_objects_; |
| 290 | |
| 291 | llvm::DenseMap<const clang::Expr*, FunctionLifetimes> |
| 292 | call_expr_virtual_lifetimes_; |
| 293 | |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 294 | const Object* string_literal_object_ = nullptr; |
Luca Versari | 91a56ff | 2022-08-22 01:58:33 -0700 | [diff] [blame] | 295 | |
Luca Versari | a12c9d5 | 2023-02-23 08:40:48 -0800 | [diff] [blame] | 296 | const clang::FunctionDecl* func_ = nullptr; |
Luca Versari | 91a56ff | 2022-08-22 01:58:33 -0700 | [diff] [blame] | 297 | |
| 298 | llvm::DenseMap<const Object*, ObjectLifetimes> initial_object_lifetimes_; |
Luca Versari | cd873a6 | 2023-01-18 13:45:08 -0800 | [diff] [blame] | 299 | |
Dmitri Gribenko | a6c5d73 | 2023-08-01 00:30:20 -0700 | [diff] [blame] | 300 | class ObjectCreator; |
Luca Versari | 99fddff | 2022-05-25 10:22:32 -0700 | [diff] [blame] | 301 | }; |
| 302 | |
| 303 | } // namespace lifetimes |
| 304 | } // namespace tidy |
| 305 | } // namespace clang |
| 306 | |
| 307 | #endif // DEVTOOLS_RUST_CC_INTEROP_LIFETIME_ANALYSIS_OBJECT_REPOSITORY_H_ |