[118/125] gccrs: borrowck: Free region representation

Message ID 20240801145809.366388-120-arthur.cohen@embecosm.com
State Committed
Commit 2cfd6f98495986c113c652302645abc932b7cf14
Headers
Series [001/125] Rust: Make 'tree'-level 'MAIN_NAME_P' work |

Commit Message

Arthur Cohen Aug. 1, 2024, 2:57 p.m. UTC
  From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* checks/errors/borrowck/rust-bir-free-region.h: New file.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 .../errors/borrowck/rust-bir-free-region.h    | 107 ++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 gcc/rust/checks/errors/borrowck/rust-bir-free-region.h
  

Patch

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-free-region.h b/gcc/rust/checks/errors/borrowck/rust-bir-free-region.h
new file mode 100644
index 00000000000..0560a894ab0
--- /dev/null
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-free-region.h
@@ -0,0 +1,107 @@ 
+#ifndef RUST_BIR_FREE_REGION_H
+#define RUST_BIR_FREE_REGION_H
+
+#include "rust-diagnostics.h"
+#include "polonius/rust-polonius-ffi.h"
+
+namespace Rust {
+
+using FreeRegion = size_t;
+
+class FreeRegions
+{
+  std::vector<FreeRegion> regions;
+
+public:
+  WARN_UNUSED_RESULT bool has_regions () const { return !regions.empty (); }
+  decltype (regions)::const_iterator begin () const { return regions.begin (); }
+  decltype (regions)::const_iterator end () const { return regions.end (); }
+  size_t size () const { return regions.size (); }
+  FreeRegion &operator[] (size_t i) { return regions.at (i); }
+  const FreeRegion &operator[] (size_t i) const { return regions.at (i); }
+  const std::vector<FreeRegion> &get_regions () const { return regions; }
+  void set_from (std::vector<Rust::Polonius::Origin> &&regions)
+  {
+    this->regions.clear ();
+    for (auto &region : regions)
+      {
+	this->regions.push_back ({region});
+      }
+  }
+
+  WARN_UNUSED_RESULT FreeRegions prepend (FreeRegion region) const
+  {
+    std::vector<FreeRegion> new_regions = {region};
+    new_regions.insert (new_regions.end (), regions.begin (), regions.end ());
+    return FreeRegions (std::move (new_regions));
+  }
+
+  FreeRegions (std::vector<FreeRegion> &&regions) : regions (regions) {}
+
+  WARN_UNUSED_RESULT std::string to_string () const
+  {
+    std::stringstream result;
+    for (auto &region : regions)
+      {
+	result << region;
+	result << ", ";
+      }
+    // Remove the last ", " from the string.
+    if (result.tellg () > 2)
+      result.seekp (-2, std::ios_base::cur);
+
+    return result.str ();
+  }
+};
+
+class RegionBinder
+{
+  FreeRegion &next_free_region;
+
+public:
+  explicit RegionBinder (FreeRegion &next_free_region)
+    : next_free_region (next_free_region)
+  {}
+
+  WARN_UNUSED_RESULT FreeRegion get_next_free_region () const
+  {
+    return next_free_region++;
+  }
+
+  FreeRegions bind_regions (std::vector<TyTy::Region> regions,
+			    FreeRegions parent_free_regions)
+  {
+    std::vector<FreeRegion> free_regions;
+    for (auto &region : regions)
+      {
+	if (region.is_early_bound ())
+	  {
+	    free_regions.push_back (parent_free_regions[region.get_index ()]);
+	  }
+	else if (region.is_static ())
+	  {
+	    free_regions.push_back (0);
+	  }
+	else if (region.is_anonymous ())
+	  {
+	    free_regions.push_back (get_next_free_region ());
+	  }
+	else if (region.is_named ())
+	  {
+	    rust_unreachable (); // FIXME
+	  }
+	else
+	  {
+	    rust_sorry_at (UNKNOWN_LOCATION, "Unimplemented");
+	    rust_unreachable ();
+	  }
+      }
+    // This is necesarry because of clash of current gcc and gcc4.8.
+    FreeRegions free_regions_final{std::move (free_regions)};
+    return free_regions_final;
+  }
+};
+
+} // namespace Rust
+
+#endif // RUST_BIR_FREE_REGION_H