================
@@ -52,41 +62,118 @@ struct Origin {
   }
 };
 
-/// Manages the creation, storage, and retrieval of origins for pointer-like
-/// variables and expressions.
-class OriginManager {
+/// A list of origins representing levels of indirection for pointer-like 
types.
+///
+/// Each node in the list contains an OriginID representing a level of
+/// indirection. The list structure captures the multi-level nature of
+/// pointer and reference types in the lifetime analysis.
+///
+/// Examples:
+///   - For `int& x`, the list has size 2:
+///     * Root: origin for the reference storage itself (the lvalue `x`)
+///     * Pointee: origin for what `x` refers to
+///
+///   - For `int* p`, the list has size 2:
+///     * Root: origin for the pointer variable `p`
+///     * Pointee: origin for what `p` points to
+///
+///   - For `View v` (where View is gsl::Pointer), the list has size 2:
+///     * Root: origin for the view object itself
+///     * Pointee: origin for what the view refers to
+///
+///   - For `int** pp`, the list has size 3:
+///     * Root: origin for `pp` itself
+///     * Pointee: origin for `*pp` (what `pp` points to)
+///     * Pointee->Pointee: origin for `**pp` (what `*pp` points to)
+///
+/// The list structure enables the analysis to track how loans flow through
+/// different levels of indirection when assignments and dereferences occur.
+class OriginList {
 public:
-  OriginManager() = default;
+  OriginList(OriginID OID) : OuterOID(OID) {}
+
+  OriginList *peelOuterOrigin() { return InnerList; }
+  OriginID getOuterOriginID() const { return OuterOID; }
 
-  Origin &addOrigin(OriginID ID, const clang::ValueDecl &D);
-  Origin &addOrigin(OriginID ID, const clang::Expr &E);
+  void setInnerOriginList(OriginList *Inner) { InnerList = Inner; }
 
-  // TODO: Mark this method as const once we remove the call to getOrCreate.
-  OriginID get(const Expr &E);
+  size_t getLength() const {
+    size_t Length = 1;
+    const OriginList *T = this;
+    while (T->InnerList) {
+      T = T->InnerList;
+      Length++;
+    }
+    return Length;
+  }
 
-  OriginID get(const ValueDecl &D);
+private:
+  OriginID OuterOID;
+  OriginList *InnerList = nullptr;
+};
 
-  OriginID getOrCreate(const Expr &E);
+bool hasOrigins(QualType QT);
+bool hasOrigins(const Expr *E);
+bool doesDeclHaveStorage(const ValueDecl *D);
+
+/// Manages the creation, storage, and retrieval of origins for pointer-like
+/// variables and expressions.
+class OriginManager {
+public:
+  explicit OriginManager(ASTContext &AST) : AST(AST) {}
+
+  /// Gets or creates the OriginList for a given ValueDecl.
+  ///
+  /// Creates a list structure mirroring the levels of indirection in the
+  /// declaration's type (e.g., `int** p` creates list of size 2).
+  ///
+  /// \returns The OriginList, or nullptr if the type is not pointer-like.
+  OriginList *getOrCreateList(const ValueDecl *D);
+
+  /// Gets or creates the OriginList for a given Expr.
+  ///
+  /// Creates a list based on the expression's type and value category:
+  /// - Lvalues get an implicit reference level (modeling addressability)
+  /// - Rvalues of non-pointer type return nullptr (no trackable origin)
+  /// - DeclRefExpr may reuse the underlying declaration's list
+  ///
+  /// \returns The OriginList, or nullptr for non-pointer rvalues.
+  OriginList *getOrCreateList(const Expr *E, size_t Depth = 0);
 
   const Origin &getOrigin(OriginID ID) const;
 
   llvm::ArrayRef<Origin> getOrigins() const { return AllOrigins; }
 
-  OriginID getOrCreate(const ValueDecl &D);
-
   unsigned getNumOrigins() const { return NextOriginID.Value; }
 
   void dump(OriginID OID, llvm::raw_ostream &OS) const;
 
 private:
   OriginID getNextOriginID() { return NextOriginID++; }
 
+  OriginList *createNode(const ValueDecl *D, QualType QT) {
+    OriginID NewID = getNextOriginID();
+    AllOrigins.emplace_back(NewID, D, QT.getTypePtrOrNull());
+    return new (ListAllocator.Allocate<OriginList>()) OriginList(NewID);
+  }
+
+  OriginList *createNode(const Expr *E, QualType QT) {
+    OriginID NewID = getNextOriginID();
+    AllOrigins.emplace_back(NewID, E, QT.getTypePtrOrNull());
+    return new (ListAllocator.Allocate<OriginList>()) OriginList(NewID);
+  }
----------------
ymand wrote:

why define these in the header (given that they are private)?

https://github.com/llvm/llvm-project/pull/168344
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to