Make various ObjectRepository methods return pointers.

PiperOrigin-RevId: 458449285
diff --git a/lifetime_analysis/analyze.cc b/lifetime_analysis/analyze.cc
index b98b068..7392dcc 100644
--- a/lifetime_analysis/analyze.cc
+++ b/lifetime_analysis/analyze.cc
@@ -168,11 +168,11 @@
   }
 
   if (object_repository.GetThisObject().has_value()) {
-    var_objects.insert(*object_repository.GetThisObject());
+    var_objects.insert(**object_repository.GetThisObject());
     lines.push_back(absl::StrFormat(
         "\"%s%s\"[label=%s]", name_prefix,
-        object_repository.GetThisObject()->DebugString(),
-        VariableLabel("this", *object_repository.GetThisObject())));
+        (*object_repository.GetThisObject())->DebugString(),
+        VariableLabel("this", **object_repository.GetThisObject())));
   }
 
   for (auto [decl, object] : object_repository) {
@@ -182,11 +182,11 @@
         VariableLabel(decl->getNameAsString(), *object)));
   }
 
-  var_objects.insert(object_repository.GetReturnObject());
+  var_objects.insert(*object_repository.GetReturnObject());
   lines.push_back(absl::StrFormat(
       "\"%s%s\"[label=%s]", name_prefix,
-      object_repository.GetReturnObject().DebugString(),
-      VariableLabel("return", object_repository.GetReturnObject())));
+      object_repository.GetReturnObject()->DebugString(),
+      VariableLabel("return", *object_repository.GetReturnObject())));
 
   for (Object object : all_objects) {
     if (!var_objects.contains(object)) {
@@ -486,7 +486,7 @@
     }
     if (!IsInitExprInitializingARecordObject(init_expr)) {
       TransferInitializer(
-          *object_repository.GetFieldObject(this_object.value(), field),
+          *object_repository.GetFieldObject(*this_object.value(), field),
           field->getType(), object_repository, init_expr, points_to_map);
     }
   }
@@ -714,11 +714,12 @@
     ObjectRepository& object_repository, PointsToMap& points_to_map) {
   assert(ctor->isDefaulted() && ctor->isDefaultConstructor());
 
-  std::optional<Object> this_object_maybe = object_repository.GetThisObject();
+  std::optional<const Object*> this_object_maybe =
+      object_repository.GetThisObject();
   if (!this_object_maybe.has_value()) {
     llvm::report_fatal_error("didn't find `this` object for constructor");
   }
-  Object this_object = *this_object_maybe;
+  const Object* this_object = *this_object_maybe;
 
   const clang::CXXRecordDecl* record = ctor->getParent();
   for (const CXXBaseSpecifier& base : record->bases()) {
@@ -727,7 +728,7 @@
       if (const clang::CXXConstructorDecl* base_ctor =
               GetDefaultConstructor(base_record)) {
         const Object* base_this_object =
-            object_repository.GetBaseClassObject(this_object, base.getType());
+            object_repository.GetBaseClassObject(*this_object, base.getType());
         if (llvm::Error err = TransferDefaultConstructor(
                 base_ctor, *base_this_object, object_repository, points_to_map,
                 callee_lifetimes)) {
@@ -742,7 +743,7 @@
       if (const clang::CXXConstructorDecl* field_ctor =
               GetDefaultConstructor(field_record)) {
         const Object* field_this_object =
-            object_repository.GetFieldObject(this_object, field);
+            object_repository.GetFieldObject(*this_object, field);
         if (llvm::Error err = TransferDefaultConstructor(
                 field_ctor, *field_this_object, object_repository,
                 points_to_map, callee_lifetimes)) {
@@ -983,7 +984,7 @@
   for (unsigned i = 0; i < func->getNumParams(); ++i) {
     const clang::ParmVarDecl* param = func->getParamDecl(i);
     FindLifetimeSubstitutions(
-        object_repository.GetOriginalParameterValue(param), param->getType(),
+        *object_repository.GetOriginalParameterValue(param), param->getType(),
         points_to_map, object_repository, result.GetParamLifetimes(i), subst);
   }
 
@@ -1009,8 +1010,8 @@
   }
 
   FindLifetimeSubstitutions(
-      object_repository.GetReturnObject(), func->getReturnType(), points_to_map,
-      object_repository, result.GetReturnLifetimes(), subst);
+      *object_repository.GetReturnObject(), func->getReturnType(),
+      points_to_map, object_repository, result.GetReturnLifetimes(), subst);
 
   result.SubstituteLifetimes(subst);
 
diff --git a/lifetime_analysis/lifetime_analysis.cc b/lifetime_analysis/lifetime_analysis.cc
index d572c0f..ff654cf 100644
--- a/lifetime_analysis/lifetime_analysis.cc
+++ b/lifetime_analysis/lifetime_analysis.cc
@@ -405,7 +405,7 @@
   if (auto iter = lifetime_to_object_set.find(Lifetime::Static());
       iter != lifetime_to_object_set.end()) {
     for (const Object& object : iter->second) {
-      Object pointer = object_repository.CreateStaticObject(
+      const Object* pointer = object_repository.CreateStaticObject(
           ast_context.getPointerType(object.Type()));
       points_to_map.ExtendPointerPointsToSet(pointer, {object});
     }
@@ -421,9 +421,9 @@
   // Step 3: Determine points-to set for the return value.
   if (return_lifetimes.HasLifetimes()) {
     if (IsInitExprInitializingARecordObject(call)) {
-      Object init_object = object_repository.GetInitializedObject(call);
+      const Object* init_object = object_repository.GetInitializedObject(call);
       PropagateLifetimesToPointees(
-          {init_object}, call->getType(), return_lifetimes, points_to_map,
+          *init_object, call->getType(), return_lifetimes, points_to_map,
           object_repository, lifetime_to_object_set, ast_context);
     } else {
       ObjectSet rval_points_to;
@@ -511,7 +511,7 @@
 
 std::optional<std::string> TransferStmtVisitor::VisitStringLiteral(
     const clang::StringLiteral* strlit) {
-  Object obj = object_repository_.CreateStaticObject(strlit->getType());
+  const Object* obj = object_repository_.CreateStaticObject(strlit->getType());
   points_to_map_.SetExprObjectSet(strlit, {obj});
   return std::nullopt;
 }
@@ -797,8 +797,9 @@
       return std::nullopt;
     }
     // The object set for each field should be pointing to the initializers.
-    Object init_object = object_repository_.GetInitializedObject(init_list);
-    TransferInitializer(init_object, init_list->getType(), object_repository_,
+    const Object* init_object =
+        object_repository_.GetInitializedObject(init_list);
+    TransferInitializer(*init_object, init_list->getType(), object_repository_,
                         init_list, points_to_map_);
   } else {
     // If the InitListExpr is not initializing a record object, we assume it's
@@ -822,7 +823,8 @@
 
 std::optional<std::string> TransferStmtVisitor::VisitMaterializeTemporaryExpr(
     const clang::MaterializeTemporaryExpr* temporary_expr) {
-  Object temp_object = object_repository_.GetTemporaryObject(temporary_expr);
+  const Object* temp_object =
+      object_repository_.GetTemporaryObject(temporary_expr);
   points_to_map_.SetExprObjectSet(temporary_expr, {temp_object});
   return std::nullopt;
 }
@@ -862,7 +864,7 @@
 
 std::optional<std::string> TransferStmtVisitor::VisitCXXThisExpr(
     const clang::CXXThisExpr* this_expr) {
-  std::optional<Object> this_object = object_repository_.GetThisObject();
+  std::optional<const Object*> this_object = object_repository_.GetThisObject();
   assert(this_object.has_value());
   points_to_map_.SetExprObjectSet(this_expr, ObjectSet{this_object.value()});
   return std::nullopt;
@@ -887,7 +889,7 @@
       fn_params.push_back(FunctionParameter{
           clang::dyn_cast<clang::CXXMethodDecl>(callee)->getThisType(),
           callee_lifetimes.GetThisLifetimes(),
-          object_repository.GetCallExprThisPointer(call)});
+          *object_repository.GetCallExprThisPointer(call)});
     }
 
     // Handle all other arguments.
@@ -895,7 +897,7 @@
       fn_params.push_back(FunctionParameter{
           callee->getParamDecl(i - 1)->getType().getCanonicalType(),
           callee_lifetimes.GetParamLifetimes(i - 1),
-          object_repository.GetCallExprArgumentObject(call, i)});
+          *object_repository.GetCallExprArgumentObject(call, i)});
     }
   } else {
     // We check <= instead of == because of default arguments.
@@ -905,7 +907,7 @@
       fn_params.push_back(FunctionParameter{
           callee->getParamDecl(i)->getType().getCanonicalType(),
           callee_lifetimes.GetParamLifetimes(i),
-          object_repository.GetCallExprArgumentObject(call, i)});
+          *object_repository.GetCallExprArgumentObject(call, i)});
     }
     if (const auto* member_call =
             clang::dyn_cast<clang::CXXMemberCallExpr>(call)) {
@@ -925,7 +927,7 @@
       fn_params.push_back(
           FunctionParameter{member_call->getMethodDecl()->getThisType(),
                             callee_lifetimes.GetThisLifetimes(),
-                            object_repository.GetCallExprThisPointer(call)});
+                            *object_repository.GetCallExprThisPointer(call)});
     }
   }
   return fn_params;
@@ -1021,7 +1023,7 @@
       // PointsToSet more than needed, as dataflow analysis relies on points-to
       // sets never shrinking.
       TransferInitializer(
-          object_repository_.GetCallExprArgumentObject(call, i),
+          *object_repository_.GetCallExprArgumentObject(call, i),
           callee->getParamDecl(is_member_operator ? i - 1 : i)->getType(),
           object_repository_, call->getArg(i), points_to_map_);
     }
@@ -1078,10 +1080,11 @@
   assert(construct_expr->getNumArgs() <= constructor->getNumParams());
 
   for (size_t i = 0; i < construct_expr->getNumArgs(); i++) {
-    TransferInitializer(
-        object_repository_.GetCXXConstructExprArgumentObject(construct_expr, i),
-        construct_expr->getArg(i)->getType(), object_repository_,
-        construct_expr->getArg(i), points_to_map_);
+    TransferInitializer(*object_repository_.GetCXXConstructExprArgumentObject(
+                            construct_expr, i),
+                        construct_expr->getArg(i)->getType(),
+                        object_repository_, construct_expr->getArg(i),
+                        points_to_map_);
   }
 
   // Handle the `this` parameter, which should point to the object getting
@@ -1098,14 +1101,14 @@
         constructor->getParamDecl(i)->getType().getCanonicalType();
     fn_params.push_back(
         FunctionParameter{arg_type, callee_lifetimes.GetParamLifetimes(i),
-                          object_repository_.GetCXXConstructExprArgumentObject(
+                          *object_repository_.GetCXXConstructExprArgumentObject(
                               construct_expr, i)});
   }
 
   clang::QualType type = constructor->getThisType();
   fn_params.push_back(FunctionParameter{
       type, callee_lifetimes.GetThisLifetimes(),
-      object_repository_.GetCXXConstructExprThisPointer(construct_expr)});
+      *object_repository_.GetCXXConstructExprThisPointer(construct_expr)});
 
   TransferLifetimesForCall(
       construct_expr, fn_params,
diff --git a/lifetime_analysis/object_repository.cc b/lifetime_analysis/object_repository.cc
index 80221d6..5f9b0ea 100644
--- a/lifetime_analysis/object_repository.cc
+++ b/lifetime_analysis/object_repository.cc
@@ -426,18 +426,20 @@
       }
 
       if (init->getMember() && init->getMember()->getType()->isRecordType()) {
-        std::optional<Object> this_object = object_repository_.GetThisObject();
+        std::optional<const Object*> this_object =
+            object_repository_.GetThisObject();
         assert(this_object.has_value());
 
         const Object* field_object =
-            object_repository_.GetFieldObject(*this_object, init->getMember());
+            object_repository_.GetFieldObject(**this_object, init->getMember());
         PropagateInitializedObject(init_expr, field_object);
       } else if (init->getBaseClass()) {
-        std::optional<Object> this_object = object_repository_.GetThisObject();
+        std::optional<const Object*> this_object =
+            object_repository_.GetThisObject();
         assert(this_object.has_value());
 
         const Object* base_object = object_repository_.GetBaseClassObject(
-            *this_object, init->getBaseClass());
+            **this_object, init->getBaseClass());
         PropagateInitializedObject(init_expr, base_object);
       }
 
@@ -537,7 +539,7 @@
   return iter->second;
 }
 
-Object ObjectRepository::GetTemporaryObject(
+const Object* ObjectRepository::GetTemporaryObject(
     const clang::MaterializeTemporaryExpr* expr) const {
   auto iter = temporary_objects_.find(expr);
   if (iter == temporary_objects_.end()) {
@@ -546,10 +548,10 @@
     llvm::errs() << "\n" << DebugString();
     llvm::report_fatal_error("Didn't find object for temporary expression");
   }
-  return *iter->second;
+  return iter->second;
 }
 
-Object ObjectRepository::GetOriginalParameterValue(
+const Object* ObjectRepository::GetOriginalParameterValue(
     const clang::ParmVarDecl* var_decl) const {
   auto iter = initial_parameter_object_.find(var_decl);
   if (iter == initial_parameter_object_.end()) {
@@ -558,11 +560,11 @@
     llvm::errs() << "\n" << DebugString();
     llvm::report_fatal_error("Didn't find caller object for parameter");
   }
-  return *iter->second;
+  return iter->second;
 }
 
-Object ObjectRepository::GetCallExprArgumentObject(const clang::CallExpr* expr,
-                                                   size_t arg_index) const {
+const Object* ObjectRepository::GetCallExprArgumentObject(
+    const clang::CallExpr* expr, size_t arg_index) const {
   auto iter = call_expr_args_objects_.find(std::make_pair(expr, arg_index));
   if (iter == call_expr_args_objects_.end()) {
     llvm::errs() << "Didn't find object for argument " << arg_index
@@ -571,10 +573,10 @@
     llvm::errs() << "\n" << DebugString();
     llvm::report_fatal_error("Didn't find object for argument");
   }
-  return *iter->second;
+  return iter->second;
 }
 
-Object ObjectRepository::GetCallExprThisPointer(
+const Object* ObjectRepository::GetCallExprThisPointer(
     const clang::CallExpr* expr) const {
   auto iter = call_expr_this_pointers_.find(expr);
   if (iter == call_expr_this_pointers_.end()) {
@@ -583,10 +585,10 @@
     llvm::errs() << "\n" << DebugString();
     llvm::report_fatal_error("Didn't find `this` object for call");
   }
-  return *iter->second;
+  return iter->second;
 }
 
-Object ObjectRepository::GetCXXConstructExprArgumentObject(
+const Object* ObjectRepository::GetCXXConstructExprArgumentObject(
     const clang::CXXConstructExpr* expr, size_t arg_index) const {
   auto iter = call_expr_args_objects_.find(std::make_pair(expr, arg_index));
   if (iter == call_expr_args_objects_.end()) {
@@ -597,10 +599,10 @@
     llvm::report_fatal_error(
         "Didn't find object for argument of constructor call");
   }
-  return *iter->second;
+  return iter->second;
 }
 
-Object ObjectRepository::GetCXXConstructExprThisPointer(
+const Object* ObjectRepository::GetCXXConstructExprThisPointer(
     const clang::CXXConstructExpr* expr) const {
   auto iter = call_expr_this_pointers_.find(expr);
   if (iter == call_expr_this_pointers_.end()) {
@@ -609,10 +611,10 @@
     llvm::errs() << "\n" << DebugString();
     llvm::report_fatal_error("Didn't find `this` object for constructor");
   }
-  return *iter->second;
+  return iter->second;
 }
 
-Object ObjectRepository::GetInitializedObject(
+const Object* ObjectRepository::GetInitializedObject(
     const clang::Expr* initializer_expr) const {
   assert(clang::isa<clang::CXXConstructExpr>(initializer_expr) ||
          clang::isa<clang::InitListExpr>(initializer_expr) ||
@@ -625,7 +627,7 @@
     llvm::errs() << "\n" << DebugString();
     llvm::report_fatal_error("Didn't find object for initializer");
   }
-  return *iter->second;
+  return iter->second;
 }
 
 ObjectRepository::ObjectValueType ObjectRepository::GetObjectValueType(
@@ -686,10 +688,10 @@
   return ret;
 }
 
-Object ObjectRepository::CreateStaticObject(clang::QualType type) {
+const Object* ObjectRepository::CreateStaticObject(clang::QualType type) {
   auto iter = static_objects_.find(type);
   if (iter != static_objects_.end()) {
-    return *iter->second;
+    return iter->second;
   }
 
   const Object* object = CreateObject(Lifetime::Static(), type);
@@ -699,7 +701,7 @@
       *object, type, [](const clang::Expr*) { return Lifetime::Static(); },
       true);
 
-  return *object;
+  return object;
 }
 
 void ObjectRepository::CreateObjects(Object root_object, clang::QualType type,
diff --git a/lifetime_analysis/object_repository.h b/lifetime_analysis/object_repository.h
index ec3d7bf..159503a 100644
--- a/lifetime_analysis/object_repository.h
+++ b/lifetime_analysis/object_repository.h
@@ -100,7 +100,8 @@
   const Object* GetDeclObject(const clang::ValueDecl* decl) const;
 
   // Returns the object associated with a materialize temporary expression.
-  Object GetTemporaryObject(const clang::MaterializeTemporaryExpr* expr) const;
+  const Object* GetTemporaryObject(
+      const clang::MaterializeTemporaryExpr* expr) const;
 
   // Returns the object representing the value of a function parameter at
   // function entry.
@@ -110,26 +111,27 @@
   // use this object's identity in any way; i.e. no other `Object` in the
   // points-to map should ever point to the object returned by this
   // function.
-  Object GetOriginalParameterValue(const clang::ParmVarDecl* var_decl) const;
+  const Object* GetOriginalParameterValue(
+      const clang::ParmVarDecl* var_decl) const;
 
   // Returns the object associated with an argument to a CallExpr.
-  Object GetCallExprArgumentObject(const clang::CallExpr* expr,
-                                   size_t arg_index) const;
+  const Object* GetCallExprArgumentObject(const clang::CallExpr* expr,
+                                          size_t arg_index) const;
 
   // Returns the object associated with the `this` argument to a CallExpr that
   // represents a method call. Note that this object represents the `this`
   // pointer, not the object that the method is being called on.
-  Object GetCallExprThisPointer(const clang::CallExpr* expr) const;
+  const Object* GetCallExprThisPointer(const clang::CallExpr* expr) const;
 
   // Returns the object associated with an argument to a CXXConstructExpr.
-  Object GetCXXConstructExprArgumentObject(const clang::CXXConstructExpr* expr,
-                                           size_t arg_index) const;
+  const Object* GetCXXConstructExprArgumentObject(
+      const clang::CXXConstructExpr* expr, size_t arg_index) const;
 
   // Returns the object associated with the `this` argument to a
   // CXXConstructExpr. Note that this object represents the `this` pointer, not
   // the object that the method is being called on (which is represnted by the
   // object from GetInitializedObject()).
-  Object GetCXXConstructExprThisPointer(
+  const Object* GetCXXConstructExprThisPointer(
       const clang::CXXConstructExpr* expr) const;
 
   // Returns the object associated with, and initialized by, a constructor call
@@ -137,19 +139,13 @@
   // represents the actual class object being initialized, not the `this`
   // pointer to it that is passed to methods of the class, and which is
   // represented by the object from GetCXXConstructExprThisPointer().
-  Object GetInitializedObject(const clang::Expr* initializer_expr) const;
+  const Object* GetInitializedObject(const clang::Expr* initializer_expr) const;
 
   // Returns what kind of values the given object represents.
   ObjectValueType GetObjectValueType(Object object) const;
 
   // Returns the object that represents `*this`, if in a member function.
-  std::optional<Object> GetThisObject() const {
-    if (this_object_) {
-      return **this_object_;
-    } else {
-      return std::nullopt;
-    }
-  }
+  std::optional<const Object*> GetThisObject() const { return this_object_; }
 
   // Returns the `Object` associated with the return value of the function.
   // Unlike the `Object`s for variables, the "return value object" is a fiction
@@ -157,7 +153,7 @@
   // the return value, and it will not, in general, be possible to take the
   // address of the return value object. It's still a useful fiction, however,
   // because it allows us to treat return values the same way as other values.
-  Object GetReturnObject() const { return *return_object_; }
+  const Object* GetReturnObject() const { return return_object_; }
 
   // Returns the object associated with a given field in the struct
   // represented by `struct_object`.
@@ -201,7 +197,7 @@
   // returns the same object. This is to guarantee that the number of objects
   // used in the analysis is bounded and that therefore the lattice is finite
   // and the analysis terminates.
-  Object CreateStaticObject(clang::QualType type);
+  const Object* CreateStaticObject(clang::QualType type);
 
  private:
   void CreateObjects(Object root_object, clang::QualType type,