[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-22 Thread weiyi via Phabricator via cfe-commits
wyt created this revision.
Herald added subscribers: martong, tschuett, xazax.hun.
Herald added a project: All.
wyt requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

`createStorageLocation` in `DataflowEnvironment` is now a trivial wrapper 
around the logic in `DataflowAnalysisContext`.
Additionally, `getObjectFields` and `getFieldsFromClassHierarchy` (required for 
the implementation of `createStorageLocation`) are also moved to 
`DataflowAnalysisContext`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128359

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
  clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -152,29 +152,6 @@
   }
 }
 
-// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
-// field decl will be modeled for all instances of the inherited field.
-static void
-getFieldsFromClassHierarchy(QualType Type,
-llvm::DenseSet &Fields) {
-  if (Type->isIncompleteType() || Type->isDependentType() ||
-  !Type->isRecordType())
-return;
-
-  for (const FieldDecl *Field : Type->getAsRecordDecl()->fields())
-Fields.insert(Field);
-  if (auto *CXXRecord = Type->getAsCXXRecordDecl())
-for (const CXXBaseSpecifier &Base : CXXRecord->bases())
-  getFieldsFromClassHierarchy(Base.getType(), Fields);
-}
-
-/// Gets the set of all fields in the type.
-static llvm::DenseSet getObjectFields(QualType Type) {
-  llvm::DenseSet Fields;
-  getFieldsFromClassHierarchy(Type, Fields);
-  return Fields;
-}
-
 Environment::Environment(DataflowAnalysisContext &DACtx)
 : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
 
@@ -310,39 +287,15 @@
 }
 
 StorageLocation &Environment::createStorageLocation(QualType Type) {
-  assert(!Type.isNull());
-  if (Type->isStructureOrClassType() || Type->isUnionType()) {
-// FIXME: Explore options to avoid eager initialization of fields as some of
-// them might not be needed for a particular analysis.
-llvm::DenseMap FieldLocs;
-for (const FieldDecl *Field : getObjectFields(Type))
-  FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
-return takeOwnership(
-std::make_unique(Type, std::move(FieldLocs)));
-  }
-  return takeOwnership(std::make_unique(Type));
+  return DACtx->createStorageLocation(Type);
 }
 
 StorageLocation &Environment::createStorageLocation(const VarDecl &D) {
-  // Evaluated declarations are always assigned the same storage locations to
-  // ensure that the environment stabilizes across loop iterations. Storage
-  // locations for evaluated declarations are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(D))
-return *Loc;
-  auto &Loc = createStorageLocation(D.getType());
-  DACtx->setStorageLocation(D, Loc);
-  return Loc;
+  return DACtx->createStorageLocation(D);
 }
 
 StorageLocation &Environment::createStorageLocation(const Expr &E) {
-  // Evaluated expressions are always assigned the same storage locations to
-  // ensure that the environment stabilizes across loop iterations. Storage
-  // locations for evaluated expressions are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(E))
-return *Loc;
-  auto &Loc = createStorageLocation(E.getType());
-  DACtx->setStorageLocation(E, Loc);
-  return Loc;
+  return DACtx->createStorageLocation(E);
 }
 
 void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) {
Index: clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -22,6 +22,43 @@
 namespace clang {
 namespace dataflow {
 
+StorageLocation &DataflowAnalysisContext::createStorageLocation(QualType Type) {
+  assert(!Type.isNull());
+  if (Type->isStructureOrClassType() || Type->isUnionType()) {
+// FIXME: Explore options to avoid eager initialization of fields as some of
+// them might not be needed for a particular analysis.
+llvm::DenseMap FieldLocs;
+for (const FieldDecl *Field : getObjectFields(Type))
+  FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
+return takeOwnership(
+std::make_unique(Type, std::move(FieldLocs)));
+  }
+  return takeOwnership(std::make_unique(Type));
+}
+
+StorageLocation &
+DataflowAnalysisContext::createStorageLocation(const VarDecl &D) {
+  // Evaluated declarations are always assigned the same storage locations to
+  // ensur

[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-22 Thread Stanislav Gatev via Phabricator via cfe-commits
sgatev added inline comments.



Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:91-92
 
+  // FIXME: Rename `createOrGetStorageLocation` to 
`getOrCreateStorageLocation`,
+  // `getStableStorageLocation`, or something more appropriate.
+

Let's implement this for the new members you are adding and keep the existing 
members in `DataflowEnvironment` as they are. I suggest calling the new ones 
`getStableStorageLocation`.



Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:94-95
+
+  /// Creates a storage location appropriate for `Type`. Does not assign a 
value
+  /// to the returned storage location in the environment.
+  ///





Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:102-104
+  /// Creates a storage location for `D`. Does not assign the returned storage
+  /// location to `D` in the environment. Does not assign a value to the
+  /// returned storage location in the environment.





Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:107-109
+  /// Creates a storage location for `E`. Does not assign the returned storage
+  /// location to `E` in the environment. Does not assign a value to the
+  /// returned storage location in the environment.





Comment at: clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp:41-43
+  // Evaluated declarations are always assigned the same storage locations to
+  // ensure that the environment stabilizes across loop iterations. Storage
+  // locations for evaluated declarations are stored in the analysis context.

I think it makes sense to keep this comment in the wrapper in 
`DataflowEnvironment`. Same for the one below.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128359/new/

https://reviews.llvm.org/D128359

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-24 Thread weiyi via Phabricator via cfe-commits
wyt updated this revision to Diff 439720.
wyt marked 5 inline comments as done.
wyt added a comment.

Address comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128359/new/

https://reviews.llvm.org/D128359

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
  clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -152,29 +152,6 @@
   }
 }
 
-// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
-// field decl will be modeled for all instances of the inherited field.
-static void
-getFieldsFromClassHierarchy(QualType Type,
-llvm::DenseSet &Fields) {
-  if (Type->isIncompleteType() || Type->isDependentType() ||
-  !Type->isRecordType())
-return;
-
-  for (const FieldDecl *Field : Type->getAsRecordDecl()->fields())
-Fields.insert(Field);
-  if (auto *CXXRecord = Type->getAsCXXRecordDecl())
-for (const CXXBaseSpecifier &Base : CXXRecord->bases())
-  getFieldsFromClassHierarchy(Base.getType(), Fields);
-}
-
-/// Gets the set of all fields in the type.
-static llvm::DenseSet getObjectFields(QualType Type) {
-  llvm::DenseSet Fields;
-  getFieldsFromClassHierarchy(Type, Fields);
-  return Fields;
-}
-
 Environment::Environment(DataflowAnalysisContext &DACtx)
 : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
 
@@ -310,39 +287,21 @@
 }
 
 StorageLocation &Environment::createStorageLocation(QualType Type) {
-  assert(!Type.isNull());
-  if (Type->isStructureOrClassType() || Type->isUnionType()) {
-// FIXME: Explore options to avoid eager initialization of fields as some of
-// them might not be needed for a particular analysis.
-llvm::DenseMap FieldLocs;
-for (const FieldDecl *Field : getObjectFields(Type))
-  FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
-return takeOwnership(
-std::make_unique(Type, std::move(FieldLocs)));
-  }
-  return takeOwnership(std::make_unique(Type));
+  return DACtx->getStableStorageLocation(Type);
 }
 
 StorageLocation &Environment::createStorageLocation(const VarDecl &D) {
   // Evaluated declarations are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated declarations are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(D))
-return *Loc;
-  auto &Loc = createStorageLocation(D.getType());
-  DACtx->setStorageLocation(D, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(D);
 }
 
 StorageLocation &Environment::createStorageLocation(const Expr &E) {
   // Evaluated expressions are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated expressions are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(E))
-return *Loc;
-  auto &Loc = createStorageLocation(E.getType());
-  DACtx->setStorageLocation(E, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(E);
 }
 
 void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) {
Index: clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -22,6 +22,39 @@
 namespace clang {
 namespace dataflow {
 
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(QualType Type) {
+  assert(!Type.isNull());
+  if (Type->isStructureOrClassType() || Type->isUnionType()) {
+// FIXME: Explore options to avoid eager initialization of fields as some of
+// them might not be needed for a particular analysis.
+llvm::DenseMap FieldLocs;
+for (const FieldDecl *Field : getObjectFields(Type))
+  FieldLocs.insert({Field, &getStableStorageLocation(Field->getType())});
+return takeOwnership(
+std::make_unique(Type, std::move(FieldLocs)));
+  }
+  return takeOwnership(std::make_unique(Type));
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const VarDecl &D) {
+  if (auto *Loc = getStorageLocation(D))
+return *Loc;
+  auto &Loc = getStableStorageLocation(D.getType());
+  setStorageLocation(D, Loc);
+  return Loc;
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const Expr &E) {
+  if (auto *Loc = getStorageLocation(E))
+return *Loc;
+  auto &Loc = getStableStorageLocation(E.getType());
+  setStorageLocation(E, Loc);
+  re

[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-24 Thread Stanislav Gatev via Phabricator via cfe-commits
sgatev accepted this revision.
sgatev added inline comments.
This revision is now accepted and ready to land.



Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:91
 
+  /// Creates a stable storage location appropriate for `Type`.
+  ///





Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:98
+
+  /// Creates a stable storage location for `D`.
+  StorageLocation &getStableStorageLocation(const VarDecl &D);





Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:101
+
+  /// Creates a stable storage location for `E`.
+  StorageLocation &getStableStorageLocation(const Expr &E);




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128359/new/

https://reviews.llvm.org/D128359

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-24 Thread weiyi via Phabricator via cfe-commits
wyt updated this revision to Diff 439730.
wyt marked 3 inline comments as done.
wyt added a comment.

Fix comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128359/new/

https://reviews.llvm.org/D128359

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
  clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -152,29 +152,6 @@
   }
 }
 
-// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
-// field decl will be modeled for all instances of the inherited field.
-static void
-getFieldsFromClassHierarchy(QualType Type,
-llvm::DenseSet &Fields) {
-  if (Type->isIncompleteType() || Type->isDependentType() ||
-  !Type->isRecordType())
-return;
-
-  for (const FieldDecl *Field : Type->getAsRecordDecl()->fields())
-Fields.insert(Field);
-  if (auto *CXXRecord = Type->getAsCXXRecordDecl())
-for (const CXXBaseSpecifier &Base : CXXRecord->bases())
-  getFieldsFromClassHierarchy(Base.getType(), Fields);
-}
-
-/// Gets the set of all fields in the type.
-static llvm::DenseSet getObjectFields(QualType Type) {
-  llvm::DenseSet Fields;
-  getFieldsFromClassHierarchy(Type, Fields);
-  return Fields;
-}
-
 Environment::Environment(DataflowAnalysisContext &DACtx)
 : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
 
@@ -310,39 +287,21 @@
 }
 
 StorageLocation &Environment::createStorageLocation(QualType Type) {
-  assert(!Type.isNull());
-  if (Type->isStructureOrClassType() || Type->isUnionType()) {
-// FIXME: Explore options to avoid eager initialization of fields as some of
-// them might not be needed for a particular analysis.
-llvm::DenseMap FieldLocs;
-for (const FieldDecl *Field : getObjectFields(Type))
-  FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
-return takeOwnership(
-std::make_unique(Type, std::move(FieldLocs)));
-  }
-  return takeOwnership(std::make_unique(Type));
+  return DACtx->getStableStorageLocation(Type);
 }
 
 StorageLocation &Environment::createStorageLocation(const VarDecl &D) {
   // Evaluated declarations are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated declarations are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(D))
-return *Loc;
-  auto &Loc = createStorageLocation(D.getType());
-  DACtx->setStorageLocation(D, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(D);
 }
 
 StorageLocation &Environment::createStorageLocation(const Expr &E) {
   // Evaluated expressions are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated expressions are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(E))
-return *Loc;
-  auto &Loc = createStorageLocation(E.getType());
-  DACtx->setStorageLocation(E, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(E);
 }
 
 void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) {
Index: clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -22,6 +22,39 @@
 namespace clang {
 namespace dataflow {
 
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(QualType Type) {
+  assert(!Type.isNull());
+  if (Type->isStructureOrClassType() || Type->isUnionType()) {
+// FIXME: Explore options to avoid eager initialization of fields as some of
+// them might not be needed for a particular analysis.
+llvm::DenseMap FieldLocs;
+for (const FieldDecl *Field : getObjectFields(Type))
+  FieldLocs.insert({Field, &getStableStorageLocation(Field->getType())});
+return takeOwnership(
+std::make_unique(Type, std::move(FieldLocs)));
+  }
+  return takeOwnership(std::make_unique(Type));
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const VarDecl &D) {
+  if (auto *Loc = getStorageLocation(D))
+return *Loc;
+  auto &Loc = getStableStorageLocation(D.getType());
+  setStorageLocation(D, Loc);
+  return Loc;
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const Expr &E) {
+  if (auto *Loc = getStorageLocation(E))
+return *Loc;
+  auto &Loc = getStableStorageLocation(E.getType());
+  setStorageLocation(E, Loc);
+  return 

[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-24 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr2 accepted this revision.
gribozavr2 added inline comments.



Comment at: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h:47
 
+/// Gets the set of all fields in the type.
+llvm::DenseSet getObjectFields(QualType Type);




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128359/new/

https://reviews.llvm.org/D128359

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-27 Thread weiyi via Phabricator via cfe-commits
wyt updated this revision to Diff 440123.
wyt marked an inline comment as done.
wyt added a comment.

Fix comment.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128359/new/

https://reviews.llvm.org/D128359

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
  clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -152,29 +152,6 @@
   }
 }
 
-// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
-// field decl will be modeled for all instances of the inherited field.
-static void
-getFieldsFromClassHierarchy(QualType Type,
-llvm::DenseSet &Fields) {
-  if (Type->isIncompleteType() || Type->isDependentType() ||
-  !Type->isRecordType())
-return;
-
-  for (const FieldDecl *Field : Type->getAsRecordDecl()->fields())
-Fields.insert(Field);
-  if (auto *CXXRecord = Type->getAsCXXRecordDecl())
-for (const CXXBaseSpecifier &Base : CXXRecord->bases())
-  getFieldsFromClassHierarchy(Base.getType(), Fields);
-}
-
-/// Gets the set of all fields in the type.
-static llvm::DenseSet getObjectFields(QualType Type) {
-  llvm::DenseSet Fields;
-  getFieldsFromClassHierarchy(Type, Fields);
-  return Fields;
-}
-
 Environment::Environment(DataflowAnalysisContext &DACtx)
 : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
 
@@ -310,39 +287,21 @@
 }
 
 StorageLocation &Environment::createStorageLocation(QualType Type) {
-  assert(!Type.isNull());
-  if (Type->isStructureOrClassType() || Type->isUnionType()) {
-// FIXME: Explore options to avoid eager initialization of fields as some of
-// them might not be needed for a particular analysis.
-llvm::DenseMap FieldLocs;
-for (const FieldDecl *Field : getObjectFields(Type))
-  FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
-return takeOwnership(
-std::make_unique(Type, std::move(FieldLocs)));
-  }
-  return takeOwnership(std::make_unique(Type));
+  return DACtx->getStableStorageLocation(Type);
 }
 
 StorageLocation &Environment::createStorageLocation(const VarDecl &D) {
   // Evaluated declarations are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated declarations are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(D))
-return *Loc;
-  auto &Loc = createStorageLocation(D.getType());
-  DACtx->setStorageLocation(D, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(D);
 }
 
 StorageLocation &Environment::createStorageLocation(const Expr &E) {
   // Evaluated expressions are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated expressions are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(E))
-return *Loc;
-  auto &Loc = createStorageLocation(E.getType());
-  DACtx->setStorageLocation(E, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(E);
 }
 
 void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) {
Index: clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -22,6 +22,39 @@
 namespace clang {
 namespace dataflow {
 
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(QualType Type) {
+  assert(!Type.isNull());
+  if (Type->isStructureOrClassType() || Type->isUnionType()) {
+// FIXME: Explore options to avoid eager initialization of fields as some of
+// them might not be needed for a particular analysis.
+llvm::DenseMap FieldLocs;
+for (const FieldDecl *Field : getObjectFields(Type))
+  FieldLocs.insert({Field, &getStableStorageLocation(Field->getType())});
+return takeOwnership(
+std::make_unique(Type, std::move(FieldLocs)));
+  }
+  return takeOwnership(std::make_unique(Type));
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const VarDecl &D) {
+  if (auto *Loc = getStorageLocation(D))
+return *Loc;
+  auto &Loc = getStableStorageLocation(D.getType());
+  setStorageLocation(D, Loc);
+  return Loc;
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const Expr &E) {
+  if (auto *Loc = getStorageLocation(E))
+return *Loc;
+  auto &Loc = getStableStorageLocation(E.getType());
+  setStorageLocation(E, Loc);
+  return 

[PATCH] D128359: [clang][dataflow] Move logic for `createStorageLocation` from `DataflowEnvironment` to `DataflowAnalysisContext`.

2022-06-27 Thread Dmitri Gribenko via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG12c7352fa488: [clang][dataflow] Move logic for 
`createStorageLocation` from… (authored by wyt, committed by gribozavr).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128359/new/

https://reviews.llvm.org/D128359

Files:
  clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
  clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
  clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Index: clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -152,29 +152,6 @@
   }
 }
 
-// FIXME: Does not precisely handle non-virtual diamond inheritance. A single
-// field decl will be modeled for all instances of the inherited field.
-static void
-getFieldsFromClassHierarchy(QualType Type,
-llvm::DenseSet &Fields) {
-  if (Type->isIncompleteType() || Type->isDependentType() ||
-  !Type->isRecordType())
-return;
-
-  for (const FieldDecl *Field : Type->getAsRecordDecl()->fields())
-Fields.insert(Field);
-  if (auto *CXXRecord = Type->getAsCXXRecordDecl())
-for (const CXXBaseSpecifier &Base : CXXRecord->bases())
-  getFieldsFromClassHierarchy(Base.getType(), Fields);
-}
-
-/// Gets the set of all fields in the type.
-static llvm::DenseSet getObjectFields(QualType Type) {
-  llvm::DenseSet Fields;
-  getFieldsFromClassHierarchy(Type, Fields);
-  return Fields;
-}
-
 Environment::Environment(DataflowAnalysisContext &DACtx)
 : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
 
@@ -310,39 +287,21 @@
 }
 
 StorageLocation &Environment::createStorageLocation(QualType Type) {
-  assert(!Type.isNull());
-  if (Type->isStructureOrClassType() || Type->isUnionType()) {
-// FIXME: Explore options to avoid eager initialization of fields as some of
-// them might not be needed for a particular analysis.
-llvm::DenseMap FieldLocs;
-for (const FieldDecl *Field : getObjectFields(Type))
-  FieldLocs.insert({Field, &createStorageLocation(Field->getType())});
-return takeOwnership(
-std::make_unique(Type, std::move(FieldLocs)));
-  }
-  return takeOwnership(std::make_unique(Type));
+  return DACtx->getStableStorageLocation(Type);
 }
 
 StorageLocation &Environment::createStorageLocation(const VarDecl &D) {
   // Evaluated declarations are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated declarations are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(D))
-return *Loc;
-  auto &Loc = createStorageLocation(D.getType());
-  DACtx->setStorageLocation(D, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(D);
 }
 
 StorageLocation &Environment::createStorageLocation(const Expr &E) {
   // Evaluated expressions are always assigned the same storage locations to
   // ensure that the environment stabilizes across loop iterations. Storage
   // locations for evaluated expressions are stored in the analysis context.
-  if (auto *Loc = DACtx->getStorageLocation(E))
-return *Loc;
-  auto &Loc = createStorageLocation(E.getType());
-  DACtx->setStorageLocation(E, Loc);
-  return Loc;
+  return DACtx->getStableStorageLocation(E);
 }
 
 void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) {
Index: clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
===
--- clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -22,6 +22,39 @@
 namespace clang {
 namespace dataflow {
 
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(QualType Type) {
+  assert(!Type.isNull());
+  if (Type->isStructureOrClassType() || Type->isUnionType()) {
+// FIXME: Explore options to avoid eager initialization of fields as some of
+// them might not be needed for a particular analysis.
+llvm::DenseMap FieldLocs;
+for (const FieldDecl *Field : getObjectFields(Type))
+  FieldLocs.insert({Field, &getStableStorageLocation(Field->getType())});
+return takeOwnership(
+std::make_unique(Type, std::move(FieldLocs)));
+  }
+  return takeOwnership(std::make_unique(Type));
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const VarDecl &D) {
+  if (auto *Loc = getStorageLocation(D))
+return *Loc;
+  auto &Loc = getStableStorageLocation(D.getType());
+  setStorageLocation(D, Loc);
+  return Loc;
+}
+
+StorageLocation &
+DataflowAnalysisContext::getStableStorageLocation(const Expr &E) {
+  if (auto *Loc = getStorageLocation(E))
+return *Lo