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_POLONIUS_FACTS_FFI_H
20 : : #define RUST_POLONIUS_FACTS_FFI_H
21 : :
22 : : #include "rust-system.h"
23 : :
24 : : // This file defines the C++ side of the FFI interface to Polonius.
25 : : // The corresponding Rust side is in `gccrs-ffi.rs`.
26 : :
27 : : // IMPORTANT:
28 : : // This file intentionally does not include any C++ headers
29 : : // to allow seamless binding generation on the Rust side.
30 : :
31 : : namespace Rust {
32 : : namespace Polonius {
33 : :
34 : : using Origin = size_t;
35 : : using Loan = size_t;
36 : : /**
37 : : * Compressed CFG point
38 : : * Encoding:
39 : : * - (bit size - 16) bits: basic block index
40 : : * - 15 bits: stmt index inside basic block
41 : : * - 1bit: start or mid
42 : : *
43 : : * Note: Polonius requires the holding type to be `size_t`/`usize`.
44 : : */
45 : : using Point = size_t;
46 : : using Variable = size_t;
47 : : using Path = size_t;
48 : :
49 : : namespace FFI {
50 : :
51 : : // NOTE: std::pair and std::tuple are complicating the bindings' generation.
52 : : template <typename T1, typename T2> struct Pair
53 : : {
54 : : T1 first;
55 : : T2 second;
56 : :
57 : 3330 : Pair (T1 first, T2 second) : first (first), second (second) {}
58 : : };
59 : :
60 : : template <typename T1, typename T2, typename T3> struct Triple
61 : : {
62 : : T1 first;
63 : : T2 second;
64 : : T3 third;
65 : :
66 : 368 : Triple (T1 first, T2 second, T3 third)
67 : 368 : : first (first), second (second), third (third)
68 : : {}
69 : : };
70 : :
71 : : /** Frozen variant to vector for FFI */
72 : : template <typename T> struct Slice
73 : : {
74 : : size_t len;
75 : : const T *const data;
76 : :
77 : : template <typename vector>
78 : 36 : Slice (const vector &v) : len (v.size ()), data (v.data ())
79 : : {}
80 : : };
81 : :
82 : : /** Frozen variant of the facts with C ABI and no methods. */
83 : : struct FactsView
84 : : {
85 : : Slice<Triple<Origin, Loan, Point>> loan_issued_at;
86 : : Slice<Origin> universal_region;
87 : : Slice<Pair<Point, Point>> cfg_edge;
88 : : Slice<Pair<Loan, Point>> loan_killed_at;
89 : : Slice<Triple<Origin, Origin, Point>> subset_base;
90 : : Slice<Pair<Point, Loan>> loan_invalidated_at;
91 : : Slice<Pair<Variable, Point>> var_used_at;
92 : : Slice<Pair<Variable, Point>> var_defined_at;
93 : : Slice<Pair<Variable, Point>> var_dropped_at;
94 : : Slice<Pair<Variable, Origin>> use_of_var_derefs_origin;
95 : : Slice<Pair<Variable, Origin>> drop_of_var_derefs_origin;
96 : : Slice<Pair<Path, Path>> child_path;
97 : : Slice<Pair<Path, Variable>> path_is_var;
98 : : Slice<Pair<Path, Point>> path_assigned_at_base;
99 : : Slice<Pair<Path, Point>> path_moved_at_base;
100 : : Slice<Pair<Path, Point>> path_accessed_at_base;
101 : : Slice<Pair<Origin, Origin>> known_placeholder_subset;
102 : : Slice<Pair<Origin, Loan>> placeholder;
103 : : };
104 : :
105 : : // Wrapper around std::vector to pass data from Rust to C++
106 : 235 : template <typename T> struct FFIVector
107 : : {
108 : : std::vector<T> data;
109 : :
110 : : public:
111 : 48 : void push (T new_element) { data.push_back (new_element); };
112 : :
113 : : // allocates memory to a new instance and returns the pointer
114 : 127 : static FFIVector *make_new () { return new FFIVector{}; }
115 : :
116 : : // returns current size
117 : 19 : size_t size () const { return data.size (); }
118 : :
119 : 87 : T at (size_t index) const
120 : : {
121 : 87 : rust_assert (index < data.size ());
122 : 87 : return data.at (index);
123 : : }
124 : : };
125 : :
126 : : // Some useful type aliases
127 : : using FFIVectorPair = FFIVector<Pair<size_t, FFIVector<size_t> *>>;
128 : : using FFIVectorTriple = FFIVector<Triple<size_t, size_t, size_t>>;
129 : :
130 : : inline std::vector<size_t>
131 : 19 : make_vector (const FFIVector<size_t> *vec_sizet)
132 : : {
133 : 19 : std::vector<size_t> return_val (vec_sizet->size ());
134 : 38 : for (size_t i = 0; i < vec_sizet->size (); ++i)
135 : : {
136 : 19 : return_val[i] = vec_sizet->at (i);
137 : : }
138 : 19 : return return_val;
139 : : }
140 : :
141 : : inline std::vector<std::pair<size_t, std::vector<size_t>>>
142 : 72 : make_vector (const FFIVectorPair *vec_pair)
143 : : {
144 : 72 : std::vector<std::pair<size_t, std::vector<size_t>>> return_val (
145 : 72 : vec_pair->size ());
146 : 91 : for (size_t i = 0; i < vec_pair->size (); ++i)
147 : : {
148 : 19 : std::pair<size_t, std::vector<size_t>> current_pair
149 : 19 : = {vec_pair->at (i).first, make_vector (vec_pair->at (i).second)};
150 : 19 : return_val[i] = current_pair;
151 : 19 : }
152 : 72 : return return_val;
153 : : }
154 : :
155 : : inline std::vector<std::pair<size_t, std::pair<size_t, size_t>>>
156 : 36 : make_vector (const FFIVectorTriple *vec_triple)
157 : : {
158 : 36 : std::vector<std::pair<size_t, std::pair<size_t, size_t>>> return_val (
159 : 36 : vec_triple->size ());
160 : 46 : for (size_t i = 0; i < vec_triple->size (); ++i)
161 : : {
162 : 10 : auto current_element = std::pair<size_t, std::pair<size_t, size_t>>{
163 : 10 : vec_triple->at (i).first,
164 : 10 : {vec_triple->at (i).second, vec_triple->at (i).third}};
165 : 10 : return_val[i] = current_element;
166 : : }
167 : 36 : return return_val;
168 : : }
169 : :
170 : : struct Output
171 : : {
172 : : FFIVectorPair *loan_errors;
173 : : FFIVectorPair *move_errors;
174 : : FFIVectorTriple *subset_errors;
175 : : };
176 : :
177 : : } // namespace FFI
178 : : } // namespace Polonius
179 : : } // namespace Rust
180 : :
181 : : #endif // RUST_POLONIUS_FACTS_FFI_H
|