libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / rust / ast / rust-path.cc
blob9131962c16810d825fd36171a0825284db5e7fa6
1 /* General AST-related method implementations for Rust frontend.
2 Copyright (C) 2009-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "rust-system.h"
21 #include "rust-ast-full.h"
22 #include "rust-diagnostics.h"
23 #include "rust-ast-visitor.h"
24 #include "rust-macro.h"
25 #include "rust-session-manager.h"
26 #include "rust-lex.h"
27 #include "rust-parse.h"
28 #include "rust-operators.h"
30 namespace Rust {
31 namespace AST {
33 std::string
34 GenericArgs::as_string () const
36 std::string args;
38 // lifetime args
39 if (!lifetime_args.empty ())
41 auto i = lifetime_args.begin ();
42 auto e = lifetime_args.end ();
44 for (; i != e; i++)
46 args += (*i).as_string ();
47 if (e != i + 1)
48 args += ", ";
52 // type args
53 if (!generic_args.empty ())
55 auto i = generic_args.begin ();
56 auto e = generic_args.end ();
58 for (; i != e; i++)
60 args += (*i).as_string ();
61 if (e != i + 1)
62 args += ", ";
66 // binding args
67 if (!binding_args.empty ())
69 auto i = binding_args.begin ();
70 auto e = binding_args.end ();
72 for (; i != e; i++)
74 args += (*i).as_string ();
75 if (e != i + 1)
76 args += ", ";
80 return args;
83 GenericArg
84 GenericArg::disambiguate_to_const () const
86 rust_assert (get_kind () == Kind::Either);
88 // FIXME: is it fine to have no outer attributes?
89 return GenericArg::create_const (
90 std::unique_ptr<Expr> (new IdentifierExpr (path, {}, locus)));
93 GenericArg
94 GenericArg::disambiguate_to_type () const
96 rust_assert (get_kind () == Kind::Either);
98 auto segment = std::unique_ptr<TypePathSegment> (
99 new TypePathSegment (path.as_string (), false, locus));
100 auto segments = std::vector<std::unique_ptr<TypePathSegment>> ();
101 segments.emplace_back (std::move (segment));
103 return GenericArg::create_type (
104 std::unique_ptr<Type> (new TypePath (std::move (segments), locus)));
107 std::string
108 GenericArgsBinding::as_string () const
110 // TODO: rewrite to work with non-literalisable types
111 return identifier.as_string () + " = " + type->as_string ();
114 std::string
115 ConstGenericParam::as_string () const
117 std::string str ("ConstGenericParam: ");
118 str += "const " + name.as_string () + ": " + type->as_string ();
120 if (has_default_value ())
121 str += " = " + get_default_value ().as_string ();
123 return str;
126 std::string
127 PathExprSegment::as_string () const
129 // TODO: rewrite dump to work with non-literalisable types
130 std::string ident_str = segment_name.as_string ();
131 if (has_generic_args ())
132 ident_str += "::<" + generic_args.as_string () + ">";
134 return ident_str;
137 std::string
138 PathPattern::as_string () const
140 std::string str;
142 for (const auto &segment : segments)
143 str += segment.as_string () + "::";
145 // basically a hack - remove last two characters of string (remove final ::)
146 str.erase (str.length () - 2);
148 return str;
151 SimplePath
152 PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const
154 if (!has_segments ())
155 return SimplePath::create_empty ();
157 // create vector of reserved size (to minimise reallocations)
158 std::vector<SimplePathSegment> simple_segments;
159 simple_segments.reserve (segments.size ());
161 for (const auto &segment : segments)
163 // return empty path if doesn't meet simple path segment requirements
164 if (segment.is_error () || segment.has_generic_args ()
165 || segment.as_string () == "Self")
166 return SimplePath::create_empty ();
168 // create segment and add to vector
169 std::string segment_str = segment.as_string ();
170 simple_segments.push_back (
171 SimplePathSegment (std::move (segment_str), segment.get_locus ()));
174 // kind of a HACK to get locus depending on opening scope resolution
175 location_t locus = UNKNOWN_LOCATION;
176 if (with_opening_scope_resolution)
177 locus = simple_segments[0].get_locus () - 2; // minus 2 chars for ::
178 else
179 locus = simple_segments[0].get_locus ();
180 // FIXME: this hack probably doesn't actually work
182 return SimplePath (std::move (simple_segments), with_opening_scope_resolution,
183 locus);
186 void
187 PathInExpression::accept_vis (ASTVisitor &vis)
189 vis.visit (*this);
192 std::string
193 PathInExpression::as_string () const
195 std::string str;
197 if (has_opening_scope_resolution)
198 str = "::";
200 return str + PathPattern::as_string ();
203 std::string
204 TypePathSegmentGeneric::as_string () const
206 // TODO: rewrite to work with non-linearisable types
207 return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">";
210 std::string
211 TypePathSegmentFunction::as_string () const
213 // TODO: rewrite to work with non-linearisable types
214 return TypePathSegment::as_string () + function_path.as_string ();
217 std::string
218 TypePath::as_string () const
220 /* TODO: this may need to be rewritten if a segment (e.g. function) can't be
221 * literalised */
222 std::string str;
224 if (has_opening_scope_resolution)
225 str = "::";
227 for (const auto &segment : segments)
228 str += segment->as_string () + "::";
230 // kinda hack - remove last 2 '::' characters
231 str.erase (str.length () - 2);
233 return str;
236 SimplePath
237 TypePath::as_simple_path () const
239 if (segments.empty ())
240 return SimplePath::create_empty ();
242 // create vector of reserved size (to minimise reallocations)
243 std::vector<SimplePathSegment> simple_segments;
244 simple_segments.reserve (segments.size ());
246 for (const auto &segment : segments)
248 // return empty path if doesn't meet simple path segment requirements
249 if (segment == nullptr || segment->is_error ()
250 || !segment->is_ident_only () || segment->as_string () == "Self")
251 return SimplePath::create_empty ();
253 // create segment and add to vector
254 std::string segment_str = segment->as_string ();
255 simple_segments.push_back (
256 SimplePathSegment (std::move (segment_str), segment->get_locus ()));
259 return SimplePath (std::move (simple_segments), has_opening_scope_resolution,
260 locus);
263 // hopefully definition here will prevent circular dependency issue
264 TraitBound *
265 TypePath::to_trait_bound (bool in_parens) const
267 return new TraitBound (TypePath (*this), get_locus (), in_parens);
270 std::string
271 TypePathFunction::as_string () const
273 // TODO: rewrite to work with non-linearisable types
274 std::string str ("(");
276 if (has_inputs ())
278 auto i = inputs.begin ();
279 auto e = inputs.end ();
281 for (; i != e; i++)
283 str += (*i)->as_string ();
284 if (e != i + 1)
285 str += ", ";
289 str += ")";
291 if (has_return_type ())
292 str += " -> " + return_type->as_string ();
294 return str;
297 std::string
298 QualifiedPathInExpression::as_string () const
300 return path_type.as_string () + "::" + PathPattern::as_string ();
303 std::string
304 QualifiedPathInType::as_string () const
306 /* TODO: this may need adjusting if segments (e.g. with functions) can't be
307 * literalised */
308 std::string str = path_type.as_string ();
310 str += "::" + associated_segment->as_string ();
311 for (const auto &segment : segments)
312 str += "::" + segment->as_string ();
314 return str;
317 void
318 ConstGenericParam::accept_vis (ASTVisitor &vis)
320 vis.visit (*this);
323 void
324 TypePathSegment::accept_vis (ASTVisitor &vis)
326 vis.visit (*this);
329 void
330 TypePathSegmentGeneric::accept_vis (ASTVisitor &vis)
332 vis.visit (*this);
335 void
336 TypePathSegmentFunction::accept_vis (ASTVisitor &vis)
338 vis.visit (*this);
341 void
342 TypePath::accept_vis (ASTVisitor &vis)
344 vis.visit (*this);
347 void
348 QualifiedPathInExpression::accept_vis (ASTVisitor &vis)
350 vis.visit (*this);
353 void
354 QualifiedPathInType::accept_vis (ASTVisitor &vis)
356 vis.visit (*this);
359 } // namespace AST
360 } // namespace Rust