1616
1717#include " clang/Analysis/Analyses/LifetimeSafety/Loans.h"
1818#include " clang/Analysis/Analyses/LifetimeSafety/Origins.h"
19+ #include " clang/Analysis/Analyses/LifetimeSafety/Utils.h"
1920#include " clang/Analysis/AnalysisDeclContext.h"
2021#include " clang/Analysis/CFG.h"
2122#include " llvm/ADT/SmallVector.h"
2223#include " llvm/Support/Debug.h"
2324#include < cstdint>
2425
2526namespace clang ::lifetimes::internal {
27+
28+ using FactID = utils::ID<struct FactTag >;
29+
2630// / An abstract base class for a single, atomic lifetime-relevant event.
2731class Fact {
2832
@@ -48,6 +52,7 @@ class Fact {
4852
4953private:
5054 Kind K;
55+ FactID ID;
5156
5257protected:
5358 Fact (Kind K) : K(K) {}
@@ -56,6 +61,9 @@ class Fact {
5661 virtual ~Fact () = default ;
5762 Kind getKind () const { return K; }
5863
64+ void setID (FactID ID) { this ->ID = ID; }
65+ FactID getID () const { return ID; }
66+
5967 template <typename T> const T *getAs () const {
6068 if (T::classof (this ))
6169 return static_cast <const T *>(this );
@@ -183,22 +191,26 @@ class TestPointFact : public Fact {
183191
184192class FactManager {
185193public:
194+ void init (const CFG &Cfg) {
195+ assert (BlockToFacts.empty () && " FactManager already initialized" );
196+ BlockToFacts.resize (Cfg.getNumBlockIDs ());
197+ }
198+
186199 llvm::ArrayRef<const Fact *> getFacts (const CFGBlock *B) const {
187- auto It = BlockToFactsMap.find (B);
188- if (It != BlockToFactsMap.end ())
189- return It->second ;
190- return {};
200+ return BlockToFacts[B->getBlockID ()];
191201 }
192202
193203 void addBlockFacts (const CFGBlock *B, llvm::ArrayRef<Fact *> NewFacts) {
194204 if (!NewFacts.empty ())
195- BlockToFactsMap[B ].assign (NewFacts.begin (), NewFacts.end ());
205+ BlockToFacts[B-> getBlockID () ].assign (NewFacts.begin (), NewFacts.end ());
196206 }
197207
198208 template <typename FactType, typename ... Args>
199209 FactType *createFact (Args &&...args) {
200210 void *Mem = FactAllocator.Allocate <FactType>();
201- return new (Mem) FactType (std::forward<Args>(args)...);
211+ FactType *Res = new (Mem) FactType (std::forward<Args>(args)...);
212+ Res->setID (NextFactID++);
213+ return Res;
202214 }
203215
204216 void dump (const CFG &Cfg, AnalysisDeclContext &AC) const ;
@@ -214,16 +226,19 @@ class FactManager {
214226 // / \note This is intended for testing only.
215227 llvm::StringMap<ProgramPoint> getTestPoints () const ;
216228
229+ unsigned getNumFacts () const { return NextFactID.Value ; }
230+
217231 LoanManager &getLoanMgr () { return LoanMgr; }
218232 const LoanManager &getLoanMgr () const { return LoanMgr; }
219233 OriginManager &getOriginMgr () { return OriginMgr; }
220234 const OriginManager &getOriginMgr () const { return OriginMgr; }
221235
222236private:
237+ FactID NextFactID{0 };
223238 LoanManager LoanMgr;
224239 OriginManager OriginMgr;
225- llvm::DenseMap< const clang::CFGBlock *, llvm::SmallVector< const Fact *>>
226- BlockToFactsMap ;
240+ // / Facts for each CFG block, indexed by block ID.
241+ llvm::SmallVector<llvm::SmallVector< const Fact *>> BlockToFacts ;
227242 llvm::BumpPtrAllocator FactAllocator;
228243};
229244} // namespace clang::lifetimes::internal
0 commit comments