compiler: don't assume that ATTRIBUTE_UNUSED is defined
[official-gcc.git] / gcc / rust / util / rust-canonical-path.h
blob969ac7f7cc18c27345135d00b5719cc0ece5c4c5
1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
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.
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.
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/>.
19 #ifndef RUST_CANONICAL_PATH
20 #define RUST_CANONICAL_PATH
22 #include "rust-system.h"
23 #include "rust-mapping-common.h"
25 namespace Rust {
26 namespace Resolver {
28 // https://doc.rust-lang.org/reference/paths.html#canonical-paths
30 // struct X - path X
31 // impl X { fn test - path X::test }
33 // struct X<T> - path X
35 // impl X<T> { fn test - path X::test}
36 // impl X<i32> { fn test - path X<i32>::test }
37 // impl X<f32> { fn test - path X<f32>::test }
39 // pub trait Trait { // ::a::Trait
40 // fn f(&self); // ::a::Trait::f
41 // }
43 // impl Trait for Struct {
44 // fn f(&self) {} // <::a::Struct as ::a::Trait>::f
45 // }
46 class CanonicalPath
48 public:
49 CanonicalPath (const CanonicalPath &other) : segs (other.segs) {}
51 CanonicalPath &operator= (const CanonicalPath &other)
53 segs = other.segs;
54 crate_num = other.crate_num;
55 return *this;
58 static CanonicalPath new_seg (NodeId id, const std::string &path)
60 rust_assert (!path.empty ());
61 return CanonicalPath ({std::pair<NodeId, std::string> (id, path)},
62 UNKNOWN_CRATENUM);
65 static CanonicalPath
66 trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg,
67 const CanonicalPath &impl_type_seg)
69 return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as "
70 + trait_seg.get () + ">");
73 static CanonicalPath inherent_impl_seg (NodeId id,
74 const CanonicalPath &impl_type_seg)
76 return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + ">");
79 std::string get () const
81 std::string buf;
82 for (size_t i = 0; i < segs.size (); i++)
84 bool have_more = (i + 1) < segs.size ();
85 const std::string &seg = segs.at (i).second;
86 buf += seg + (have_more ? "::" : "");
88 return buf;
91 static CanonicalPath get_big_self (NodeId id)
93 return CanonicalPath::new_seg (id, "Self");
96 static CanonicalPath create_empty ()
98 return CanonicalPath ({}, UNKNOWN_CRATENUM);
101 bool is_empty () const { return segs.size () == 0; }
103 CanonicalPath append (const CanonicalPath &other) const
105 rust_assert (!other.is_empty ());
106 if (is_empty ())
107 return CanonicalPath (other.segs, crate_num);
109 std::vector<std::pair<NodeId, std::string>> copy (segs);
110 for (auto &s : other.segs)
111 copy.push_back (s);
113 return CanonicalPath (copy, crate_num);
116 // if we have the path A::B::C this will give a callback for each segment
117 // including the prefix, example:
119 // path:
120 // A::B::C
122 // iterate:
123 // A
124 // A::B
125 // A::B::C
126 void iterate (std::function<bool (const CanonicalPath &)> cb) const
128 std::vector<std::pair<NodeId, std::string>> buf;
129 for (auto &seg : segs)
131 buf.push_back (seg);
132 if (!cb (CanonicalPath (buf, crate_num)))
133 return;
137 // if we have the path A::B::C this will give a callback for each segment
138 // example:
140 // path:
141 // A::B::C
143 // iterate:
144 // A
145 // B
146 // C
147 void iterate_segs (std::function<bool (const CanonicalPath &)> cb) const
149 for (auto &seg : segs)
151 std::vector<std::pair<NodeId, std::string>> buf;
152 buf.push_back ({seg.first, seg.second});
153 if (!cb (CanonicalPath (buf, crate_num)))
154 return;
158 size_t size () const { return segs.size (); }
160 NodeId get_node_id () const
162 rust_assert (!segs.empty ());
163 return segs.back ().first;
166 const std::pair<NodeId, std::string> &get_seg_at (size_t index) const
168 rust_assert (index < size ());
169 return segs.at (index);
172 bool is_equal (const CanonicalPath &b) const
174 return get ().compare (b.get ()) == 0;
177 void set_crate_num (CrateNum n) { crate_num = n; }
179 CrateNum get_crate_num () const
181 rust_assert (crate_num != UNKNOWN_CRATENUM);
182 return crate_num;
185 bool operator== (const CanonicalPath &b) const { return is_equal (b); }
187 bool operator< (const CanonicalPath &b) const { return get () < b.get (); }
189 private:
190 explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path,
191 CrateNum crate_num)
192 : segs (path), crate_num (crate_num)
195 std::vector<std::pair<NodeId, std::string>> segs;
196 CrateNum crate_num;
199 } // namespace Resolver
200 } // namespace Rust
202 #endif // RUST_CANONICAL_PATH