Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>
18 : :
19 : : #ifndef RUST_BIR_FREE_REGION_H
20 : : #define RUST_BIR_FREE_REGION_H
21 : :
22 : : #include "rust-diagnostics.h"
23 : : #include "polonius/rust-polonius-ffi.h"
24 : :
25 : : namespace Rust {
26 : :
27 : : struct FreeRegion
28 : : {
29 : : size_t value;
30 : : // some overloads for comparision
31 : 2 : bool operator== (const FreeRegion &rhs) const { return value == rhs.value; }
32 : 2 : bool operator!= (const FreeRegion &rhs) const { return !(operator== (rhs)); }
33 : : bool operator< (const FreeRegion &rhs) const { return value < rhs.value; }
34 : : bool operator> (const FreeRegion &rhs) const { return value > rhs.value; }
35 : : bool operator<= (const FreeRegion &rhs) const { return !(operator> (rhs)); }
36 : : bool operator>= (const FreeRegion &rhs) const { return !(operator< (rhs)); }
37 : : };
38 : :
39 : : static constexpr FreeRegion STATIC_FREE_REGION = {0};
40 : :
41 : 2023 : class FreeRegions
42 : : {
43 : : std::vector<FreeRegion> regions;
44 : :
45 : : public:
46 : : WARN_UNUSED_RESULT bool has_regions () const { return !regions.empty (); }
47 : 254 : decltype (regions)::const_iterator begin () const { return regions.begin (); }
48 : 255 : decltype (regions)::const_iterator end () const { return regions.end (); }
49 : 576 : size_t size () const { return regions.size (); }
50 : 162 : FreeRegion &operator[] (size_t i) { return regions.at (i); }
51 : 35 : const FreeRegion &operator[] (size_t i) const { return regions.at (i); }
52 : 0 : const std::vector<FreeRegion> &get_regions () const { return regions; }
53 : :
54 : 55 : WARN_UNUSED_RESULT FreeRegions prepend (FreeRegion region) const
55 : : {
56 : 55 : std::vector<FreeRegion> new_regions = {region};
57 : 55 : new_regions.insert (new_regions.end (), regions.begin (), regions.end ());
58 : 55 : return FreeRegions (std::move (new_regions));
59 : 55 : }
60 : :
61 : 160 : void push_back (FreeRegion region) { regions.push_back (region); }
62 : :
63 : 427 : FreeRegions () {}
64 : 426 : FreeRegions (std::vector<FreeRegion> &®ions) : regions (regions) {}
65 : :
66 : 36 : WARN_UNUSED_RESULT std::string to_string () const
67 : : {
68 : 36 : std::stringstream result;
69 : 36 : for (auto ®ion : regions)
70 : : {
71 : 0 : result << region.value;
72 : 0 : result << ", ";
73 : : }
74 : : // Remove the last ", " from the string.
75 : 36 : if (result.tellg () > 2)
76 : 0 : result.seekp (-2, std::ios_base::cur);
77 : :
78 : 36 : return result.str ();
79 : 36 : }
80 : : };
81 : :
82 : : class RegionBinder
83 : : {
84 : : FreeRegion &next_free_region;
85 : :
86 : : public:
87 : 72 : explicit RegionBinder (FreeRegion &next_free_region)
88 : 36 : : next_free_region (next_free_region)
89 : : {}
90 : :
91 : 12 : WARN_UNUSED_RESULT FreeRegion get_next_free_region () const
92 : : {
93 : 12 : ++next_free_region.value;
94 : 12 : return {next_free_region.value - 1};
95 : : }
96 : :
97 : 22 : FreeRegions bind_regions (std::vector<TyTy::Region> regions,
98 : : FreeRegions parent_free_regions)
99 : : {
100 : 22 : FreeRegions free_regions;
101 : 46 : for (auto ®ion : regions)
102 : : {
103 : 24 : if (region.is_early_bound ())
104 : 24 : free_regions.push_back (parent_free_regions[region.get_index ()]);
105 : 0 : else if (region.is_static ())
106 : 0 : free_regions.push_back (STATIC_FREE_REGION);
107 : 0 : else if (region.is_anonymous ())
108 : 0 : free_regions.push_back (get_next_free_region ());
109 : 0 : else if (region.is_named ())
110 : 0 : rust_unreachable (); // FIXME
111 : : else
112 : : {
113 : 0 : rust_sorry_at (UNKNOWN_LOCATION, "Unimplemented");
114 : 0 : rust_unreachable ();
115 : : }
116 : : }
117 : 22 : return free_regions;
118 : : }
119 : : };
120 : :
121 : : } // namespace Rust
122 : :
123 : : #endif // RUST_BIR_FREE_REGION_H
|