diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -76,7 +76,7 @@
     virtual ComparisonResult compare(QualType Type, const Value &Val1,
                                      const Environment &Env1, const Value &Val2,
                                      const Environment &Env2) {
-      // FIXME: Consider adding QualType to StructValue and removing the Type
+      // FIXME: Consider adding QualType to RecordValue and removing the Type
       // argument here.
       return ComparisonResult::Unknown;
     }
@@ -300,7 +300,7 @@
   /// Returns the storage location assigned to the `this` pointee in the
   /// environment or null if the `this` pointee has no assigned storage location
   /// in the environment.
-  AggregateStorageLocation *getThisPointeeStorageLocation() const;
+  RecordStorageLocation *getThisPointeeStorageLocation() const;
 
   /// Returns the location of the result object for a record-type prvalue.
   ///
@@ -325,7 +325,7 @@
   ///
   /// Requirements:
   ///  `E` must be a prvalue of record type.
-  AggregateStorageLocation &getResultObjectLocation(const Expr &RecordPRValue);
+  RecordStorageLocation &getResultObjectLocation(const Expr &RecordPRValue);
 
   /// Returns the return value of the current function. This can be null if:
   /// - The function has a void return type
@@ -385,8 +385,8 @@
   /// non-pointer/non-reference type.
   ///
   /// If `Type` is a class, struct, or union type, calls `setValue()` to
-  /// associate the `StructValue` with its storage location
-  /// (`StructValue::getAggregateLoc()`).
+  /// associate the `RecordValue` with its storage location
+  /// (`RecordValue::getLoc()`).
   ///
   /// If `Type` is one of the following types, this function will always return
   /// a non-null pointer:
@@ -448,10 +448,10 @@
   ///
   ///  `E` must be a prvalue
   ///  `Val` must not be a `ReferenceValue`
-  ///  If `Val` is a `StructValue`, its `AggregateStorageLocation` must be the
-  ///  same as that of any `StructValue` that has already been associated with
+  ///  If `Val` is a `RecordValue`, its `RecordStorageLocation` must be the
+  ///  same as that of any `RecordValue` that has already been associated with
   ///  `E`. This is to guarantee that the result object initialized by a prvalue
-  ///  `StructValue` has a durable storage location.
+  ///  `RecordValue` has a durable storage location.
   void setValue(const Expr &E, Value &Val);
 
   /// Deprecated synonym for `setValue()`.
@@ -662,7 +662,7 @@
   StorageLocation *ReturnLoc = nullptr;
   // The storage location of the `this` pointee. Should only be null if the
   // function being analyzed is only a function and not a method.
-  AggregateStorageLocation *ThisPointeeLoc = nullptr;
+  RecordStorageLocation *ThisPointeeLoc = nullptr;
 
   // Maps from program declarations and statements to storage locations that are
   // assigned to them. Unlike the maps in `DataflowAnalysisContext`, these
@@ -681,36 +681,44 @@
 /// `CXXMemberCallExpr`, or null if none is defined in the environment.
 /// Dereferences the pointer if the member call expression was written using
 /// `->`.
-AggregateStorageLocation *
-getImplicitObjectLocation(const CXXMemberCallExpr &MCE, const Environment &Env);
+RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE,
+                                                 const Environment &Env);
 
 /// Returns the storage location for the base object of a `MemberExpr`, or null
 /// if none is defined in the environment. Dereferences the pointer if the
 /// member expression was written using `->`.
-AggregateStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
-                                                const Environment &Env);
+RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
+                                             const Environment &Env);
 
 /// Returns the fields of `RD` that are initialized by an `InitListExpr`, in the
 /// order in which they appear in `InitListExpr::inits()`.
 std::vector<FieldDecl *> getFieldsForInitListExpr(const RecordDecl *RD);
 
-/// Associates a new `StructValue` with `Loc` and returns the new value.
+/// Associates a new `RecordValue` with `Loc` and returns the new value.
 /// It is not defined whether the field values remain the same or not.
 ///
 /// This function is primarily intended for use by checks that set custom
-/// properties on `StructValue`s to model the state of these values. Such checks
-/// should avoid modifying the properties of an existing `StructValue` because
+/// properties on `RecordValue`s to model the state of these values. Such checks
+/// should avoid modifying the properties of an existing `RecordValue` because
 /// these changes would be visible to other `Environment`s that share the same
-/// `StructValue`. Instead, call `refreshStructValue()`, then set the properties
-/// on the new `StructValue` that it returns. Typical usage:
+/// `RecordValue`. Instead, call `refreshRecordValue()`, then set the properties
+/// on the new `RecordValue` that it returns. Typical usage:
 ///
-///   refreshStructValue(Loc, Env).setProperty("my_prop", MyPropValue);
-StructValue &refreshStructValue(AggregateStorageLocation &Loc,
-                                Environment &Env);
+///   refreshRecordValue(Loc, Env).setProperty("my_prop", MyPropValue);
+RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env);
 
-/// Associates a new `StructValue` with `Expr` and returns the new value.
+/// Associates a new `RecordValue` with `Expr` and returns the new value.
 /// See also documentation for the overload above.
-StructValue &refreshStructValue(const Expr &Expr, Environment &Env);
+RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env);
+
+/// Deprecated synonym for `refreshRecordValue()`.
+inline RecordValue &refreshStructValue(RecordStorageLocation &Loc,
+                                       Environment &Env) {
+  return refreshRecordValue(Loc, Env);
+}
+inline RecordValue &refreshStructValue(const Expr &Expr, Environment &Env) {
+  return refreshRecordValue(Expr, Env);
+}
 
 } // namespace dataflow
 } // namespace clang
diff --git a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h
--- a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h
@@ -22,23 +22,23 @@
 /// Copies a record (struct, class, or union) from `Src` to `Dst`.
 ///
 /// This performs a deep copy, i.e. it copies every field and recurses on
-/// fields of record type. It also copies properties from the `StructValue`
-/// associated with `Src` to the `StructValue` associated with `Dst` (if these
-/// `StructValue`s exist).
+/// fields of record type. It also copies properties from the `RecordValue`
+/// associated with `Src` to the `RecordValue` associated with `Dst` (if these
+/// `RecordValue`s exist).
 ///
-/// If there is a `StructValue` associated with `Dst` in the environment, this
-/// function creates a new `StructValue` and associates it with `Dst`; clients
-/// need to be aware of this and must not assume that the `StructValue`
+/// If there is a `RecordValue` associated with `Dst` in the environment, this
+/// function creates a new `RecordValue` and associates it with `Dst`; clients
+/// need to be aware of this and must not assume that the `RecordValue`
 /// associated with `Dst` remains the same after the call.
 ///
-/// We create a new `StructValue` rather than modifying properties on the old
-/// `StructValue` because the old `StructValue` may be shared with other
+/// We create a new `RecordValue` rather than modifying properties on the old
+/// `RecordValue` because the old `RecordValue` may be shared with other
 /// `Environment`s, and we don't want changes to properties to be visible there.
 ///
 /// Requirements:
 ///
 ///  `Src` and `Dst` must have the same canonical unqualified type.
-void copyRecord(AggregateStorageLocation &Src, AggregateStorageLocation &Dst,
+void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst,
                 Environment &Env);
 
 /// Returns whether the records `Loc1` and `Loc2` are equal.
@@ -49,8 +49,8 @@
 ///
 /// This performs a deep comparison, i.e. it compares every field and recurses
 /// on fields of record type. Fields of reference type compare equal if they
-/// refer to the same storage location. If `StructValue`s are associated with
-/// `Loc1` and `Loc2`, it also compares the properties on those `StructValue`s.
+/// refer to the same storage location. If `RecordValue`s are associated with
+/// `Loc1` and `Loc2`, it also compares the properties on those `RecordValue`s.
 ///
 /// Note on how to interpret the result:
 /// - If this returns true, the records are guaranteed to be equal at runtime.
@@ -60,12 +60,11 @@
 /// Requirements:
 ///
 ///  `Src` and `Dst` must have the same canonical unqualified type.
-bool recordsEqual(const AggregateStorageLocation &Loc1, const Environment &Env1,
-                  const AggregateStorageLocation &Loc2,
-                  const Environment &Env2);
+bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1,
+                  const RecordStorageLocation &Loc2, const Environment &Env2);
 
-inline bool recordsEqual(const AggregateStorageLocation &Loc1,
-                         const AggregateStorageLocation &Loc2,
+inline bool recordsEqual(const RecordStorageLocation &Loc1,
+                         const RecordStorageLocation &Loc2,
                          const Environment &Env) {
   return recordsEqual(Loc1, Env, Loc2, Env);
 }
diff --git a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
--- a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
+++ b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
@@ -31,7 +31,12 @@
 /// values is stored in the environment.
 class StorageLocation {
 public:
-  enum class Kind { Scalar, Aggregate };
+  enum class Kind {
+    Scalar,
+    Record,
+    // Deprecated synonym for `Record`
+    Aggregate = Record,
+  };
 
   StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) {
     assert(Type.isNull() || !Type->isReferenceType());
@@ -66,11 +71,11 @@
   }
 };
 
-/// A storage location which is subdivided into smaller storage locations that
-/// can be traced independently by abstract interpretation. For example: a
-/// struct with public members. The child map is flat, so when used for a struct
-/// or class type, all accessible members of base struct and class types are
-/// directly accesible as children of this location.
+/// A storage location for a record (struct, class, or union).
+///
+/// Contains storage locations for all modeled fields of the record (also
+/// referred to as "children"). The child map is flat, so accessible members of
+/// the base class are directly accesible as children of this location.
 ///
 /// The storage location for a field of reference type may be null. This
 /// typically occurs in one of two situations:
@@ -82,16 +87,15 @@
 /// FIXME: Currently, the storage location of unions is modelled the same way as
 /// that of structs or classes. Eventually, we need to change this modelling so
 /// that all of the members of a given union have the same storage location.
-class AggregateStorageLocation final : public StorageLocation {
+class RecordStorageLocation final : public StorageLocation {
 public:
   using FieldToLoc = llvm::DenseMap<const ValueDecl *, StorageLocation *>;
 
-  explicit AggregateStorageLocation(QualType Type)
-      : AggregateStorageLocation(Type, FieldToLoc()) {}
+  explicit RecordStorageLocation(QualType Type)
+      : RecordStorageLocation(Type, FieldToLoc()) {}
 
-  AggregateStorageLocation(QualType Type, FieldToLoc TheChildren)
-      : StorageLocation(Kind::Aggregate, Type),
-        Children(std::move(TheChildren)) {
+  RecordStorageLocation(QualType Type, FieldToLoc TheChildren)
+      : StorageLocation(Kind::Record, Type), Children(std::move(TheChildren)) {
     assert(!Type.isNull());
     assert(Type->isRecordType());
     assert([this] {
@@ -104,7 +108,7 @@
   }
 
   static bool classof(const StorageLocation *Loc) {
-    return Loc->getKind() == Kind::Aggregate;
+    return Loc->getKind() == Kind::Record;
   }
 
   /// Returns the child storage location for `D`.
@@ -133,7 +137,7 @@
 
   /// Changes the child storage location for a field `D` of reference type.
   /// All other fields cannot change their storage location and always retain
-  /// the storage location passed to the `AggregateStorageLocation` constructor.
+  /// the storage location passed to the `RecordStorageLocation` constructor.
   ///
   /// Requirements:
   ///
@@ -151,6 +155,9 @@
   FieldToLoc Children;
 };
 
+/// Deprecated synonym for `RecordStorageLocation`.
+using AggregateStorageLocation = RecordStorageLocation;
+
 } // namespace dataflow
 } // namespace clang
 
diff --git a/clang/include/clang/Analysis/FlowSensitive/Value.h b/clang/include/clang/Analysis/FlowSensitive/Value.h
--- a/clang/include/clang/Analysis/FlowSensitive/Value.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Value.h
@@ -35,7 +35,9 @@
   enum class Kind {
     Integer,
     Pointer,
-    Struct,
+    Record,
+    // Deprecated synonym for `Record`
+    Struct = Record,
 
     // TODO: Top values should not be need to be type-specific.
     TopBool,
@@ -184,13 +186,13 @@
 /// In C++, prvalues of class type serve only a limited purpose: They can only
 /// be used to initialize a result object. It is not possible to access member
 /// variables or call member functions on a prvalue of class type.
-/// Correspondingly, `StructValue` also serves only two limited purposes:
+/// Correspondingly, `RecordValue` also serves only two limited purposes:
 /// - It conveys a prvalue of class type from the place where the object is
 ///   constructed to the result object that it initializes.
 ///
 ///   When creating a prvalue of class type, we already need a storage location
 ///   for `this`, even though prvalues are otherwise not associated with storage
-///   locations. `StructValue` is therefore essentially a wrapper for a storage
+///   locations. `RecordValue` is therefore essentially a wrapper for a storage
 ///   location, which is then used to set the storage location for the result
 ///   object when we process the AST node for that result object.
 ///
@@ -198,43 +200,49 @@
 ///      MyStruct S = MyStruct(3);
 ///
 ///   In this example, `MyStruct(3) is a prvalue, which is modeled as a
-///   `StructValue` that wraps an `AbstractStorageLocation`. This
-//    `AbstractStorageLocation` is then used as the storage location for `S`.
+///   `RecordValue` that wraps a `RecordStorageLocation`. This
+//    `RecordStorageLocation` is then used as the storage location for `S`.
 ///
 /// - It allows properties to be associated with an object of class type.
 ///   Note that when doing so, you should avoid mutating the properties of an
-///   existing `StructValue` in place, as these changes would be visible to
-///   other `Environment`s that share the same `StructValue`. Instead, associate
-///   a new `StructValue` with the `AggregateStorageLocation` and set the
-///   properties on this new `StructValue`. (See also `refreshStructValue()` in
+///   existing `RecordValue` in place, as these changes would be visible to
+///   other `Environment`s that share the same `RecordValue`. Instead, associate
+///   a new `RecordValue` with the `RecordStorageLocation` and set the
+///   properties on this new `RecordValue`. (See also `refreshRecordValue()` in
 ///   DataflowEnvironment.h, which makes this easy.)
 ///   Note also that this implies that it is common for the same
-///   `AggregateStorageLocation` to be associated with different `StructValue`s
+///   `RecordStorageLocation` to be associated with different `RecordValue`s
 ///   in different environments.
-/// Over time, we may eliminate `StructValue` entirely. See also the discussion
+/// Over time, we may eliminate `RecordValue` entirely. See also the discussion
 /// here: https://reviews.llvm.org/D155204#inline-1503204
-class StructValue final : public Value {
+class RecordValue final : public Value {
 public:
-  explicit StructValue(AggregateStorageLocation &Loc)
-      : Value(Kind::Struct), Loc(Loc) {}
+  explicit RecordValue(RecordStorageLocation &Loc)
+      : Value(Kind::Record), Loc(Loc) {}
 
   static bool classof(const Value *Val) {
-    return Val->getKind() == Kind::Struct;
+    return Val->getKind() == Kind::Record;
   }
 
-  /// Returns the storage location that this `StructValue` is associated with.
-  AggregateStorageLocation &getAggregateLoc() const { return Loc; }
+  /// Returns the storage location that this `RecordValue` is associated with.
+  RecordStorageLocation &getLoc() const { return Loc; }
+
+  /// Deprecated synonym for `getLoc()`.
+  RecordStorageLocation &getAggregateLoc() const { return Loc; }
 
   /// Convenience function that returns the child storage location for `Field`.
-  /// See also the documentation for `AggregateStorageLocation::getChild()`.
+  /// See also the documentation for `RecordStorageLocation::getChild()`.
   StorageLocation *getChild(const ValueDecl &Field) const {
     return Loc.getChild(Field);
   }
 
 private:
-  AggregateStorageLocation &Loc;
+  RecordStorageLocation &Loc;
 };
 
+/// Deprecated synonym for `RecordValue`.
+using StructValue = RecordValue;
+
 raw_ostream &operator<<(raw_ostream &OS, const Value &Val);
 
 } // namespace dataflow
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -67,7 +67,7 @@
       else
         FieldLocs.insert({Field, &createStorageLocation(
                                      Field->getType().getNonReferenceType())});
-    return arena().create<AggregateStorageLocation>(Type, std::move(FieldLocs));
+    return arena().create<RecordStorageLocation>(Type, std::move(FieldLocs));
   }
   return arena().create<ScalarStorageLocation>(Type);
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -69,7 +69,7 @@
     switch (Val1.getKind()) {
     case Value::Kind::Integer:
     case Value::Kind::Pointer:
-    case Value::Kind::Struct:
+    case Value::Kind::Record:
       // FIXME: this choice intentionally introduces unsoundness to allow
       // for convergence. Once we have widening support for the
       // reference/pointer and struct built-in models, this should be
@@ -120,19 +120,19 @@
   }
 
   Value *MergedVal = nullptr;
-  if (auto *StructVal1 = dyn_cast<StructValue>(&Val1)) {
-    [[maybe_unused]] auto *StructVal2 = cast<StructValue>(&Val2);
+  if (auto *RecordVal1 = dyn_cast<RecordValue>(&Val1)) {
+    [[maybe_unused]] auto *RecordVal2 = cast<RecordValue>(&Val2);
 
     // Values to be merged are always associated with the same location in
-    // `LocToVal`. The location stored in `StructVal` should therefore also
+    // `LocToVal`. The location stored in `RecordVal` should therefore also
     // be the same.
-    assert(&StructVal1->getAggregateLoc() == &StructVal2->getAggregateLoc());
+    assert(&RecordVal1->getLoc() == &RecordVal2->getLoc());
 
-    // `StructVal1` and `StructVal2` may have different properties associated
-    // with them. Create a new `StructValue` without any properties so that we
+    // `RecordVal1` and `RecordVal2` may have different properties associated
+    // with them. Create a new `RecordValue` without any properties so that we
     // soundly approximate both values. If a particular analysis needs to merge
     // properties, it should do so in `DataflowAnalysis::merge()`.
-    MergedVal = &MergedEnv.create<StructValue>(StructVal1->getAggregateLoc());
+    MergedVal = &MergedEnv.create<RecordValue>(RecordVal1->getLoc());
   } else {
     MergedVal = MergedEnv.createValue(Type);
   }
@@ -320,7 +320,7 @@
     if (MethodDecl && !MethodDecl->isStatic()) {
       QualType ThisPointeeType = MethodDecl->getThisObjectType();
       ThisPointeeLoc =
-          &cast<StructValue>(createValue(ThisPointeeType))->getAggregateLoc();
+          &cast<RecordValue>(createValue(ThisPointeeType))->getLoc();
     }
   }
 }
@@ -337,7 +337,7 @@
     if (const Expr *Arg = MethodCall->getImplicitObjectArgument()) {
       if (!isa<CXXThisExpr>(Arg))
           Env.ThisPointeeLoc =
-              cast<AggregateStorageLocation>(getStorageLocation(*Arg));
+              cast<RecordStorageLocation>(getStorageLocation(*Arg));
       // Otherwise (when the argument is `this`), retain the current
       // environment's `ThisPointeeLoc`.
     }
@@ -634,18 +634,18 @@
   return getStorageLocationInternal(E);
 }
 
-AggregateStorageLocation *Environment::getThisPointeeStorageLocation() const {
+RecordStorageLocation *Environment::getThisPointeeStorageLocation() const {
   return ThisPointeeLoc;
 }
 
-AggregateStorageLocation &
+RecordStorageLocation &
 Environment::getResultObjectLocation(const Expr &RecordPRValue) {
   assert(RecordPRValue.getType()->isRecordType());
   assert(RecordPRValue.isPRValue());
 
   if (StorageLocation *ExistingLoc = getStorageLocationInternal(RecordPRValue))
-    return *cast<AggregateStorageLocation>(ExistingLoc);
-  auto &Loc = cast<AggregateStorageLocation>(
+    return *cast<RecordStorageLocation>(ExistingLoc);
+  auto &Loc = cast<RecordStorageLocation>(
       DACtx->getStableStorageLocation(RecordPRValue));
   setStorageLocationInternal(RecordPRValue, Loc);
   return Loc;
@@ -656,8 +656,7 @@
 }
 
 void Environment::setValue(const StorageLocation &Loc, Value &Val) {
-  assert(!isa<StructValue>(&Val) ||
-         &cast<StructValue>(&Val)->getAggregateLoc() == &Loc);
+  assert(!isa<RecordValue>(&Val) || &cast<RecordValue>(&Val)->getLoc() == &Loc);
 
   LocToVal[&Loc] = &Val;
 }
@@ -665,16 +664,16 @@
 void Environment::setValue(const Expr &E, Value &Val) {
   assert(E.isPRValue());
 
-  if (auto *StructVal = dyn_cast<StructValue>(&Val)) {
+  if (auto *RecordVal = dyn_cast<RecordValue>(&Val)) {
     if ([[maybe_unused]] auto *ExistingVal =
-            cast_or_null<StructValue>(getValue(E)))
-      assert(&ExistingVal->getAggregateLoc() == &StructVal->getAggregateLoc());
+            cast_or_null<RecordValue>(getValue(E)))
+      assert(&ExistingVal->getLoc() == &RecordVal->getLoc());
     if ([[maybe_unused]] StorageLocation *ExistingLoc =
             getStorageLocationInternal(E))
-      assert(ExistingLoc == &StructVal->getAggregateLoc());
+      assert(ExistingLoc == &RecordVal->getLoc());
     else
-      setStorageLocationInternal(E, StructVal->getAggregateLoc());
-    setValue(StructVal->getAggregateLoc(), Val);
+      setStorageLocationInternal(E, RecordVal->getLoc());
+    setValue(RecordVal->getLoc(), Val);
     return;
   }
 
@@ -774,15 +773,15 @@
                                           CreatedValuesCount)});
     }
 
-    AggregateStorageLocation &Loc =
-        arena().create<AggregateStorageLocation>(Type, std::move(FieldLocs));
-    StructValue &StructVal = create<StructValue>(Loc);
+    RecordStorageLocation &Loc =
+        arena().create<RecordStorageLocation>(Type, std::move(FieldLocs));
+    RecordValue &RecordVal = create<RecordValue>(Loc);
 
-    // As we already have a storage location for the `StructValue`, we can and
+    // As we already have a storage location for the `RecordValue`, we can and
     // should associate them in the environment.
-    setValue(Loc, StructVal);
+    setValue(Loc, RecordVal);
 
-    return &StructVal;
+    return &RecordVal;
   }
 
   return nullptr;
@@ -804,7 +803,7 @@
     return createStorageLocation(Ty);
 
   if (Ty->isRecordType())
-    return cast<StructValue>(Val)->getAggregateLoc();
+    return cast<RecordValue>(Val)->getLoc();
 
   StorageLocation &Loc = createStorageLocation(Ty);
   setValue(Loc, *Val);
@@ -850,7 +849,7 @@
     Val = createValue(Ty);
 
   if (Ty->isRecordType())
-    return cast<StructValue>(Val)->getAggregateLoc();
+    return cast<RecordValue>(Val)->getLoc();
 
   StorageLocation &Loc =
       D ? createStorageLocation(*D) : createStorageLocation(Ty);
@@ -893,32 +892,31 @@
   dump(llvm::dbgs());
 }
 
-AggregateStorageLocation *
-getImplicitObjectLocation(const CXXMemberCallExpr &MCE,
-                          const Environment &Env) {
+RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE,
+                                                 const Environment &Env) {
   Expr *ImplicitObject = MCE.getImplicitObjectArgument();
   if (ImplicitObject == nullptr)
     return nullptr;
   if (ImplicitObject->getType()->isPointerType()) {
     if (auto *Val = cast_or_null<PointerValue>(Env.getValue(*ImplicitObject)))
-      return &cast<AggregateStorageLocation>(Val->getPointeeLoc());
+      return &cast<RecordStorageLocation>(Val->getPointeeLoc());
     return nullptr;
   }
-  return cast_or_null<AggregateStorageLocation>(
+  return cast_or_null<RecordStorageLocation>(
       Env.getStorageLocation(*ImplicitObject));
 }
 
-AggregateStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
-                                                const Environment &Env) {
+RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
+                                             const Environment &Env) {
   Expr *Base = ME.getBase();
   if (Base == nullptr)
     return nullptr;
   if (ME.isArrow()) {
     if (auto *Val = cast_or_null<PointerValue>(Env.getValue(*Base)))
-      return &cast<AggregateStorageLocation>(Val->getPointeeLoc());
+      return &cast<RecordStorageLocation>(Val->getPointeeLoc());
     return nullptr;
   }
-  return cast_or_null<AggregateStorageLocation>(Env.getStorageLocation(*Base));
+  return cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Base));
 }
 
 std::vector<FieldDecl *> getFieldsForInitListExpr(const RecordDecl *RD) {
@@ -933,37 +931,36 @@
   return Fields;
 }
 
-StructValue &refreshStructValue(AggregateStorageLocation &Loc,
-                                Environment &Env) {
-  auto &NewVal = Env.create<StructValue>(Loc);
+RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env) {
+  auto &NewVal = Env.create<RecordValue>(Loc);
   Env.setValue(Loc, NewVal);
   return NewVal;
 }
 
-StructValue &refreshStructValue(const Expr &Expr, Environment &Env) {
+RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) {
   assert(Expr.getType()->isRecordType());
 
   if (Expr.isPRValue()) {
-    if (auto *ExistingVal = cast_or_null<StructValue>(Env.getValue(Expr))) {
-      auto &NewVal = Env.create<StructValue>(ExistingVal->getAggregateLoc());
+    if (auto *ExistingVal = cast_or_null<RecordValue>(Env.getValue(Expr))) {
+      auto &NewVal = Env.create<RecordValue>(ExistingVal->getLoc());
       Env.setValue(Expr, NewVal);
       return NewVal;
     }
 
-    auto &NewVal = *cast<StructValue>(Env.createValue(Expr.getType()));
+    auto &NewVal = *cast<RecordValue>(Env.createValue(Expr.getType()));
     Env.setValue(Expr, NewVal);
     return NewVal;
   }
 
-  if (auto *Loc = cast_or_null<AggregateStorageLocation>(
-          Env.getStorageLocation(Expr))) {
-    auto &NewVal = Env.create<StructValue>(*Loc);
+  if (auto *Loc =
+          cast_or_null<RecordStorageLocation>(Env.getStorageLocation(Expr))) {
+    auto &NewVal = Env.create<RecordValue>(*Loc);
     Env.setValue(*Loc, NewVal);
     return NewVal;
   }
 
-  auto &NewVal = *cast<StructValue>(Env.createValue(Expr.getType()));
-  Env.setStorageLocation(Expr, NewVal.getAggregateLoc());
+  auto &NewVal = *cast<RecordValue>(Env.createValue(Expr.getType()));
+  Env.setStorageLocation(Expr, NewVal.getLoc());
   return NewVal;
 }
 
diff --git a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
--- a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
@@ -28,8 +28,8 @@
     return "Integer";
   case Value::Kind::Pointer:
     return "Pointer";
-  case Value::Kind::Struct:
-    return "Struct";
+  case Value::Kind::Record:
+    return "Record";
   case Value::Kind::AtomicBool:
     return "AtomicBool";
   case Value::Kind::TopBool:
diff --git a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
--- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
+++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
@@ -103,9 +103,8 @@
       JOS.attributeObject(
           "pointee", [&] { dump(cast<PointerValue>(V).getPointeeLoc()); });
       break;
-    case Value::Kind::Struct:
-      for (const auto &Child :
-           cast<StructValue>(V).getAggregateLoc().children())
+    case Value::Kind::Record:
+      for (const auto &Child : cast<RecordValue>(V).getLoc().children())
         JOS.attributeObject("f:" + Child.first->getNameAsString(), [&] {
           if (Child.second)
             if (Value *Val = Env.getValue(*Child.second))
diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
--- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
@@ -256,9 +256,9 @@
 /// Creates a symbolic value for an `optional` value at an existing storage
 /// location. Uses `HasValueVal` as the symbolic value of the "has_value"
 /// property.
-StructValue &createOptionalValue(AggregateStorageLocation &Loc,
+RecordValue &createOptionalValue(RecordStorageLocation &Loc,
                                  BoolValue &HasValueVal, Environment &Env) {
-  auto &OptionalVal = Env.create<StructValue>(Loc);
+  auto &OptionalVal = Env.create<RecordValue>(Loc);
   Env.setValue(Loc, OptionalVal);
   setHasValue(OptionalVal, HasValueVal);
   return OptionalVal;
@@ -335,7 +335,7 @@
     // the check, like another optional or a boolean that influences control
     // flow.
     if (ValueLoc.getType()->isRecordType()) {
-      refreshStructValue(cast<AggregateStorageLocation>(ValueLoc), Env);
+      refreshRecordValue(cast<RecordStorageLocation>(ValueLoc), Env);
       return &ValueLoc;
     } else {
       auto *ValueVal = Env.createValue(ValueLoc.getType());
@@ -356,7 +356,7 @@
   // example:
   //
   //   void target(optional<int> oo, bool b) {
-  //     // `oo` is associated with a `StructValue` here, which we will call
+  //     // `oo` is associated with a `RecordValue` here, which we will call
   //     // `OptionalVal`.
   //
   //     // The `has_value` property is set on `OptionalVal` (but not the
@@ -532,15 +532,13 @@
   if (State.Env.getValue(*E) != nullptr)
     return;
 
-  AggregateStorageLocation *Loc = nullptr;
+  RecordStorageLocation *Loc = nullptr;
   if (E->isPRValue()) {
     Loc = &State.Env.getResultObjectLocation(*E);
   } else {
-    Loc = cast_or_null<AggregateStorageLocation>(
-        State.Env.getStorageLocation(*E));
+    Loc = cast_or_null<RecordStorageLocation>(State.Env.getStorageLocation(*E));
     if (Loc == nullptr) {
-      Loc =
-          &cast<AggregateStorageLocation>(State.Env.createStorageLocation(*E));
+      Loc = &cast<RecordStorageLocation>(State.Env.createStorageLocation(*E));
       State.Env.setStorageLocation(*E, *Loc);
     }
   }
@@ -550,7 +548,7 @@
 
 void constructOptionalValue(const Expr &E, Environment &Env,
                             BoolValue &HasValueVal) {
-  AggregateStorageLocation &Loc = Env.getResultObjectLocation(E);
+  RecordStorageLocation &Loc = Env.getResultObjectLocation(E);
   Env.setValue(E, createOptionalValue(Loc, HasValueVal, Env));
 }
 
@@ -598,7 +596,7 @@
                         LatticeTransferState &State) {
   assert(E->getNumArgs() > 0);
 
-  if (auto *Loc = cast<AggregateStorageLocation>(
+  if (auto *Loc = cast<RecordStorageLocation>(
           State.Env.getStorageLocation(*E->getArg(0)))) {
     createOptionalValue(*Loc, HasValueVal, State.Env);
 
@@ -623,8 +621,8 @@
   transferAssignment(E, State.Env.getBoolLiteralValue(false), State);
 }
 
-void transferSwap(AggregateStorageLocation *Loc1,
-                  AggregateStorageLocation *Loc2, Environment &Env) {
+void transferSwap(RecordStorageLocation *Loc1, RecordStorageLocation *Loc2,
+                  Environment &Env) {
   // We account for cases where one or both of the optionals are not modeled,
   // either lacking associated storage locations, or lacking values associated
   // to such storage locations.
@@ -661,7 +659,7 @@
                       const MatchFinder::MatchResult &,
                       LatticeTransferState &State) {
   assert(E->getNumArgs() == 1);
-  auto *OtherLoc = cast_or_null<AggregateStorageLocation>(
+  auto *OtherLoc = cast_or_null<RecordStorageLocation>(
       State.Env.getStorageLocation(*E->getArg(0)));
   transferSwap(getImplicitObjectLocation(*E, State.Env), OtherLoc, State.Env);
 }
@@ -669,9 +667,9 @@
 void transferStdSwapCall(const CallExpr *E, const MatchFinder::MatchResult &,
                          LatticeTransferState &State) {
   assert(E->getNumArgs() == 2);
-  auto *Arg0Loc = cast_or_null<AggregateStorageLocation>(
+  auto *Arg0Loc = cast_or_null<RecordStorageLocation>(
       State.Env.getStorageLocation(*E->getArg(0)));
-  auto *Arg1Loc = cast_or_null<AggregateStorageLocation>(
+  auto *Arg1Loc = cast_or_null<RecordStorageLocation>(
       State.Env.getStorageLocation(*E->getArg(1)));
   transferSwap(Arg0Loc, Arg1Loc, State.Env);
 }
@@ -848,7 +846,7 @@
           isOptionalMemberCallWithNameMatcher(hasName("emplace")),
           [](const CXXMemberCallExpr *E, const MatchFinder::MatchResult &,
              LatticeTransferState &State) {
-            if (AggregateStorageLocation *Loc =
+            if (RecordStorageLocation *Loc =
                     getImplicitObjectLocation(*E, State.Env)) {
               createOptionalValue(*Loc, State.Env.getBoolLiteralValue(true),
                                   State.Env);
@@ -860,7 +858,7 @@
           isOptionalMemberCallWithNameMatcher(hasName("reset")),
           [](const CXXMemberCallExpr *E, const MatchFinder::MatchResult &,
              LatticeTransferState &State) {
-            if (AggregateStorageLocation *Loc =
+            if (RecordStorageLocation *Loc =
                     getImplicitObjectLocation(*E, State.Env)) {
               createOptionalValue(*Loc, State.Env.getBoolLiteralValue(false),
                                   State.Env);
@@ -1032,7 +1030,7 @@
       if (isa<TopBoolValue>(CurrentHasVal))
         return &Current;
     }
-    return &createOptionalValue(cast<StructValue>(Current).getAggregateLoc(),
+    return &createOptionalValue(cast<RecordValue>(Current).getLoc(),
                                 CurrentEnv.makeTopBoolValue(), CurrentEnv);
   case ComparisonResult::Unknown:
     return nullptr;
diff --git a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp
--- a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp
+++ b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp
@@ -14,9 +14,8 @@
 
 #define DEBUG_TYPE "dataflow"
 
-void clang::dataflow::copyRecord(AggregateStorageLocation &Src,
-                                 AggregateStorageLocation &Dst,
-                                 Environment &Env) {
+void clang::dataflow::copyRecord(RecordStorageLocation &Src,
+                                 RecordStorageLocation &Dst, Environment &Env) {
   auto SrcType = Src.getType().getCanonicalType().getUnqualifiedType();
   auto DstType = Dst.getType().getCanonicalType().getUnqualifiedType();
 
@@ -43,8 +42,8 @@
            (SrcFieldLoc != nullptr && DstFieldLoc != nullptr));
 
     if (Field->getType()->isRecordType()) {
-      copyRecord(cast<AggregateStorageLocation>(*SrcFieldLoc),
-                 cast<AggregateStorageLocation>(*DstFieldLoc), Env);
+      copyRecord(cast<RecordStorageLocation>(*SrcFieldLoc),
+                 cast<RecordStorageLocation>(*DstFieldLoc), Env);
     } else if (Field->getType()->isReferenceType()) {
       Dst.setChild(*Field, SrcFieldLoc);
     } else {
@@ -55,10 +54,10 @@
     }
   }
 
-  StructValue *SrcVal = cast_or_null<StructValue>(Env.getValue(Src));
-  StructValue *DstVal = cast_or_null<StructValue>(Env.getValue(Dst));
+  RecordValue *SrcVal = cast_or_null<RecordValue>(Env.getValue(Src));
+  RecordValue *DstVal = cast_or_null<RecordValue>(Env.getValue(Dst));
 
-  DstVal = &Env.create<StructValue>(Dst);
+  DstVal = &Env.create<RecordValue>(Dst);
   Env.setValue(Dst, *DstVal);
 
   if (SrcVal == nullptr)
@@ -70,9 +69,9 @@
   }
 }
 
-bool clang::dataflow::recordsEqual(const AggregateStorageLocation &Loc1,
+bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1,
                                    const Environment &Env1,
-                                   const AggregateStorageLocation &Loc2,
+                                   const RecordStorageLocation &Loc2,
                                    const Environment &Env2) {
   LLVM_DEBUG({
     if (Loc2.getType().getCanonicalType().getUnqualifiedType() !=
@@ -91,8 +90,8 @@
            (FieldLoc1 != nullptr && FieldLoc2 != nullptr));
 
     if (Field->getType()->isRecordType()) {
-      if (!recordsEqual(cast<AggregateStorageLocation>(*FieldLoc1), Env1,
-                        cast<AggregateStorageLocation>(*FieldLoc2), Env2))
+      if (!recordsEqual(cast<RecordStorageLocation>(*FieldLoc1), Env1,
+                        cast<RecordStorageLocation>(*FieldLoc2), Env2))
         return false;
     } else if (Field->getType()->isReferenceType()) {
       if (FieldLoc1 != FieldLoc2)
@@ -104,10 +103,10 @@
 
   llvm::StringMap<Value *> Props1, Props2;
 
-  if (StructValue *Val1 = cast_or_null<StructValue>(Env1.getValue(Loc1)))
+  if (RecordValue *Val1 = cast_or_null<RecordValue>(Env1.getValue(Loc1)))
     for (const auto &[Name, Value] : Val1->properties())
       Props1[Name] = Value;
-  if (StructValue *Val2 = cast_or_null<StructValue>(Env2.getValue(Loc2)))
+  if (RecordValue *Val2 = cast_or_null<RecordValue>(Env2.getValue(Loc2)))
     for (const auto &[Name, Value] : Val2->properties())
       Props2[Name] = Value;
 
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -435,7 +435,7 @@
       }
     }
 
-    AggregateStorageLocation *BaseLoc = getBaseObjectLocation(*S, Env);
+    RecordStorageLocation *BaseLoc = getBaseObjectLocation(*S, Env);
     if (BaseLoc == nullptr)
       return;
 
@@ -464,7 +464,7 @@
       assert(Arg != nullptr);
 
       auto *ArgLoc =
-          cast_or_null<AggregateStorageLocation>(Env.getStorageLocation(*Arg));
+          cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Arg));
       if (ArgLoc == nullptr)
         return;
 
@@ -472,9 +472,9 @@
         if (Value *Val = Env.getValue(*ArgLoc))
           Env.setValue(*S, *Val);
       } else {
-        auto &Val = *cast<StructValue>(Env.createValue(S->getType()));
+        auto &Val = *cast<RecordValue>(Env.createValue(S->getType()));
         Env.setValue(*S, Val);
-        copyRecord(*ArgLoc, Val.getAggregateLoc(), Env);
+        copyRecord(*ArgLoc, Val.getLoc(), Env);
       }
       return;
     }
@@ -483,9 +483,8 @@
     // of records, and we currently can't create values for arrays. So check if
     // we've got a record type.
     if (S->getType()->isRecordType()) {
-      auto &InitialVal = *cast<StructValue>(Env.createValue(S->getType()));
-      copyRecord(InitialVal.getAggregateLoc(), Env.getResultObjectLocation(*S),
-                 Env);
+      auto &InitialVal = *cast<RecordValue>(Env.createValue(S->getType()));
+      copyRecord(InitialVal.getLoc(), Env.getResultObjectLocation(*S), Env);
     }
 
     transferInlineCall(S, ConstructorDecl);
@@ -511,9 +510,9 @@
         return;
 
       auto *LocSrc =
-          cast_or_null<AggregateStorageLocation>(Env.getStorageLocation(*Arg1));
+          cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Arg1));
       auto *LocDst =
-          cast_or_null<AggregateStorageLocation>(Env.getStorageLocation(*Arg0));
+          cast_or_null<RecordStorageLocation>(Env.getStorageLocation(*Arg0));
 
       if (LocSrc != nullptr && LocDst != nullptr) {
         copyRecord(*LocSrc, *LocDst, Env);
@@ -573,8 +572,8 @@
     if (SubExprVal == nullptr)
       return;
 
-    if (StructValue *StructVal = dyn_cast<StructValue>(SubExprVal)) {
-      Env.setStorageLocation(*S, StructVal->getAggregateLoc());
+    if (RecordValue *RecordVal = dyn_cast<RecordValue>(SubExprVal)) {
+      Env.setStorageLocation(*S, RecordVal->getLoc());
       return;
     }
 
@@ -638,14 +637,13 @@
     }
 
     auto &Loc =
-        Env.getDataflowAnalysisContext()
-            .arena()
-            .create<AggregateStorageLocation>(Type, std::move(FieldLocs));
-    StructValue &StructVal = Env.create<StructValue>(Loc);
+        Env.getDataflowAnalysisContext().arena().create<RecordStorageLocation>(
+            Type, std::move(FieldLocs));
+    RecordValue &RecordVal = Env.create<RecordValue>(Loc);
 
-    Env.setValue(Loc, StructVal);
+    Env.setValue(Loc, RecordVal);
 
-    Env.setValue(*S, StructVal);
+    Env.setValue(*S, RecordVal);
 
     // FIXME: Implement array initialization.
   }
diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -376,7 +376,7 @@
   assert(InitExpr != nullptr);
 
   const FieldDecl *Member = nullptr;
-  AggregateStorageLocation *ParentLoc = &ThisLoc;
+  RecordStorageLocation *ParentLoc = &ThisLoc;
   StorageLocation *MemberLoc = nullptr;
   if (Init->isMemberInitializer()) {
     Member = Init->getMember();
@@ -387,7 +387,7 @@
     MemberLoc = &ThisLoc;
     for (const auto *I : IndirectField->chain()) {
       Member = cast<FieldDecl>(I);
-      ParentLoc = cast<AggregateStorageLocation>(MemberLoc);
+      ParentLoc = cast<RecordStorageLocation>(MemberLoc);
       MemberLoc = ParentLoc->getChild(*Member);
     }
   }
@@ -398,8 +398,8 @@
   // to simply use `Environment::createObject()` here, the same way that we do
   // this in `TransferVisitor::VisitInitListExpr()`. However, this would require
   // us to be able to build a list of fields that we then use to initialize an
-  // `AggregateStorageLocation` -- and the problem is that, when we get here,
-  // the `AggregateStorageLocation` already exists. We should explore if there's
+  // `RecordStorageLocation` -- and the problem is that, when we get here,
+  // the `RecordStorageLocation` already exists. We should explore if there's
   // anything that we can do to change this.
   if (Member->getType()->isReferenceType()) {
     auto *InitExprLoc = Env.getStorageLocation(*InitExpr);
@@ -409,13 +409,13 @@
     ParentLoc->setChild(*Member, InitExprLoc);
   } else if (auto *InitExprVal = Env.getValue(*InitExpr)) {
     if (Member->getType()->isRecordType()) {
-      auto *InitValStruct = cast<StructValue>(InitExprVal);
+      auto *InitValStruct = cast<RecordValue>(InitExprVal);
       // FIXME: Rather than performing a copy here, we should really be
       // initializing the field in place. This would require us to propagate the
       // storage location of the field to the AST node that creates the
-      // `StructValue`.
-      copyRecord(InitValStruct->getAggregateLoc(),
-                 *cast<AggregateStorageLocation>(MemberLoc), Env);
+      // `RecordValue`.
+      copyRecord(InitValStruct->getLoc(),
+                 *cast<RecordStorageLocation>(MemberLoc), Env);
     } else {
       Env.setValue(*MemberLoc, *InitExprVal);
     }
diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -91,7 +91,7 @@
   // Verify that the struct and the field (`R`) with first appearance of the
   // type is created successfully.
   Environment Env(DAContext, *Fun);
-  StructValue *SVal = cast<StructValue>(Env.createValue(Ty));
+  RecordValue *SVal = cast<RecordValue>(Env.createValue(Ty));
   PointerValue *PV = cast_or_null<PointerValue>(getFieldValue(SVal, *R, Env));
   EXPECT_THAT(PV, NotNull());
 }
@@ -171,7 +171,7 @@
   // Verify that the `X` field of `S` is populated when analyzing the
   // constructor, even though it is not referenced directly in the constructor.
   Environment Env(DAContext, *Constructor);
-  auto *Val = cast<StructValue>(Env.createValue(QTy));
+  auto *Val = cast<RecordValue>(Env.createValue(QTy));
   EXPECT_THAT(getFieldValue(Val, *XDecl, Env), NotNull());
 }
 
@@ -215,8 +215,8 @@
   // Verify the global variable is populated when we analyze `Target`.
   Environment Env(DAContext, *Fun);
   const auto *GlobalLoc =
-      cast<AggregateStorageLocation>(Env.getStorageLocation(*GlobalDecl));
-  const auto *GlobalVal = cast<StructValue>(Env.getValue(*GlobalLoc));
+      cast<RecordStorageLocation>(Env.getStorageLocation(*GlobalDecl));
+  const auto *GlobalVal = cast<RecordValue>(Env.getValue(*GlobalLoc));
   auto *BarVal = getFieldValue(GlobalVal, *BarDecl, Env);
   EXPECT_TRUE(isa<IntegerValue>(BarVal));
 }
@@ -253,7 +253,7 @@
   EXPECT_THAT(Env.getValue(*Var), NotNull());
 }
 
-TEST_F(EnvironmentTest, RefreshStructValue) {
+TEST_F(EnvironmentTest, RefreshRecordValue) {
   using namespace ast_matchers;
 
   std::string Code = R"cc(
@@ -280,7 +280,7 @@
 
   Environment Env(DAContext, *Target);
   EXPECT_THAT(Env.getStorageLocation(*DRE), IsNull());
-  refreshStructValue(*DRE, Env);
+  refreshRecordValue(*DRE, Env);
   EXPECT_THAT(Env.getStorageLocation(*DRE), NotNull());
 }
 
diff --git a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp
--- a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp
@@ -58,10 +58,10 @@
         const ValueDecl *InnerDecl = findValueDecl(ASTCtx, "inner");
         const ValueDecl *InnerIntDecl = findValueDecl(ASTCtx, "inner_int");
 
-        auto &S1 = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "s1");
-        auto &S2 = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "s2");
-        auto &Inner1 = *cast<AggregateStorageLocation>(S1.getChild(*InnerDecl));
-        auto &Inner2 = *cast<AggregateStorageLocation>(S2.getChild(*InnerDecl));
+        auto &S1 = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s1");
+        auto &S2 = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s2");
+        auto &Inner1 = *cast<RecordStorageLocation>(S1.getChild(*InnerDecl));
+        auto &Inner2 = *cast<RecordStorageLocation>(S2.getChild(*InnerDecl));
 
         EXPECT_NE(getFieldValue(&S1, *OuterIntDecl, Env),
                   getFieldValue(&S2, *OuterIntDecl, Env));
@@ -69,8 +69,8 @@
         EXPECT_NE(getFieldValue(&Inner1, *InnerIntDecl, Env),
                   getFieldValue(&Inner2, *InnerIntDecl, Env));
 
-        auto *S1Val = cast<StructValue>(Env.getValue(S1));
-        auto *S2Val = cast<StructValue>(Env.getValue(S2));
+        auto *S1Val = cast<RecordValue>(Env.getValue(S1));
+        auto *S2Val = cast<RecordValue>(Env.getValue(S2));
         EXPECT_NE(S1Val, S2Val);
 
         S1Val->setProperty("prop", Env.getBoolLiteralValue(true));
@@ -83,8 +83,8 @@
         EXPECT_EQ(getFieldValue(&Inner1, *InnerIntDecl, Env),
                   getFieldValue(&Inner2, *InnerIntDecl, Env));
 
-        S1Val = cast<StructValue>(Env.getValue(S1));
-        S2Val = cast<StructValue>(Env.getValue(S2));
+        S1Val = cast<RecordValue>(Env.getValue(S1));
+        S2Val = cast<RecordValue>(Env.getValue(S2));
         EXPECT_NE(S1Val, S2Val);
 
         EXPECT_EQ(S2Val->getProperty("prop"), &Env.getBoolLiteralValue(true));
@@ -118,11 +118,11 @@
         const ValueDecl *InnerDecl = findValueDecl(ASTCtx, "inner");
         const ValueDecl *InnerIntDecl = findValueDecl(ASTCtx, "inner_int");
 
-        auto &S1 = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "s1");
-        auto &S2 = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "s2");
-        auto &Inner2 = *cast<AggregateStorageLocation>(S2.getChild(*InnerDecl));
+        auto &S1 = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s1");
+        auto &S2 = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s2");
+        auto &Inner2 = *cast<RecordStorageLocation>(S2.getChild(*InnerDecl));
 
-        cast<StructValue>(Env.getValue(S1))
+        cast<RecordValue>(Env.getValue(S1))
             ->setProperty("prop", Env.getBoolLiteralValue(true));
 
         // Strategy: Create two equal records, then verify each of the various
@@ -163,14 +163,14 @@
         EXPECT_TRUE(recordsEqual(S1, S2, Env));
 
         // S1 and S2 have the same property with different values.
-        cast<StructValue>(Env.getValue(S2))
+        cast<RecordValue>(Env.getValue(S2))
             ->setProperty("prop", Env.getBoolLiteralValue(false));
         EXPECT_FALSE(recordsEqual(S1, S2, Env));
         copyRecord(S1, S2, Env);
         EXPECT_TRUE(recordsEqual(S1, S2, Env));
 
         // S1 has a property that S2 doesn't have.
-        cast<StructValue>(Env.getValue(S1))
+        cast<RecordValue>(Env.getValue(S1))
             ->setProperty("other_prop", Env.getBoolLiteralValue(false));
         EXPECT_FALSE(recordsEqual(S1, S2, Env));
         // We modified S1 this time, so need to copy back the other way.
@@ -178,7 +178,7 @@
         EXPECT_TRUE(recordsEqual(S1, S2, Env));
 
         // S2 has a property that S1 doesn't have.
-        cast<StructValue>(Env.getValue(S2))
+        cast<RecordValue>(Env.getValue(S2))
             ->setProperty("other_prop", Env.getBoolLiteralValue(false));
         EXPECT_FALSE(recordsEqual(S1, S2, Env));
         copyRecord(S1, S2, Env);
@@ -186,9 +186,9 @@
 
         // S1 and S2 have the same number of properties, but with different
         // names.
-        cast<StructValue>(Env.getValue(S1))
+        cast<RecordValue>(Env.getValue(S1))
             ->setProperty("prop1", Env.getBoolLiteralValue(false));
-        cast<StructValue>(Env.getValue(S2))
+        cast<RecordValue>(Env.getValue(S2))
             ->setProperty("prop2", Env.getBoolLiteralValue(false));
         EXPECT_FALSE(recordsEqual(S1, S2, Env));
       });
@@ -215,8 +215,8 @@
         Environment Env = getEnvironmentAtAnnotation(Results, "p").fork();
 
         const ValueDecl *IDecl = findValueDecl(ASTCtx, "i");
-        auto &A = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "a");
-        auto &B = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "b");
+        auto &A = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "a");
+        auto &B = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "b");
 
         EXPECT_NE(Env.getValue(*A.getChild(*IDecl)),
                   Env.getValue(*B.getChild(*IDecl)));
diff --git a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h
--- a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h
+++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h
@@ -453,7 +453,7 @@
 
 /// Returns the value of a `Field` on the record referenced by `Loc.`
 /// Returns null if `Loc` is null.
-inline Value *getFieldValue(const AggregateStorageLocation *Loc,
+inline Value *getFieldValue(const RecordStorageLocation *Loc,
                             const ValueDecl &Field, const Environment &Env) {
   if (Loc == nullptr)
     return nullptr;
@@ -469,7 +469,7 @@
 /// Note: This function currently does not use the `Env` parameter, but it will
 /// soon be needed to look up the `Value` when `setChild()` changes to return a
 /// `StorageLocation *`.
-inline Value *getFieldValue(const StructValue *Struct, const ValueDecl &Field,
+inline Value *getFieldValue(const RecordValue *Struct, const ValueDecl &Field,
                             const Environment &Env) {
   if (Struct == nullptr)
     return nullptr;
diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -164,10 +164,10 @@
         auto *FooValue = dyn_cast_or_null<PointerValue>(Env.getValue(*FooDecl));
         ASSERT_THAT(FooValue, NotNull());
 
-        EXPECT_TRUE(isa<AggregateStorageLocation>(FooValue->getPointeeLoc()));
+        EXPECT_TRUE(isa<RecordStorageLocation>(FooValue->getPointeeLoc()));
         auto *FooPointeeValue = Env.getValue(FooValue->getPointeeLoc());
         ASSERT_THAT(FooPointeeValue, NotNull());
-        EXPECT_TRUE(isa<StructValue>(FooPointeeValue));
+        EXPECT_TRUE(isa<RecordValue>(FooPointeeValue));
       });
 }
 
@@ -215,9 +215,9 @@
         ASSERT_THAT(UnmodeledDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         const auto *UnmodeledLoc = FooLoc->getChild(*UnmodeledDecl);
-        ASSERT_TRUE(isa<AggregateStorageLocation>(UnmodeledLoc));
+        ASSERT_TRUE(isa<RecordStorageLocation>(UnmodeledLoc));
         EXPECT_THAT(Env.getValue(*UnmodeledLoc), IsNull());
 
         const ValueDecl *ZabDecl = findValueDecl(ASTCtx, "Zab");
@@ -262,7 +262,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         EXPECT_TRUE(isa<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env)));
       });
 }
@@ -305,7 +305,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         EXPECT_TRUE(isa<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env)));
       });
 }
@@ -369,7 +369,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         EXPECT_TRUE(isa<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env)));
       });
 }
@@ -396,10 +396,10 @@
         ASSERT_THAT(FooDecl, NotNull());
 
         const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl);
-        ASSERT_TRUE(isa_and_nonnull<AggregateStorageLocation>(FooLoc));
+        ASSERT_TRUE(isa_and_nonnull<RecordStorageLocation>(FooLoc));
 
         const Value *FooReferentVal = Env.getValue(*FooLoc);
-        EXPECT_TRUE(isa_and_nonnull<StructValue>(FooReferentVal));
+        EXPECT_TRUE(isa_and_nonnull<RecordValue>(FooReferentVal));
       });
 }
 
@@ -483,20 +483,20 @@
     ASSERT_THAT(BazPtrDecl, NotNull());
 
     const auto &FooLoc =
-        *cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+        *cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
 
     const auto &BarLoc =
-        *cast<AggregateStorageLocation>(FooLoc.getChild(*BarDecl));
+        *cast<RecordStorageLocation>(FooLoc.getChild(*BarDecl));
 
     const auto &FooReferentLoc =
-        *cast<AggregateStorageLocation>(BarLoc.getChild(*FooRefDecl));
+        *cast<RecordStorageLocation>(BarLoc.getChild(*FooRefDecl));
     EXPECT_THAT(Env.getValue(FooReferentLoc), NotNull());
     EXPECT_THAT(getFieldValue(&FooReferentLoc, *BarDecl, Env), IsNull());
 
     const auto &FooPtrVal =
         *cast<PointerValue>(getFieldValue(&BarLoc, *FooPtrDecl, Env));
     const auto &FooPtrPointeeLoc =
-        cast<AggregateStorageLocation>(FooPtrVal.getPointeeLoc());
+        cast<RecordStorageLocation>(FooPtrVal.getPointeeLoc());
     EXPECT_THAT(Env.getValue(FooPtrPointeeLoc), NotNull());
     EXPECT_THAT(getFieldValue(&FooPtrPointeeLoc, *BarDecl, Env), IsNull());
 
@@ -535,10 +535,10 @@
 
         const PointerValue *FooVal = cast<PointerValue>(Env.getValue(*FooLoc));
         const StorageLocation &FooPointeeLoc = FooVal->getPointeeLoc();
-        EXPECT_TRUE(isa<AggregateStorageLocation>(&FooPointeeLoc));
+        EXPECT_TRUE(isa<RecordStorageLocation>(&FooPointeeLoc));
 
         const Value *FooPointeeVal = Env.getValue(FooPointeeLoc);
-        EXPECT_TRUE(isa_and_nonnull<StructValue>(FooPointeeVal));
+        EXPECT_TRUE(isa_and_nonnull<RecordValue>(FooPointeeVal));
       });
 }
 
@@ -638,19 +638,19 @@
             *cast<ScalarStorageLocation>(Env.getStorageLocation(*FooDecl));
         const auto &FooVal = *cast<PointerValue>(Env.getValue(FooLoc));
         const auto &FooPointeeVal =
-            *cast<StructValue>(Env.getValue(FooVal.getPointeeLoc()));
+            *cast<RecordValue>(Env.getValue(FooVal.getPointeeLoc()));
 
         const auto &BarVal =
             *cast<PointerValue>(getFieldValue(&FooPointeeVal, *BarDecl, Env));
         const auto &BarPointeeVal =
-            *cast<StructValue>(Env.getValue(BarVal.getPointeeLoc()));
+            *cast<RecordValue>(Env.getValue(BarVal.getPointeeLoc()));
 
         EXPECT_THAT(getFieldValue(&BarPointeeVal, *FooRefDecl, Env), NotNull());
 
         const auto &FooPtrVal = *cast<PointerValue>(
             getFieldValue(&BarPointeeVal, *FooPtrDecl, Env));
         const auto &FooPtrPointeeLoc =
-            cast<AggregateStorageLocation>(FooPtrVal.getPointeeLoc());
+            cast<RecordStorageLocation>(FooPtrVal.getPointeeLoc());
         EXPECT_THAT(Env.getValue(FooPtrPointeeLoc), IsNull());
 
         EXPECT_THAT(getFieldValue(&BarPointeeVal, *BazRefDecl, Env), NotNull());
@@ -1044,7 +1044,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         EXPECT_TRUE(isa<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env)));
       });
 }
@@ -1069,10 +1069,10 @@
         ASSERT_THAT(FooDecl, NotNull());
 
         const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl);
-        ASSERT_TRUE(isa_and_nonnull<AggregateStorageLocation>(FooLoc));
+        ASSERT_TRUE(isa_and_nonnull<RecordStorageLocation>(FooLoc));
 
         const Value *FooReferentVal = Env.getValue(*FooLoc);
-        EXPECT_TRUE(isa_and_nonnull<StructValue>(FooReferentVal));
+        EXPECT_TRUE(isa_and_nonnull<RecordValue>(FooReferentVal));
       });
 }
 
@@ -1100,10 +1100,10 @@
 
         const PointerValue *FooVal = cast<PointerValue>(Env.getValue(*FooLoc));
         const StorageLocation &FooPointeeLoc = FooVal->getPointeeLoc();
-        EXPECT_TRUE(isa<AggregateStorageLocation>(&FooPointeeLoc));
+        EXPECT_TRUE(isa<RecordStorageLocation>(&FooPointeeLoc));
 
         const Value *FooPointeeVal = Env.getValue(FooPointeeLoc);
-        EXPECT_TRUE(isa_and_nonnull<StructValue>(FooPointeeVal));
+        EXPECT_TRUE(isa_and_nonnull<RecordValue>(FooPointeeVal));
       });
 }
 
@@ -1142,7 +1142,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         const auto *BarVal =
             cast<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env));
 
@@ -1273,7 +1273,7 @@
         ASSERT_THAT(APublicDecl, NotNull());
 
         ASSERT_TRUE(
-            isa<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl)));
+            isa<RecordStorageLocation>(Env.getStorageLocation(*FooDecl)));
       });
 }
 
@@ -1304,9 +1304,9 @@
   ASSERT_THAT(BarDecl, NotNull());
 
   const auto &FooLoc =
-      *cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
-  const auto &FooVal = *cast<StructValue>(Env.getValue(FooLoc));
-  EXPECT_EQ(&FooVal.getAggregateLoc(), &FooLoc);
+      *cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
+  const auto &FooVal = *cast<RecordValue>(Env.getValue(FooLoc));
+  EXPECT_EQ(&FooVal.getLoc(), &FooLoc);
 }
 
 TEST(TransferTest, DerivedBaseMemberStructDefault) {
@@ -1383,7 +1383,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         const auto *BarVal =
             cast<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env));
 
@@ -1473,7 +1473,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         const auto *BarReferentVal =
             cast<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env));
 
@@ -1543,8 +1543,8 @@
         ASSERT_THAT(BazDecl, NotNull());
 
         const auto *QuxLoc =
-            cast<AggregateStorageLocation>(ThisLoc->getChild(*QuxDecl));
-        EXPECT_THAT(dyn_cast<StructValue>(Env.getValue(*QuxLoc)), NotNull());
+            cast<RecordStorageLocation>(ThisLoc->getChild(*QuxDecl));
+        EXPECT_THAT(dyn_cast<RecordValue>(Env.getValue(*QuxLoc)), NotNull());
 
         const auto *BazVal =
             cast<IntegerValue>(getFieldValue(QuxLoc, *BazDecl, Env));
@@ -1614,8 +1614,8 @@
         ASSERT_THAT(BazDecl, NotNull());
 
         const auto *QuxLoc =
-            cast<AggregateStorageLocation>(ThisLoc->getChild(*QuxDecl));
-        EXPECT_THAT(dyn_cast<StructValue>(Env.getValue(*QuxLoc)), NotNull());
+            cast<RecordStorageLocation>(ThisLoc->getChild(*QuxDecl));
+        EXPECT_THAT(dyn_cast<RecordValue>(Env.getValue(*QuxLoc)), NotNull());
 
         const auto *BazVal =
             cast<IntegerValue>(getFieldValue(QuxLoc, *BazDecl, Env));
@@ -1897,7 +1897,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         EXPECT_TRUE(isa<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env)));
       });
 }
@@ -1930,7 +1930,7 @@
         ASSERT_THAT(BarDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         EXPECT_TRUE(isa<IntegerValue>(getFieldValue(FooLoc, *BarDecl, Env)));
       },
       LangStandard::lang_cxx14);
@@ -1970,9 +1970,9 @@
           const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1");
 
           const auto *FooLoc1 =
-              cast<AggregateStorageLocation>(Env1.getStorageLocation(*FooDecl));
+              cast<RecordStorageLocation>(Env1.getStorageLocation(*FooDecl));
           const auto *BarLoc1 =
-              cast<AggregateStorageLocation>(Env1.getStorageLocation(*BarDecl));
+              cast<RecordStorageLocation>(Env1.getStorageLocation(*BarDecl));
           EXPECT_FALSE(recordsEqual(*FooLoc1, *BarLoc1, Env1));
 
           const auto *FooBazVal1 =
@@ -1987,12 +1987,12 @@
           const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2");
 
           const auto *FooLoc2 =
-              cast<AggregateStorageLocation>(Env2.getStorageLocation(*FooDecl));
+              cast<RecordStorageLocation>(Env2.getStorageLocation(*FooDecl));
           const auto *BarLoc2 =
-              cast<AggregateStorageLocation>(Env2.getStorageLocation(*BarDecl));
+              cast<RecordStorageLocation>(Env2.getStorageLocation(*BarDecl));
 
-          const auto *FooVal2 = cast<StructValue>(Env2.getValue(*FooLoc2));
-          const auto *BarVal2 = cast<StructValue>(Env2.getValue(*BarLoc2));
+          const auto *FooVal2 = cast<RecordValue>(Env2.getValue(*FooLoc2));
+          const auto *BarVal2 = cast<RecordValue>(Env2.getValue(*BarLoc2));
           EXPECT_NE(FooVal2, BarVal2);
 
           EXPECT_TRUE(recordsEqual(*FooLoc2, *BarLoc2, Env2));
@@ -2009,9 +2009,9 @@
           const Environment &Env3 = getEnvironmentAtAnnotation(Results, "p3");
 
           const auto *FooLoc3 =
-              cast<AggregateStorageLocation>(Env3.getStorageLocation(*FooDecl));
+              cast<RecordStorageLocation>(Env3.getStorageLocation(*FooDecl));
           const auto *BarLoc3 =
-              cast<AggregateStorageLocation>(Env3.getStorageLocation(*BarDecl));
+              cast<RecordStorageLocation>(Env3.getStorageLocation(*BarDecl));
           EXPECT_FALSE(recordsEqual(*FooLoc3, *BarLoc3, Env3));
 
           const auto *FooBazVal3 =
@@ -2076,13 +2076,13 @@
               getEnvironmentAtAnnotation(Results, "after_copy");
 
           const auto *FooLoc =
-              cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+              cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
           const auto *BarLoc =
-              cast<AggregateStorageLocation>(Env.getStorageLocation(*BarDecl));
+              cast<RecordStorageLocation>(Env.getStorageLocation(*BarDecl));
 
-          // `Foo` and `Bar` have different `StructValue`s associated with them.
-          const auto *FooVal = cast<StructValue>(Env.getValue(*FooLoc));
-          const auto *BarVal = cast<StructValue>(Env.getValue(*BarLoc));
+          // `Foo` and `Bar` have different `RecordValue`s associated with them.
+          const auto *FooVal = cast<RecordValue>(Env.getValue(*FooLoc));
+          const auto *BarVal = cast<RecordValue>(Env.getValue(*BarLoc));
           EXPECT_NE(FooVal, BarVal);
 
           // But the records compare equal.
@@ -2102,9 +2102,9 @@
               getEnvironmentAtAnnotation(Results, "after_update");
 
           const auto *FooLoc =
-              cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+              cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
           const auto *BarLoc =
-              cast<AggregateStorageLocation>(Env.getStorageLocation(*BarDecl));
+              cast<RecordStorageLocation>(Env.getStorageLocation(*BarDecl));
 
           EXPECT_FALSE(recordsEqual(*FooLoc, *BarLoc, Env));
 
@@ -2149,9 +2149,9 @@
         ASSERT_THAT(BazDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         const auto *BarLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*BarDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*BarDecl));
         EXPECT_TRUE(recordsEqual(*FooLoc, *BarLoc, Env));
 
         const auto *FooBazVal =
@@ -2192,9 +2192,9 @@
         ASSERT_THAT(BazDecl, NotNull());
 
         const auto *FooLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*FooDecl));
         const auto *BarLoc =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*BarDecl));
+            cast<RecordStorageLocation>(Env.getStorageLocation(*BarDecl));
         EXPECT_TRUE(recordsEqual(*FooLoc, *BarLoc, Env));
 
         const auto *FooBazVal =
@@ -2226,9 +2226,9 @@
         const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz");
 
         const auto &FooLoc =
-            getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "Foo");
+            getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "Foo");
         const auto &BarLoc =
-            getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "Bar");
+            getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "Bar");
 
         const auto *FooBazVal =
             cast<IntegerValue>(getFieldValue(&FooLoc, *BazDecl, Env));
@@ -2300,14 +2300,14 @@
         ASSERT_THAT(BazDecl, NotNull());
 
         const auto *FooLoc1 =
-            cast<AggregateStorageLocation>(Env1.getStorageLocation(*FooDecl));
+            cast<RecordStorageLocation>(Env1.getStorageLocation(*FooDecl));
         const auto *BarLoc1 =
-            cast<AggregateStorageLocation>(Env1.getStorageLocation(*BarDecl));
+            cast<RecordStorageLocation>(Env1.getStorageLocation(*BarDecl));
 
         EXPECT_FALSE(recordsEqual(*FooLoc1, *BarLoc1, Env1));
 
-        const auto *FooVal1 = cast<StructValue>(Env1.getValue(*FooLoc1));
-        const auto *BarVal1 = cast<StructValue>(Env1.getValue(*BarLoc1));
+        const auto *FooVal1 = cast<RecordValue>(Env1.getValue(*FooLoc1));
+        const auto *BarVal1 = cast<RecordValue>(Env1.getValue(*BarLoc1));
         EXPECT_NE(FooVal1, BarVal1);
 
         const auto *FooBazVal1 =
@@ -2317,8 +2317,8 @@
         EXPECT_NE(FooBazVal1, BarBazVal1);
 
         const auto *FooLoc2 =
-            cast<AggregateStorageLocation>(Env2.getStorageLocation(*FooDecl));
-        const auto *FooVal2 = cast<StructValue>(Env2.getValue(*FooLoc2));
+            cast<RecordStorageLocation>(Env2.getStorageLocation(*FooDecl));
+        const auto *FooVal2 = cast<RecordValue>(Env2.getValue(*FooLoc2));
         EXPECT_NE(FooVal2, BarVal1);
         EXPECT_TRUE(recordsEqual(*FooLoc2, Env2, *BarLoc1, Env1));
 
@@ -2357,7 +2357,7 @@
         const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz");
         ASSERT_THAT(BazDecl, NotNull());
 
-        const auto &FooVal = *cast<StructValue>(Env.getValue(*FooDecl));
+        const auto &FooVal = *cast<RecordValue>(Env.getValue(*FooDecl));
         const auto *BarVal = cast<IntegerValue>(Env.getValue(*BarDecl));
         EXPECT_EQ(BarVal, getFieldValue(&FooVal, *BazDecl, Env));
       });
@@ -2530,7 +2530,7 @@
         EXPECT_THAT(Env.getValue(BarPointeeLoc), IsNull());
 
         const StorageLocation &BazPointeeLoc = BazVal->getPointeeLoc();
-        EXPECT_TRUE(isa<AggregateStorageLocation>(BazPointeeLoc));
+        EXPECT_TRUE(isa<RecordStorageLocation>(BazPointeeLoc));
         EXPECT_THAT(Env.getValue(BazPointeeLoc), IsNull());
 
         const StorageLocation &NullPointeeLoc = NullVal->getPointeeLoc();
@@ -2716,10 +2716,10 @@
         const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz");
         ASSERT_THAT(BazDecl, NotNull());
 
-        const auto *FooVal = cast<StructValue>(Env.getValue(*FooDecl));
-        const auto *BarVal = cast<StructValue>(Env.getValue(*BarDecl));
+        const auto *FooVal = cast<RecordValue>(Env.getValue(*FooDecl));
+        const auto *BarVal = cast<RecordValue>(Env.getValue(*BarDecl));
 
-        const auto *BazVal = dyn_cast<StructValue>(Env.getValue(*BazDecl));
+        const auto *BazVal = dyn_cast<RecordValue>(Env.getValue(*BazDecl));
         ASSERT_THAT(BazVal, NotNull());
 
         EXPECT_NE(BazVal, FooVal);
@@ -2857,11 +2857,11 @@
           const auto *BarArgVal = cast<IntegerValue>(Env.getValue(*BarArgDecl));
           const auto *QuxArgVal = cast<IntegerValue>(Env.getValue(*QuxArgDecl));
 
-          const auto *QuuxVal = cast<StructValue>(Env.getValue(*QuuxDecl));
+          const auto *QuuxVal = cast<RecordValue>(Env.getValue(*QuuxDecl));
           ASSERT_THAT(QuuxVal, NotNull());
 
           const auto *BazVal =
-              cast<StructValue>(getFieldValue(QuuxVal, *BazDecl, Env));
+              cast<RecordValue>(getFieldValue(QuuxVal, *BazDecl, Env));
           ASSERT_THAT(BazVal, NotNull());
 
           EXPECT_EQ(getFieldValue(QuuxVal, *BarDecl, Env), BarArgVal);
@@ -2871,7 +2871,7 @@
           // Check that fields initialized in an initializer list are always
           // modeled in other instances of the same type.
           const auto &OtherBVal =
-              getValueForDecl<StructValue>(ASTCtx, Env, "OtherB");
+              getValueForDecl<RecordValue>(ASTCtx, Env, "OtherB");
           EXPECT_THAT(OtherBVal.getChild(*BarDecl), NotNull());
           EXPECT_THAT(OtherBVal.getChild(*BazDecl), NotNull());
           EXPECT_THAT(OtherBVal.getChild(*QuxDecl), NotNull());
@@ -2899,7 +2899,7 @@
         const ValueDecl *RefFieldDecl = findValueDecl(ASTCtx, "RefField");
 
         auto &ILoc = getLocForDecl<StorageLocation>(ASTCtx, Env, "i");
-        auto &SLoc = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "s");
+        auto &SLoc = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s");
 
         EXPECT_EQ(SLoc.getChild(*RefFieldDecl), &ILoc);
       });
@@ -2926,7 +2926,7 @@
         const ValueDecl *I1FieldDecl = findValueDecl(ASTCtx, "i1");
         const ValueDecl *I2FieldDecl = findValueDecl(ASTCtx, "i2");
 
-        auto &SLoc = getLocForDecl<AggregateStorageLocation>(ASTCtx, Env, "s");
+        auto &SLoc = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "s");
 
         auto &IValue = getValueForDecl<IntegerValue>(ASTCtx, Env, "i");
         auto &I1Value =
@@ -2972,7 +2972,7 @@
         }
         ASSERT_THAT(FooDecl, NotNull());
 
-        const auto *BazLoc = dyn_cast_or_null<AggregateStorageLocation>(
+        const auto *BazLoc = dyn_cast_or_null<RecordStorageLocation>(
             Env.getStorageLocation(*BazDecl));
         ASSERT_THAT(BazLoc, NotNull());
         ASSERT_THAT(Env.getValue(*BazLoc), NotNull());
@@ -3540,7 +3540,7 @@
 
         const auto *BarVal = cast<IntegerValue>(Env.getValue(*BarDecl));
 
-        const auto *A2Val = cast<StructValue>(Env.getValue(*A2Decl));
+        const auto *A2Val = cast<RecordValue>(Env.getValue(*A2Decl));
         EXPECT_EQ(getFieldValue(A2Val, *FooDecl, Env), BarVal);
       });
 }
@@ -5449,7 +5449,7 @@
     void target() {
       Outer *p = new Outer;
       // Access the fields to make sure the analysis actually generates children
-      // for them in the `AggregateStorageLoc` and `StructValue`.
+      // for them in the `RecordStorageLocation` and `RecordValue`.
       p->OuterField.InnerField;
       // [[after_new]]
     }
@@ -5466,9 +5466,9 @@
 
         auto &P = getValueForDecl<PointerValue>(ASTCtx, Env, "p");
 
-        auto &OuterLoc = cast<AggregateStorageLocation>(P.getPointeeLoc());
+        auto &OuterLoc = cast<RecordStorageLocation>(P.getPointeeLoc());
         auto &OuterFieldLoc =
-            *cast<AggregateStorageLocation>(OuterLoc.getChild(*OuterField));
+            *cast<RecordStorageLocation>(OuterLoc.getChild(*OuterField));
         auto &InnerFieldLoc = *OuterFieldLoc.getChild(*InnerField);
 
         // Values for the struct and all fields exist after the new.
@@ -5574,9 +5574,8 @@
         const IndirectFieldDecl *IndirectField =
             findIndirectFieldDecl(ASTCtx, "b");
 
-        auto *S =
-            cast<AggregateStorageLocation>(Env.getStorageLocation(*SDecl));
-        auto &AnonStruct = *cast<AggregateStorageLocation>(
+        auto *S = cast<RecordStorageLocation>(Env.getStorageLocation(*SDecl));
+        auto &AnonStruct = *cast<RecordStorageLocation>(
             S->getChild(*cast<ValueDecl>(IndirectField->chain().front())));
 
         auto *B = cast<BoolValue>(getFieldValue(&AnonStruct, *BDecl, Env));
@@ -5606,8 +5605,8 @@
             findIndirectFieldDecl(ASTCtx, "b");
 
         auto *ThisLoc =
-            cast<AggregateStorageLocation>(Env.getThisPointeeStorageLocation());
-        auto &AnonStruct = *cast<AggregateStorageLocation>(ThisLoc->getChild(
+            cast<RecordStorageLocation>(Env.getThisPointeeStorageLocation());
+        auto &AnonStruct = *cast<RecordStorageLocation>(ThisLoc->getChild(
             *cast<ValueDecl>(IndirectField->chain().front())));
 
         auto *B = cast<BoolValue>(getFieldValue(&AnonStruct, *BDecl, Env));
@@ -5639,8 +5638,8 @@
             findIndirectFieldDecl(ASTCtx, "i");
 
         auto *ThisLoc =
-            cast<AggregateStorageLocation>(Env.getThisPointeeStorageLocation());
-        auto &AnonStruct = *cast<AggregateStorageLocation>(ThisLoc->getChild(
+            cast<RecordStorageLocation>(Env.getThisPointeeStorageLocation());
+        auto &AnonStruct = *cast<RecordStorageLocation>(ThisLoc->getChild(
             *cast<ValueDecl>(IndirectField->chain().front())));
 
         ASSERT_EQ(AnonStruct.getChild(*IDecl),
diff --git a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
--- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -415,7 +415,7 @@
     if (const auto *E = selectFirst<CXXConstructExpr>(
             "call", match(cxxConstructExpr(HasSpecialBoolType).bind("call"), *S,
                           getASTContext()))) {
-      cast<StructValue>(Env.getValue(*E))
+      cast<RecordValue>(Env.getValue(*E))
           ->setProperty("is_set", Env.getBoolLiteralValue(false));
     } else if (const auto *E = selectFirst<CXXMemberCallExpr>(
                    "call", match(cxxMemberCallExpr(callee(cxxMethodDecl(ofClass(
@@ -423,9 +423,9 @@
                                      .bind("call"),
                                  *S, getASTContext()))) {
       auto &ObjectLoc =
-          *cast<AggregateStorageLocation>(getImplicitObjectLocation(*E, Env));
+          *cast<RecordStorageLocation>(getImplicitObjectLocation(*E, Env));
 
-      refreshStructValue(ObjectLoc, Env)
+      refreshRecordValue(ObjectLoc, Env)
           .setProperty("is_set", Env.getBoolLiteralValue(true));
     }
   }
@@ -572,7 +572,7 @@
         *S, getASTContext());
     if (const auto *E = selectFirst<CXXConstructExpr>(
             "construct", Matches)) {
-      cast<StructValue>(Env.getValue(*E))
+      cast<RecordValue>(Env.getValue(*E))
           ->setProperty("has_value", Env.getBoolLiteralValue(false));
     } else if (const auto *E =
                    selectFirst<CXXOperatorCallExpr>("operator", Matches)) {
@@ -580,7 +580,7 @@
       auto *Object = E->getArg(0);
       assert(Object != nullptr);
 
-      refreshStructValue(*Object, Env)
+      refreshRecordValue(*Object, Env)
           .setProperty("has_value", Env.getBoolLiteralValue(true));
     }
   }