[clang] 9ecdbe3 - [clang][dataflow] Rename `AggregateStorageLocation` to `RecordStorageLocation` and `StructValue` to `RecordValue`.

Martin Braenne via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 1 13:29:49 PDT 2023


Author: Martin Braenne
Date: 2023-08-01T20:29:40Z
New Revision: 9ecdbe3855a8048989a507ff8d470aee4d407589

URL: https://github.com/llvm/llvm-project/commit/9ecdbe3855a8048989a507ff8d470aee4d407589
DIFF: https://github.com/llvm/llvm-project/commit/9ecdbe3855a8048989a507ff8d470aee4d407589.diff

LOG: [clang][dataflow] Rename `AggregateStorageLocation` to `RecordStorageLocation` and `StructValue` to `RecordValue`.

- Both of these constructs are used to represent structs, classes, and unions;
  Clang uses the collective term "record" for these.

- The term "aggregate" in `AggregateStorageLocation` implies that, at some
  point, the intention may have been to use it also for arrays, but it don't
  think it's possible to use it for arrays. Records and arrays are very
  different and therefore need to be modeled differently. Records have a fixed
  set of named fields, which can have different type; arrays have a variable
  number of elements, but they all have the same type.

- Futhermore, "aggregate" has a very specific meaning in C++
  (https://en.cppreference.com/w/cpp/language/aggregate_initialization).
  Aggregates of class type may not have any user-declared or inherited
  constructors, no private or protected non-static data members, no virtual
  member functions, and so on, but we use `AggregateStorageLocations` to model all objects of class type.

In addition, for consistency, we also rename the following:

- `getAggregateLoc()` (in `RecordValue`, formerly known as `StructValue`) to
  simply `getLoc()`.

- `refreshStructValue()` to `refreshRecordValue()`

We keep the old names around as deprecated synonyms to enable clients to be migrated to the new names.

Reviewed By: ymandel, xazax.hun

Differential Revision: https://reviews.llvm.org/D156788

Added: 
    

Modified: 
    clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
    clang/include/clang/Analysis/FlowSensitive/RecordOps.h
    clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
    clang/include/clang/Analysis/FlowSensitive/Value.h
    clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
    clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
    clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
    clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
    clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
    clang/lib/Analysis/FlowSensitive/RecordOps.cpp
    clang/lib/Analysis/FlowSensitive/Transfer.cpp
    clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
    clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
    clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp
    clang/unittests/Analysis/FlowSensitive/TestingSupport.h
    clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
    clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 7ac2ff3102adcd..f812c01d42040b 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -76,7 +76,7 @@ class Environment {
     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;
     }
@@ -290,7 +290,7 @@ class Environment {
   /// 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.
   ///
@@ -315,7 +315,7 @@ class Environment {
   ///
   /// 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
@@ -375,8 +375,8 @@ class Environment {
   /// 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:
@@ -438,10 +438,10 @@ class Environment {
   ///
   ///  `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);
 
   /// Returns the value assigned to `Loc` in the environment or null if `Loc`
@@ -649,7 +649,7 @@ class Environment {
   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
@@ -668,36 +668,44 @@ class Environment {
 /// `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
index c9c302b9199bf2..f007a947a82f13 100644
--- a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h
@@ -22,23 +22,23 @@ namespace dataflow {
 /// 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 @@ void copyRecord(AggregateStorageLocation &Src, AggregateStorageLocation &Dst,
 ///
 /// 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 @@ void copyRecord(AggregateStorageLocation &Src, AggregateStorageLocation &Dst,
 /// 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
index 62e3d5e59c6590..4a55adad74616e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
+++ b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
@@ -31,7 +31,12 @@ namespace dataflow {
 /// 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 @@ class ScalarStorageLocation final : public StorageLocation {
   }
 };
 
-/// 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 @@ class ScalarStorageLocation final : public StorageLocation {
 /// 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 @@ class AggregateStorageLocation final : public StorageLocation {
   }
 
   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 @@ class AggregateStorageLocation final : public StorageLocation {
 
   /// 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 @@ class AggregateStorageLocation final : public StorageLocation {
   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
index d1432fe8217a13..b2f71de593f995 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Value.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Value.h
@@ -35,7 +35,9 @@ class Value {
   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 @@ class PointerValue final : public Value {
 /// 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 @@ class PointerValue final : public Value {
 ///      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 
diff erent `StructValue`s
+///   `RecordStorageLocation` to be associated with 
diff erent `RecordValue`s
 ///   in 
diff erent 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
index 9f72dc8f6ab38b..0a6d7792208258 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -67,7 +67,7 @@ StorageLocation &DataflowAnalysisContext::createStorageLocation(QualType Type) {
       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
index 503158c91c3f4f..f6c8f7d2d395ec 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -69,7 +69,7 @@ static bool compareDistinctValues(QualType Type, Value &Val1,
     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 @@ static Value *mergeDistinctValues(QualType Type, Value &Val1,
   }
 
   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 
diff erent properties associated
-    // with them. Create a new `StructValue` without any properties so that we
+    // `RecordVal1` and `RecordVal2` may have 
diff erent 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 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
     if (MethodDecl && !MethodDecl->isStatic()) {
       QualType ThisPointeeType = MethodDecl->getThisObjectType();
       ThisPointeeLoc =
-          &cast<StructValue>(createValue(ThisPointeeType))->getAggregateLoc();
+          &cast<RecordValue>(createValue(ThisPointeeType))->getLoc();
     }
   }
 }
@@ -337,7 +337,7 @@ Environment Environment::pushCall(const CallExpr *Call) const {
     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 @@ StorageLocation *Environment::getStorageLocation(const Expr &E) const {
   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 @@ PointerValue &Environment::getOrCreateNullPointerValue(QualType PointeeType) {
 }
 
 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 StorageLocation &Loc, Value &Val) {
 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 @@ Value *Environment::createValueUnlessSelfReferential(
                                           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 @@ Environment::createLocAndMaybeValue(QualType Ty,
     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 @@ StorageLocation &Environment::createObjectInternal(const VarDecl *D,
     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 @@ void Environment::dump() const {
   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 @@ std::vector<FieldDecl *> getFieldsForInitListExpr(const RecordDecl *RD) {
   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
index faca68e2f5951f..573c4b1d474bf4 100644
--- a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
@@ -28,8 +28,8 @@ llvm::StringRef debugString(Value::Kind Kind) {
     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
index 6848127e173e7a..9ec0160b1e3fe4 100644
--- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
+++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
@@ -103,9 +103,8 @@ class ModelDumper {
       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
index 1d6dfa95576434..961a06d0aa0afe 100644
--- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
@@ -256,9 +256,9 @@ void setHasValue(Value &OptionalVal, BoolValue &HasValueVal) {
 /// 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 @@ StorageLocation *maybeInitializeOptionalValueMember(QualType Q,
     // 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 @@ StorageLocation *maybeInitializeOptionalValueMember(QualType Q,
   // 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 @@ void transferCallReturningOptional(const CallExpr *E,
   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 transferCallReturningOptional(const CallExpr *E,
 
 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 @@ void transferAssignment(const CXXOperatorCallExpr *E, BoolValue &HasValueVal,
                         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 @@ void transferNulloptAssignment(const CXXOperatorCallExpr *E,
   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 @@ void transferSwapCall(const CXXMemberCallExpr *E,
                       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 transferSwapCall(const CXXMemberCallExpr *E,
 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 @@ auto buildTransferMatchSwitch() {
           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 @@ auto buildTransferMatchSwitch() {
           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 @@ Value *UncheckedOptionalAccessModel::widen(QualType Type, Value &Prev,
       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
index 95693f2e933a49..38638f8a9e5892 100644
--- 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 @@ void clang::dataflow::copyRecord(AggregateStorageLocation &Src,
            (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 @@ void clang::dataflow::copyRecord(AggregateStorageLocation &Src,
     }
   }
 
-  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 @@ void clang::dataflow::copyRecord(AggregateStorageLocation &Src,
   }
 }
 
-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 @@ bool clang::dataflow::recordsEqual(const AggregateStorageLocation &Loc1,
            (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 @@ bool clang::dataflow::recordsEqual(const AggregateStorageLocation &Loc1,
 
   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
index dee3687d7da0ae..d5da879d1bed2a 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -435,7 +435,7 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
       }
     }
 
-    AggregateStorageLocation *BaseLoc = getBaseObjectLocation(*S, Env);
+    RecordStorageLocation *BaseLoc = getBaseObjectLocation(*S, Env);
     if (BaseLoc == nullptr)
       return;
 
@@ -464,7 +464,7 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
       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 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
         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 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
     // 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 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
         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 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
     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 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
     }
 
     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
index 586c72baaf5fb9..e0c4991ca1a45d 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -376,7 +376,7 @@ builtinTransferInitializer(const CFGInitializer &Elt,
   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 @@ builtinTransferInitializer(const CFGInitializer &Elt,
     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 @@ builtinTransferInitializer(const CFGInitializer &Elt,
   // 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 @@ builtinTransferInitializer(const CFGInitializer &Elt,
     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
index cba9867912c963..a318d9ab7391aa 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -91,7 +91,7 @@ TEST_F(EnvironmentTest, CreateValueRecursiveType) {
   // 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 @@ TEST_F(EnvironmentTest, IncludeFieldsFromDefaultInitializers) {
   // 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 @@ TEST_F(EnvironmentTest, InitGlobalVarsFieldFun) {
   // 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 @@ TEST_F(EnvironmentTest, InitGlobalVarsConstructor) {
   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 @@ TEST_F(EnvironmentTest, RefreshStructValue) {
 
   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
index b4eb0f26bf76be..6ba1c2ebd833d4 100644
--- a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp
@@ -58,10 +58,10 @@ TEST(RecordOpsTest, CopyRecord) {
         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 @@ TEST(RecordOpsTest, CopyRecord) {
         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 @@ TEST(RecordOpsTest, CopyRecord) {
         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 @@ TEST(RecordOpsTest, RecordsEqual) {
         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 @@ TEST(RecordOpsTest, RecordsEqual) {
         EXPECT_TRUE(recordsEqual(S1, S2, Env));
 
         // S1 and S2 have the same property with 
diff erent 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 @@ TEST(RecordOpsTest, RecordsEqual) {
         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 @@ TEST(RecordOpsTest, RecordsEqual) {
 
         // S1 and S2 have the same number of properties, but with 
diff erent
         // 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 @@ TEST(TransferTest, CopyRecordFromDerivedToBase) {
         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
index e6f0b04c43c71f..11dc4ed76aa4fc 100644
--- a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h
+++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h
@@ -453,7 +453,7 @@ ValueT &getValueForDecl(ASTContext &ASTCtx, const Environment &Env,
 
 /// 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 @@ inline Value *getFieldValue(const AggregateStorageLocation *Loc,
 /// 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
index 33e9f06bc6439b..117230e14aa9e9 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -164,10 +164,10 @@ TEST(TransferTest, StructIncomplete) {
         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 @@ TEST(TransferTest, StructFieldUnmodeled) {
         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 @@ TEST(TransferTest, StructVarDecl) {
         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 @@ TEST(TransferTest, StructVarDeclWithInit) {
         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 @@ TEST(TransferTest, ClassVarDecl) {
         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 @@ TEST(TransferTest, ReferenceVarDecl) {
         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 @@ TEST(TransferTest, SelfReferentialReferenceVarDecl) {
     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 @@ TEST(TransferTest, PointerVarDecl) {
 
         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 @@ TEST(TransferTest, SelfReferentialPointerVarDecl) {
             *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 @@ TEST(TransferTest, StructParamDecl) {
         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 @@ TEST(TransferTest, ReferenceParamDecl) {
         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 @@ TEST(TransferTest, PointerParamDecl) {
 
         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 @@ TEST(TransferTest, StructMember) {
         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 @@ TEST(TransferTest, DerivedBaseMemberClass) {
         ASSERT_THAT(APublicDecl, NotNull());
 
         ASSERT_TRUE(
-            isa<AggregateStorageLocation>(Env.getStorageLocation(*FooDecl)));
+            isa<RecordStorageLocation>(Env.getStorageLocation(*FooDecl)));
       });
 }
 
@@ -1304,9 +1304,9 @@ static void derivedBaseMemberExpectations(
   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 @@ TEST(TransferTest, ClassMember) {
         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 @@ TEST(TransferTest, ReferenceMember) {
         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 @@ TEST(TransferTest, StructThisMember) {
         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 @@ TEST(TransferTest, ClassThisMember) {
         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 @@ TEST(TransferTest, TemporaryObject) {
         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 @@ TEST(TransferTest, ElidableConstructor) {
         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 @@ TEST(TransferTest, AssignmentOperator) {
           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 @@ TEST(TransferTest, AssignmentOperator) {
           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 @@ TEST(TransferTest, AssignmentOperator) {
           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 @@ TEST(TransferTest, CopyConstructor) {
               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 
diff erent `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 
diff erent `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 @@ TEST(TransferTest, CopyConstructor) {
               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 @@ TEST(TransferTest, CopyConstructorWithDefaultArgument) {
         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 @@ TEST(TransferTest, CopyConstructorWithParens) {
         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 @@ TEST(TransferTest, CopyConstructorWithInitializerListAsSyntacticSugar) {
         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 @@ TEST(TransferTest, MoveConstructor) {
         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 @@ TEST(TransferTest, MoveConstructor) {
         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 @@ TEST(TransferTest, BindTemporary) {
         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 @@ TEST(TransferTest, NullToPointerCast) {
         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 @@ TEST(TransferTest, VarDeclInitAssignConditionalOperator) {
         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 @@ TEST(TransferTest, AggregateInitialization) {
           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 @@ TEST(TransferTest, AggregateInitialization) {
           // 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 @@ TEST(TransferTest, AggregateInitializationReferenceField) {
         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 @@ TEST(TransferTest, AggregateInitialization_NotExplicitlyInitializedField) {
         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 @@ TEST(TransferTest, AssignToUnionMember) {
         }
         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 @@ TEST(TransferTest, AssignMemberBeforeCopy) {
 
         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 @@ TEST(TransferTest, NewExpressions_Structs) {
     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 @@ TEST(TransferTest, NewExpressions_Structs) {
 
         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 @@ TEST(TransferTest, AnonymousStruct) {
         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 @@ TEST(TransferTest, AnonymousStructWithInitializer) {
             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 @@ TEST(TransferTest, AnonymousStructWithReferenceField) {
             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
index 3e73a40ee2a454..8e43ef73c6b78b 100644
--- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -415,7 +415,7 @@ class SpecialBoolAnalysis final
     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 @@ class SpecialBoolAnalysis final
                                      .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 @@ class OptionalIntAnalysis final
         *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 @@ class OptionalIntAnalysis final
       auto *Object = E->getArg(0);
       assert(Object != nullptr);
 
-      refreshStructValue(*Object, Env)
+      refreshRecordValue(*Object, Env)
           .setProperty("has_value", Env.getBoolLiteralValue(true));
     }
   }


        


More information about the cfe-commits mailing list