Branch data Line data Source code
1 : : /* General AST-related method implementations for Rust frontend.
2 : : Copyright (C) 2009-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
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.
10 : :
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.
15 : :
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/>. */
19 : :
20 : : #include "rust-ast.h"
21 : : #include "optional.h"
22 : : #include "rust-builtin-ast-nodes.h"
23 : : #include "rust-common.h"
24 : : #include "rust-expr.h"
25 : : #include "rust-system.h"
26 : : #include "rust-ast-full.h"
27 : : #include "rust-diagnostics.h"
28 : : #include "rust-ast-visitor.h"
29 : : #include "rust-macro.h"
30 : : #include "rust-session-manager.h"
31 : : #include "rust-lex.h"
32 : : #include "rust-parse.h"
33 : : #include "rust-operators.h"
34 : : #include "rust-dir-owner.h"
35 : : #include "rust-attribute-values.h"
36 : : #include "rust-macro-invoc-lexer.h"
37 : :
38 : : /* Compilation unit used for various AST-related functions that would make
39 : : * the headers too long if they were defined inline and don't receive any
40 : : * benefits from being defined inline because they are virtual. Also used
41 : : * for various other stuff. */
42 : :
43 : : namespace Rust {
44 : : namespace AST {
45 : :
46 : 22956 : SingleASTNode::SingleASTNode (SingleASTNode const &other)
47 : : {
48 : 22956 : kind = other.kind;
49 : 22956 : switch (kind)
50 : : {
51 : 10138 : case EXPRESSION:
52 : 10138 : expr = other.expr->clone_expr ();
53 : 10138 : break;
54 : :
55 : 10332 : case ITEM:
56 : 10332 : item = other.item->clone_item ();
57 : 10332 : break;
58 : :
59 : 1906 : case STMT:
60 : 1906 : stmt = other.stmt->clone_stmt ();
61 : 1906 : break;
62 : :
63 : 12 : case EXTERN:
64 : 12 : external_item = other.external_item->clone_external_item ();
65 : 12 : break;
66 : :
67 : 428 : case ASSOC_ITEM:
68 : 428 : assoc_item = other.assoc_item->clone_associated_item ();
69 : 428 : break;
70 : :
71 : 140 : case TYPE:
72 : 140 : type = other.type->clone_type ();
73 : 140 : break;
74 : : }
75 : 22956 : }
76 : :
77 : : SingleASTNode
78 : 0 : SingleASTNode::operator= (SingleASTNode const &other)
79 : : {
80 : 0 : kind = other.kind;
81 : 0 : switch (kind)
82 : : {
83 : 0 : case EXPRESSION:
84 : 0 : expr = other.expr->clone_expr ();
85 : 0 : break;
86 : :
87 : 0 : case ITEM:
88 : 0 : item = other.item->clone_item ();
89 : 0 : break;
90 : :
91 : 0 : case STMT:
92 : 0 : stmt = other.stmt->clone_stmt ();
93 : 0 : break;
94 : :
95 : 0 : case EXTERN:
96 : 0 : external_item = other.external_item->clone_external_item ();
97 : 0 : break;
98 : :
99 : 0 : case ASSOC_ITEM:
100 : 0 : assoc_item = other.assoc_item->clone_associated_item ();
101 : 0 : break;
102 : :
103 : 0 : case TYPE:
104 : 0 : type = other.type->clone_type ();
105 : 0 : break;
106 : : }
107 : 0 : return *this;
108 : : }
109 : :
110 : : void
111 : 0 : SingleASTNode::accept_vis (ASTVisitor &vis)
112 : : {
113 : 0 : switch (kind)
114 : : {
115 : 0 : case EXPRESSION:
116 : 0 : expr->accept_vis (vis);
117 : 0 : break;
118 : :
119 : 0 : case ITEM:
120 : 0 : item->accept_vis (vis);
121 : 0 : break;
122 : :
123 : 0 : case STMT:
124 : 0 : stmt->accept_vis (vis);
125 : 0 : break;
126 : :
127 : 0 : case EXTERN:
128 : 0 : external_item->accept_vis (vis);
129 : 0 : break;
130 : :
131 : 0 : case ASSOC_ITEM:
132 : 0 : assoc_item->accept_vis (vis);
133 : 0 : break;
134 : :
135 : 0 : case TYPE:
136 : 0 : type->accept_vis (vis);
137 : 0 : break;
138 : : }
139 : 0 : }
140 : :
141 : : bool
142 : 8186 : SingleASTNode::is_error ()
143 : : {
144 : 8186 : switch (kind)
145 : : {
146 : 1880 : case EXPRESSION:
147 : 1880 : return expr == nullptr;
148 : 5160 : case ITEM:
149 : 5160 : return item == nullptr;
150 : 898 : case STMT:
151 : 898 : return stmt == nullptr;
152 : 6 : case EXTERN:
153 : 6 : return external_item == nullptr;
154 : 214 : case ASSOC_ITEM:
155 : 214 : return assoc_item == nullptr;
156 : 28 : case TYPE:
157 : 28 : return type == nullptr;
158 : : }
159 : :
160 : 0 : rust_unreachable ();
161 : : return true;
162 : : }
163 : :
164 : : std::string
165 : 0 : SingleASTNode::as_string () const
166 : : {
167 : 0 : switch (kind)
168 : : {
169 : 0 : case EXPRESSION:
170 : 0 : return "Expr: " + expr->as_string ();
171 : 0 : case ITEM:
172 : 0 : return "Item: " + item->as_string ();
173 : 0 : case STMT:
174 : 0 : return "Stmt: " + stmt->as_string ();
175 : 0 : case EXTERN:
176 : 0 : return "External Item: " + external_item->as_string ();
177 : 0 : case ASSOC_ITEM:
178 : 0 : return "Associated Item: " + assoc_item->as_string ();
179 : 0 : case TYPE:
180 : 0 : return "Type: " + type->as_string ();
181 : : }
182 : :
183 : 0 : rust_unreachable ();
184 : : return "";
185 : : }
186 : :
187 : : std::string
188 : 0 : Crate::as_string () const
189 : : {
190 : 0 : rust_debug ("beginning crate recursive as-string");
191 : :
192 : 0 : std::string str ("Crate: ");
193 : :
194 : : // inner attributes
195 : 0 : str += append_attributes (inner_attrs, INNER);
196 : :
197 : : // items
198 : 0 : str += "\n items: ";
199 : 0 : if (items.empty ())
200 : : {
201 : 0 : str += "none";
202 : : }
203 : : else
204 : : {
205 : 0 : for (const auto &item : items)
206 : : {
207 : : // DEBUG: null pointer check
208 : 0 : if (item == nullptr)
209 : : {
210 : 0 : rust_debug ("something really terrible has gone wrong - "
211 : : "null pointer item in crate.");
212 : 0 : return "NULL_POINTER_MARK";
213 : : }
214 : :
215 : 0 : str += "\n " + item->as_string ();
216 : : }
217 : : }
218 : :
219 : 0 : return str + "\n";
220 : 0 : }
221 : :
222 : : std::string
223 : 2110 : Attribute::as_string () const
224 : : {
225 : 2110 : std::string path_str = path.as_string ();
226 : 2110 : if (attr_input == nullptr)
227 : 0 : return path_str;
228 : : else
229 : 2110 : return path_str + attr_input->as_string ();
230 : 2110 : }
231 : :
232 : : bool
233 : 40580 : Attribute::is_derive () const
234 : : {
235 : 77079 : return has_attr_input () && get_path () == "derive";
236 : : }
237 : :
238 : : /**
239 : : * Returns a list of traits to derive from within a given attribute.
240 : : *
241 : : * @param attrs The attributes on the item to derive
242 : : */
243 : : std::vector<std::reference_wrapper<AST::SimplePath>>
244 : 253 : Attribute::get_traits_to_derive ()
245 : : {
246 : 253 : rust_assert (this->is_derive ());
247 : :
248 : 253 : this->parse_attr_to_meta_item ();
249 : 253 : std::vector<std::reference_wrapper<AST::SimplePath>> result;
250 : 253 : auto &input = get_attr_input ();
251 : 253 : switch (input.get_attr_input_type ())
252 : : {
253 : 253 : case AST::AttrInput::META_ITEM:
254 : 253 : {
255 : 253 : auto &meta = static_cast<AST::AttrInputMetaItemContainer &> (input);
256 : 734 : for (auto ¤t : meta.get_items ())
257 : : {
258 : : // HACK: Find a better way to achieve the downcast.
259 : 481 : switch (current->get_kind ())
260 : : {
261 : 481 : case AST::MetaItemInner::Kind::MetaItem:
262 : 481 : {
263 : : // Let raw pointer go out of scope without freeing, it doesn't
264 : : // own the data anyway
265 : 481 : auto meta_item
266 : 481 : = static_cast<AST::MetaItem *> (current.get ());
267 : 481 : switch (meta_item->get_item_kind ())
268 : : {
269 : 195 : case AST::MetaItem::ItemKind::Path:
270 : 195 : {
271 : 195 : auto path
272 : : = static_cast<AST::MetaItemPath *> (meta_item);
273 : 195 : result.push_back (path->get_path ());
274 : : }
275 : 195 : break;
276 : 286 : case AST::MetaItem::ItemKind::Word:
277 : 286 : {
278 : 286 : auto word = static_cast<AST::MetaWord *> (meta_item);
279 : : // Convert current word to path
280 : 858 : current = std::make_unique<AST::MetaItemPath> (
281 : 286 : AST::MetaItemPath (
282 : 572 : AST::SimplePath (word->get_ident ())));
283 : 286 : auto path
284 : 286 : = static_cast<AST::MetaItemPath *> (current.get ());
285 : :
286 : 286 : result.push_back (path->get_path ());
287 : : }
288 : 286 : break;
289 : 0 : case AST::MetaItem::ItemKind::ListPaths:
290 : 0 : case AST::MetaItem::ItemKind::NameValueStr:
291 : 0 : case AST::MetaItem::ItemKind::PathExpr:
292 : 0 : case AST::MetaItem::ItemKind::Seq:
293 : 0 : case AST::MetaItem::ItemKind::ListNameValueStr:
294 : 0 : default:
295 : 0 : gcc_unreachable ();
296 : 481 : break;
297 : : }
298 : : }
299 : 481 : break;
300 : 0 : case AST::MetaItemInner::Kind::LitExpr:
301 : 0 : default:
302 : 0 : gcc_unreachable ();
303 : 481 : break;
304 : : }
305 : : }
306 : : }
307 : : break;
308 : 0 : case AST::AttrInput::TOKEN_TREE:
309 : 0 : case AST::AttrInput::LITERAL:
310 : 0 : case AST::AttrInput::MACRO:
311 : 0 : rust_unreachable ();
312 : 253 : break;
313 : : }
314 : 253 : return result;
315 : : }
316 : :
317 : : // Copy constructor must deep copy attr_input as unique pointer
318 : 55930 : Attribute::Attribute (Attribute const &other)
319 : 55930 : : path (other.path), locus (other.locus),
320 : 55930 : inner_attribute (other.inner_attribute)
321 : : {
322 : : // guard to protect from null pointer dereference
323 : 55930 : if (other.attr_input != nullptr)
324 : 45795 : attr_input = other.attr_input->clone_attr_input ();
325 : 55930 : }
326 : :
327 : : // overload assignment operator to use custom clone method
328 : : Attribute &
329 : 64 : Attribute::operator= (Attribute const &other)
330 : : {
331 : 64 : path = other.path;
332 : 64 : locus = other.locus;
333 : 64 : inner_attribute = other.inner_attribute;
334 : : // guard to protect from null pointer dereference
335 : 64 : if (other.attr_input != nullptr)
336 : 57 : attr_input = other.attr_input->clone_attr_input ();
337 : : else
338 : 7 : attr_input = nullptr;
339 : :
340 : 64 : return *this;
341 : : }
342 : :
343 : : std::string
344 : 0 : DelimTokenTree::as_string () const
345 : : {
346 : 0 : std::string start_delim;
347 : 0 : std::string end_delim;
348 : 0 : switch (delim_type)
349 : : {
350 : 0 : case PARENS:
351 : 0 : start_delim = "(";
352 : 0 : end_delim = ")";
353 : 0 : break;
354 : 0 : case SQUARE:
355 : 0 : start_delim = "[";
356 : 0 : end_delim = "]";
357 : 0 : break;
358 : 0 : case CURLY:
359 : 0 : start_delim = "{";
360 : 0 : end_delim = "}";
361 : 0 : break;
362 : 0 : default:
363 : 0 : rust_debug ("Invalid delimiter type, "
364 : : "Should be PARENS, SQUARE, or CURLY.");
365 : 0 : return "Invalid delimiter type";
366 : : }
367 : 0 : std::string str = start_delim;
368 : 0 : if (!token_trees.empty ())
369 : : {
370 : 0 : for (const auto &tree : token_trees)
371 : : {
372 : : // DEBUG: null pointer check
373 : 0 : if (tree == nullptr)
374 : : {
375 : 0 : rust_debug (
376 : : "something really terrible has gone wrong - null pointer "
377 : : "token tree in delim token tree.");
378 : 0 : return "NULL_POINTER_MARK";
379 : : }
380 : :
381 : 0 : str += tree->as_string ();
382 : : }
383 : : }
384 : 0 : str += end_delim;
385 : :
386 : 0 : return str;
387 : 0 : }
388 : :
389 : : std::string
390 : 132450 : Token::as_string () const
391 : : {
392 : 132450 : if (tok_ref->has_str ())
393 : : {
394 : 37616 : std::string str = tok_ref->get_str ();
395 : :
396 : 37616 : std::string quote = is_string_lit () ? "\"" : "";
397 : 37616 : return quote + str + quote;
398 : 37616 : }
399 : : else
400 : : {
401 : 94834 : return tok_ref->get_token_description ();
402 : : }
403 : : }
404 : :
405 : : std::string
406 : 505999 : SimplePathSegment::as_string () const
407 : : {
408 : 505999 : return segment_name;
409 : : }
410 : :
411 : : const std::string
412 : 202625 : SimplePath::as_string () const
413 : : {
414 : 202625 : std::string path;
415 : 202625 : if (opening_scope_resolution)
416 : 0 : path = "::";
417 : :
418 : : // crappy hack because doing proper for loop would be more code
419 : 202625 : bool first_time = true;
420 : 405284 : for (const auto &segment : segments)
421 : : {
422 : 202659 : if (first_time)
423 : : {
424 : 405250 : path += segment.as_string ();
425 : 202625 : first_time = false;
426 : : }
427 : : else
428 : : {
429 : 68 : path += "::" + segment.as_string ();
430 : : }
431 : :
432 : : // DEBUG: remove later. Checks for path error.
433 : 202659 : if (segment.is_error ())
434 : : {
435 : 0 : rust_debug ("segment in path is error - this should've been filtered "
436 : : "out. first segment "
437 : : "was '%s'",
438 : : segments.at (0).as_string ().c_str ());
439 : : }
440 : : }
441 : :
442 : 202625 : return path;
443 : : }
444 : :
445 : : std::string
446 : 10 : Visibility::as_string () const
447 : : {
448 : 10 : switch (vis_type)
449 : : {
450 : 0 : case PRIV:
451 : 0 : return std::string ("");
452 : 10 : case PUB:
453 : 10 : return std::string ("pub");
454 : 0 : case PUB_CRATE:
455 : 0 : return std::string ("pub(crate)");
456 : 0 : case PUB_SELF:
457 : 0 : return std::string ("pub(self)");
458 : 0 : case PUB_SUPER:
459 : 0 : return std::string ("pub(super)");
460 : 0 : case PUB_IN_PATH:
461 : 0 : return std::string ("pub(in ") + in_path.as_string () + std::string (")");
462 : 0 : default:
463 : 0 : rust_unreachable ();
464 : : }
465 : : }
466 : :
467 : : // Creates a string that reflects the visibility stored.
468 : : std::string
469 : 0 : VisItem::as_string () const
470 : : {
471 : : // FIXME: can't do formatting on string to make identation occur.
472 : 0 : std::string str;
473 : :
474 : 0 : if (!outer_attrs.empty ())
475 : : {
476 : 0 : for (const auto &attr : outer_attrs)
477 : 0 : str += attr.as_string () + "\n";
478 : : }
479 : :
480 : 0 : if (has_visibility ())
481 : 0 : str += visibility.as_string () + " ";
482 : :
483 : 0 : return str;
484 : : }
485 : :
486 : : std::string
487 : 0 : Module::as_string () const
488 : : {
489 : 0 : std::string str = VisItem::as_string () + "mod " + module_name.as_string ();
490 : :
491 : : // Return early if we're dealing with an unloaded module as their body resides
492 : : // in a different file
493 : 0 : if (kind == ModuleKind::UNLOADED)
494 : 0 : return str + "\n no body (reference to external file)\n";
495 : :
496 : : // inner attributes
497 : 0 : str += append_attributes (inner_attrs, INNER);
498 : :
499 : : // items
500 : 0 : str += "\n items: ";
501 : :
502 : : // This can still happen if the module is loaded but empty, i.e. `mod foo {}`
503 : 0 : if (items.empty ())
504 : : {
505 : 0 : str += "none";
506 : : }
507 : : else
508 : : {
509 : 0 : for (const auto &item : items)
510 : : {
511 : : // DEBUG: null pointer check
512 : 0 : if (item == nullptr)
513 : : {
514 : 0 : rust_debug ("something really terrible has gone wrong - "
515 : : "null pointer item in crate.");
516 : 0 : return "NULL_POINTER_MARK";
517 : : }
518 : :
519 : 0 : str += "\n " + item->as_string ();
520 : : }
521 : : }
522 : :
523 : 0 : return str + "\n";
524 : 0 : }
525 : :
526 : : std::string
527 : 0 : StaticItem::as_string () const
528 : : {
529 : 0 : std::string str = VisItem::as_string ();
530 : :
531 : 0 : str += indent_spaces (stay) + "static";
532 : :
533 : 0 : if (has_mut)
534 : 0 : str += " mut";
535 : :
536 : 0 : str += " " + name.as_string ();
537 : :
538 : : // DEBUG: null pointer check
539 : 0 : if (type == nullptr)
540 : : {
541 : 0 : rust_debug ("something really terrible has gone wrong - null "
542 : : "pointer type in static item.");
543 : 0 : return "NULL_POINTER_MARK";
544 : : }
545 : 0 : str += "\n" + indent_spaces (stay) + "Type: " + type->as_string ();
546 : :
547 : : // DEBUG: null pointer check
548 : 0 : if (expr == nullptr)
549 : : {
550 : 0 : rust_debug ("something really terrible has gone wrong - null "
551 : : "pointer expr in static item.");
552 : 0 : return "NULL_POINTER_MARK";
553 : : }
554 : 0 : str += "\n" + indent_spaces (stay) + "Expression: " + expr->as_string ();
555 : :
556 : 0 : return str + "\n";
557 : 0 : }
558 : :
559 : : std::string
560 : 0 : ExternCrate::as_string () const
561 : : {
562 : 0 : std::string str = VisItem::as_string ();
563 : :
564 : 0 : str += "extern crate " + referenced_crate;
565 : :
566 : 0 : if (has_as_clause ())
567 : 0 : str += " as " + as_clause_name;
568 : :
569 : 0 : return str;
570 : : }
571 : :
572 : : std::string
573 : 0 : TupleStruct::as_string () const
574 : : {
575 : 0 : std::string str = VisItem::as_string ();
576 : :
577 : 0 : str += "struct " + struct_name.as_string ();
578 : :
579 : : // generic params
580 : 0 : str += "\n Generic params: ";
581 : 0 : if (generic_params.empty ())
582 : : {
583 : 0 : str += "none";
584 : : }
585 : : else
586 : : {
587 : 0 : for (const auto ¶m : generic_params)
588 : : {
589 : : // DEBUG: null pointer check
590 : 0 : if (param == nullptr)
591 : : {
592 : 0 : rust_debug (
593 : : "something really terrible has gone wrong - null pointer "
594 : : "generic param in enum.");
595 : 0 : return "NULL_POINTER_MARK";
596 : : }
597 : :
598 : 0 : str += "\n " + param->as_string ();
599 : : }
600 : : }
601 : :
602 : : // tuple fields
603 : 0 : str += "\n Tuple fields: ";
604 : 0 : if (fields.empty ())
605 : : {
606 : 0 : str += "none";
607 : : }
608 : : else
609 : : {
610 : 0 : for (const auto &field : fields)
611 : 0 : str += "\n " + field.as_string ();
612 : : }
613 : :
614 : 0 : str += "\n Where clause: ";
615 : 0 : if (has_where_clause ())
616 : 0 : str += where_clause.as_string ();
617 : : else
618 : 0 : str += "none";
619 : :
620 : 0 : return str;
621 : 0 : }
622 : :
623 : : std::string
624 : 0 : ConstantItem::as_string () const
625 : : {
626 : 0 : std::string str = VisItem::as_string ();
627 : :
628 : 0 : str += "const " + identifier.as_string ();
629 : :
630 : : // DEBUG: null pointer check
631 : 0 : if (type == nullptr)
632 : : {
633 : 0 : rust_debug ("something really terrible has gone wrong - null "
634 : : "pointer type in const item.");
635 : 0 : return "NULL_POINTER_MARK";
636 : : }
637 : 0 : str += "\n Type: " + type->as_string ();
638 : :
639 : : // DEBUG: null pointer check
640 : 0 : if (const_expr == nullptr)
641 : : {
642 : 0 : rust_debug ("something really terrible has gone wrong - null "
643 : : "pointer expr in const item.");
644 : 0 : return "NULL_POINTER_MARK";
645 : : }
646 : 0 : str += "\n Expression: " + const_expr->as_string ();
647 : :
648 : 0 : return str + "\n";
649 : 0 : }
650 : :
651 : : std::string
652 : 0 : InherentImpl::as_string () const
653 : : {
654 : 0 : std::string str = VisItem::as_string ();
655 : :
656 : 0 : str += "impl ";
657 : :
658 : : // generic params
659 : 0 : str += "\n Generic params: ";
660 : 0 : if (generic_params.empty ())
661 : : {
662 : 0 : str += "none";
663 : : }
664 : : else
665 : : {
666 : 0 : for (const auto ¶m : generic_params)
667 : : {
668 : : // DEBUG: null pointer check
669 : 0 : if (param == nullptr)
670 : : {
671 : 0 : rust_debug (
672 : : "something really terrible has gone wrong - null pointer "
673 : : "generic param in inherent impl.");
674 : 0 : return "NULL_POINTER_MARK";
675 : : }
676 : :
677 : 0 : str += "\n " + param->as_string ();
678 : : }
679 : : }
680 : :
681 : 0 : str += "\n Type: " + trait_type->as_string ();
682 : :
683 : 0 : str += "\n Where clause: ";
684 : 0 : if (has_where_clause ())
685 : 0 : str += where_clause.as_string ();
686 : : else
687 : 0 : str += "none";
688 : :
689 : : // inner attributes
690 : 0 : str += append_attributes (inner_attrs, INNER);
691 : :
692 : : // inherent impl items
693 : 0 : str += "\n Inherent impl items: ";
694 : 0 : if (!has_impl_items ())
695 : : {
696 : 0 : str += "none";
697 : : }
698 : : else
699 : : {
700 : 0 : for (const auto &item : impl_items)
701 : 0 : str += "\n " + item->as_string ();
702 : : }
703 : :
704 : 0 : return str;
705 : 0 : }
706 : :
707 : : std::string
708 : 0 : StructStruct::as_string () const
709 : : {
710 : 0 : std::string str = VisItem::as_string ();
711 : :
712 : 0 : str += "struct " + struct_name.as_string ();
713 : :
714 : : // generic params
715 : 0 : str += "\n Generic params: ";
716 : 0 : if (generic_params.empty ())
717 : : {
718 : 0 : str += "none";
719 : : }
720 : : else
721 : : {
722 : 0 : for (const auto ¶m : generic_params)
723 : : {
724 : : // DEBUG: null pointer check
725 : 0 : if (param == nullptr)
726 : : {
727 : 0 : rust_debug (
728 : : "something really terrible has gone wrong - null pointer "
729 : : "generic param in enum.");
730 : 0 : return "NULL_POINTER_MARK";
731 : : }
732 : :
733 : 0 : str += "\n " + param->as_string ();
734 : : }
735 : : }
736 : :
737 : 0 : str += "\n Where clause: ";
738 : 0 : if (has_where_clause ())
739 : 0 : str += where_clause.as_string ();
740 : : else
741 : 0 : str += "none";
742 : :
743 : : // struct fields
744 : 0 : str += "\n Struct fields: ";
745 : 0 : if (is_unit)
746 : : {
747 : 0 : str += "none (unit)";
748 : : }
749 : 0 : else if (fields.empty ())
750 : : {
751 : 0 : str += "none (non-unit)";
752 : : }
753 : : else
754 : : {
755 : 0 : for (const auto &field : fields)
756 : 0 : str += "\n " + field.as_string ();
757 : : }
758 : :
759 : 0 : return str;
760 : 0 : }
761 : :
762 : : std::string
763 : 0 : UseDeclaration::as_string () const
764 : : {
765 : 0 : std::string str = VisItem::as_string ();
766 : :
767 : : // DEBUG: null pointer check
768 : 0 : if (use_tree == nullptr)
769 : : {
770 : 0 : rust_debug (
771 : : "something really terrible has gone wrong - null pointer use tree in "
772 : : "use declaration.");
773 : 0 : return "NULL_POINTER_MARK";
774 : : }
775 : :
776 : 0 : str += "use " + use_tree->as_string ();
777 : :
778 : 0 : return str;
779 : 0 : }
780 : :
781 : : std::string
782 : 0 : UseTreeGlob::as_string () const
783 : : {
784 : 0 : switch (glob_type)
785 : : {
786 : 0 : case NO_PATH:
787 : 0 : return "*";
788 : 0 : case GLOBAL:
789 : 0 : return "::*";
790 : 0 : case PATH_PREFIXED:
791 : 0 : {
792 : 0 : std::string path_str = path.as_string ();
793 : 0 : return path_str + "::*";
794 : 0 : }
795 : 0 : default:
796 : : // some kind of error
797 : 0 : return "ERROR-PATH";
798 : : }
799 : : rust_unreachable ();
800 : : }
801 : :
802 : : std::string
803 : 0 : UseTreeList::as_string () const
804 : : {
805 : 0 : std::string path_str;
806 : 0 : switch (path_type)
807 : : {
808 : 0 : case NO_PATH:
809 : 0 : path_str = "{";
810 : 0 : break;
811 : 0 : case GLOBAL:
812 : 0 : path_str = "::{";
813 : 0 : break;
814 : 0 : case PATH_PREFIXED:
815 : 0 : {
816 : 0 : path_str = path.as_string () + "::{";
817 : 0 : break;
818 : : }
819 : 0 : default:
820 : : // some kind of error
821 : 0 : return "ERROR-PATH-LIST";
822 : : }
823 : :
824 : 0 : if (has_trees ())
825 : : {
826 : 0 : auto i = trees.begin ();
827 : 0 : auto e = trees.end ();
828 : :
829 : : // DEBUG: null pointer check
830 : 0 : if (*i == nullptr)
831 : : {
832 : 0 : rust_debug ("something really terrible has gone wrong - null pointer "
833 : : "tree in use tree list.");
834 : 0 : return "NULL_POINTER_MARK";
835 : : }
836 : :
837 : 0 : for (; i != e; i++)
838 : : {
839 : 0 : path_str += (*i)->as_string ();
840 : 0 : if (e != i + 1)
841 : 0 : path_str += ", ";
842 : : }
843 : : }
844 : : else
845 : : {
846 : 0 : path_str += "none";
847 : : }
848 : :
849 : 0 : return path_str + "}";
850 : 0 : }
851 : :
852 : : std::string
853 : 0 : UseTreeRebind::as_string () const
854 : : {
855 : 0 : std::string path_str = path.as_string ();
856 : :
857 : 0 : switch (bind_type)
858 : : {
859 : : case NONE:
860 : : // nothing to add, just path
861 : : break;
862 : 0 : case IDENTIFIER:
863 : 0 : path_str += " as " + identifier.as_string ();
864 : 0 : break;
865 : 0 : case WILDCARD:
866 : 0 : path_str += " as _";
867 : 0 : break;
868 : 0 : default:
869 : : // error
870 : 0 : return "ERROR-PATH-REBIND";
871 : : }
872 : :
873 : 0 : return path_str;
874 : 0 : }
875 : :
876 : : std::string
877 : 0 : Enum::as_string () const
878 : : {
879 : 0 : std::string str = VisItem::as_string ();
880 : 0 : str += enum_name.as_string ();
881 : :
882 : : // generic params
883 : 0 : str += "\n Generic params: ";
884 : 0 : if (generic_params.empty ())
885 : : {
886 : 0 : str += "none";
887 : : }
888 : : else
889 : : {
890 : 0 : for (const auto ¶m : generic_params)
891 : : {
892 : : // DEBUG: null pointer check
893 : 0 : if (param == nullptr)
894 : : {
895 : 0 : rust_debug (
896 : : "something really terrible has gone wrong - null pointer "
897 : : "generic param in enum.");
898 : 0 : return "NULL_POINTER_MARK";
899 : : }
900 : :
901 : 0 : str += "\n " + param->as_string ();
902 : : }
903 : : }
904 : :
905 : 0 : str += "\n Where clause: ";
906 : 0 : if (has_where_clause ())
907 : 0 : str += where_clause.as_string ();
908 : : else
909 : 0 : str += "none";
910 : :
911 : : // items
912 : 0 : str += "\n Items: ";
913 : 0 : if (items.empty ())
914 : : {
915 : 0 : str += "none";
916 : : }
917 : : else
918 : : {
919 : 0 : for (const auto &item : items)
920 : : {
921 : : // DEBUG: null pointer check
922 : 0 : if (item == nullptr)
923 : : {
924 : 0 : rust_debug (
925 : : "something really terrible has gone wrong - null pointer "
926 : : "enum item in enum.");
927 : 0 : return "NULL_POINTER_MARK";
928 : : }
929 : :
930 : 0 : str += "\n " + item->as_string ();
931 : : }
932 : : }
933 : :
934 : 0 : return str;
935 : 0 : }
936 : :
937 : : std::string
938 : 0 : Trait::as_string () const
939 : : {
940 : 0 : std::string str = VisItem::as_string ();
941 : :
942 : 0 : if (has_unsafe)
943 : 0 : str += "unsafe ";
944 : :
945 : 0 : str += "trait " + name.as_string ();
946 : :
947 : : // generic params
948 : 0 : str += "\n Generic params: ";
949 : 0 : if (generic_params.empty ())
950 : : {
951 : 0 : str += "none";
952 : : }
953 : : else
954 : : {
955 : 0 : for (const auto ¶m : generic_params)
956 : : {
957 : : // DEBUG: null pointer check
958 : 0 : if (param == nullptr)
959 : : {
960 : 0 : rust_debug (
961 : : "something really terrible has gone wrong - null pointer "
962 : : "generic param in trait.");
963 : 0 : return "NULL_POINTER_MARK";
964 : : }
965 : :
966 : 0 : str += "\n " + param->as_string ();
967 : : }
968 : : }
969 : :
970 : 0 : str += "\n Type param bounds: ";
971 : 0 : if (!has_type_param_bounds ())
972 : : {
973 : 0 : str += "none";
974 : : }
975 : : else
976 : : {
977 : 0 : for (const auto &bound : type_param_bounds)
978 : : {
979 : : // DEBUG: null pointer check
980 : 0 : if (bound == nullptr)
981 : : {
982 : 0 : rust_debug (
983 : : "something really terrible has gone wrong - null pointer "
984 : : "type param bound in trait.");
985 : 0 : return "NULL_POINTER_MARK";
986 : : }
987 : :
988 : 0 : str += "\n " + bound->as_string ();
989 : : }
990 : : }
991 : :
992 : 0 : str += "\n Where clause: ";
993 : 0 : if (!has_where_clause ())
994 : 0 : str += "none";
995 : : else
996 : 0 : str += where_clause.as_string ();
997 : :
998 : 0 : str += "\n Trait items: ";
999 : 0 : if (!has_trait_items ())
1000 : : {
1001 : 0 : str += "none";
1002 : : }
1003 : : else
1004 : : {
1005 : 0 : for (const auto &item : trait_items)
1006 : : {
1007 : : // DEBUG: null pointer check
1008 : 0 : if (item == nullptr)
1009 : : {
1010 : 0 : rust_debug (
1011 : : "something really terrible has gone wrong - null pointer "
1012 : : "trait item in trait.");
1013 : 0 : return "NULL_POINTER_MARK";
1014 : : }
1015 : :
1016 : 0 : str += "\n " + item->as_string ();
1017 : : }
1018 : : }
1019 : :
1020 : 0 : return str;
1021 : 0 : }
1022 : :
1023 : : std::string
1024 : 0 : Union::as_string () const
1025 : : {
1026 : 0 : std::string str = VisItem::as_string ();
1027 : :
1028 : 0 : str += "union " + union_name.as_string ();
1029 : :
1030 : : // generic params
1031 : 0 : str += "\n Generic params: ";
1032 : 0 : if (generic_params.empty ())
1033 : : {
1034 : 0 : str += "none";
1035 : : }
1036 : : else
1037 : : {
1038 : 0 : for (const auto ¶m : generic_params)
1039 : : {
1040 : : // DEBUG: null pointer check
1041 : 0 : if (param == nullptr)
1042 : : {
1043 : 0 : rust_debug (
1044 : : "something really terrible has gone wrong - null pointer "
1045 : : "generic param in union.");
1046 : 0 : return "NULL_POINTER_MARK";
1047 : : }
1048 : :
1049 : 0 : str += "\n " + param->as_string ();
1050 : : }
1051 : : }
1052 : :
1053 : 0 : str += "\n Where clause: ";
1054 : 0 : if (has_where_clause ())
1055 : 0 : str += where_clause.as_string ();
1056 : : else
1057 : 0 : str += "none";
1058 : :
1059 : : // struct fields
1060 : 0 : str += "\n Struct fields (variants): ";
1061 : 0 : if (variants.empty ())
1062 : : {
1063 : 0 : str += "none";
1064 : : }
1065 : : else
1066 : : {
1067 : 0 : for (const auto &field : variants)
1068 : 0 : str += "\n " + field.as_string ();
1069 : : }
1070 : :
1071 : 0 : return str;
1072 : 0 : }
1073 : :
1074 : 13218 : Function::Function (Function const &other)
1075 : 13218 : : VisItem (other), ExternalItem (other.get_node_id ()),
1076 : 13218 : qualifiers (other.qualifiers), function_name (other.function_name),
1077 : 13218 : where_clause (other.where_clause), locus (other.locus),
1078 : 13218 : has_default (other.has_default),
1079 : 26436 : is_external_function (other.is_external_function)
1080 : : {
1081 : : // guard to prevent null dereference (always required)
1082 : 13218 : if (other.return_type != nullptr)
1083 : 13107 : return_type = other.return_type->clone_type ();
1084 : :
1085 : : // guard to prevent null dereference (only required if error state)
1086 : 13218 : if (other.has_body ())
1087 : 13118 : function_body = other.function_body.value ()->clone_block_expr ();
1088 : : else
1089 : 100 : function_body = tl::nullopt;
1090 : :
1091 : 13218 : generic_params.reserve (other.generic_params.size ());
1092 : 13270 : for (const auto &e : other.generic_params)
1093 : 52 : generic_params.push_back (e->clone_generic_param ());
1094 : :
1095 : 13218 : function_params.reserve (other.function_params.size ());
1096 : 32858 : for (const auto &e : other.function_params)
1097 : 19640 : function_params.push_back (e->clone_param ());
1098 : 13218 : }
1099 : :
1100 : : Function &
1101 : 0 : Function::operator= (Function const &other)
1102 : : {
1103 : 0 : VisItem::operator= (other);
1104 : 0 : function_name = other.function_name;
1105 : 0 : qualifiers = other.qualifiers;
1106 : 0 : where_clause = other.where_clause;
1107 : : // visibility = other.visibility->clone_visibility();
1108 : : // outer_attrs = other.outer_attrs;
1109 : 0 : locus = other.locus;
1110 : 0 : has_default = other.has_default;
1111 : 0 : is_external_function = other.is_external_function;
1112 : :
1113 : : // guard to prevent null dereference (always required)
1114 : 0 : if (other.return_type != nullptr)
1115 : 0 : return_type = other.return_type->clone_type ();
1116 : : else
1117 : 0 : return_type = nullptr;
1118 : :
1119 : : // guard to prevent null dereference (only required if error state)
1120 : 0 : if (other.has_body ())
1121 : 0 : function_body = other.function_body.value ()->clone_block_expr ();
1122 : : else
1123 : 0 : function_body = tl::nullopt;
1124 : :
1125 : 0 : generic_params.reserve (other.generic_params.size ());
1126 : 0 : for (const auto &e : other.generic_params)
1127 : 0 : generic_params.push_back (e->clone_generic_param ());
1128 : :
1129 : 0 : function_params.reserve (other.function_params.size ());
1130 : 0 : for (const auto &e : other.function_params)
1131 : 0 : function_params.push_back (e->clone_param ());
1132 : :
1133 : 0 : return *this;
1134 : : }
1135 : : std::string
1136 : 0 : Function::as_string () const
1137 : : {
1138 : 0 : std::string str = VisItem::as_string () + "\n";
1139 : 0 : std::string qstr = qualifiers.as_string ();
1140 : 0 : if ("" != qstr)
1141 : 0 : str += qstr + " ";
1142 : :
1143 : 0 : if (has_return_type ())
1144 : : {
1145 : : // DEBUG: null pointer check
1146 : 0 : if (return_type == nullptr)
1147 : : {
1148 : : rust_debug (
1149 : : "something really terrible has gone wrong - null pointer return "
1150 : : "type in function.");
1151 : : return "NULL_POINTER_MARK";
1152 : : }
1153 : :
1154 : 0 : str += return_type->as_string () + " ";
1155 : : }
1156 : : else
1157 : : {
1158 : 0 : str += "void ";
1159 : : }
1160 : :
1161 : 0 : str += function_name.as_string ();
1162 : :
1163 : 0 : if (has_generics ())
1164 : : {
1165 : 0 : str += "<";
1166 : :
1167 : 0 : auto i = generic_params.begin ();
1168 : 0 : auto e = generic_params.end ();
1169 : :
1170 : : // DEBUG: null pointer check
1171 : 0 : if (i == e)
1172 : : {
1173 : 0 : rust_debug ("something really terrible has gone wrong - null pointer "
1174 : : "generic param in function item.");
1175 : 0 : return "NULL_POINTER_MARK";
1176 : : }
1177 : :
1178 : 0 : for (; i != e; i++)
1179 : : {
1180 : 0 : str += (*i)->as_string ();
1181 : 0 : if (e != i + 1)
1182 : 0 : str += ", ";
1183 : : }
1184 : 0 : str += ">";
1185 : : }
1186 : :
1187 : 0 : if (has_function_params ())
1188 : : {
1189 : 0 : auto i = function_params.begin ();
1190 : 0 : auto e = function_params.end ();
1191 : 0 : str += "(";
1192 : 0 : for (; i != e; i++)
1193 : : {
1194 : 0 : str += (*i)->as_string ();
1195 : 0 : if (e != i + 1)
1196 : 0 : str += ", ";
1197 : : }
1198 : 0 : str += ")";
1199 : : }
1200 : : else
1201 : : {
1202 : 0 : str += "()";
1203 : : }
1204 : :
1205 : 0 : if (has_where_clause ())
1206 : 0 : str += " where " + where_clause.as_string ();
1207 : :
1208 : 0 : str += "\n";
1209 : :
1210 : 0 : if (has_body ())
1211 : 0 : str += function_body.value ()->as_string () + "\n";
1212 : :
1213 : 0 : return str;
1214 : 0 : }
1215 : :
1216 : : std::string
1217 : 0 : WhereClause::as_string () const
1218 : : {
1219 : : // just print where clause items, don't mention "where" or "where clause"
1220 : 0 : std::string str;
1221 : :
1222 : 0 : if (where_clause_items.empty ())
1223 : : {
1224 : 0 : str = "none";
1225 : : }
1226 : : else
1227 : : {
1228 : 0 : for (const auto &item : where_clause_items)
1229 : 0 : str += "\n " + item->as_string ();
1230 : : }
1231 : :
1232 : 0 : return str;
1233 : : }
1234 : :
1235 : : std::string
1236 : 0 : BlockExpr::as_string () const
1237 : : {
1238 : 0 : std::string istr = indent_spaces (enter);
1239 : 0 : std::string str = istr + "BlockExpr:\n" + istr;
1240 : :
1241 : : // get outer attributes
1242 : 0 : str += append_attributes (outer_attrs, OUTER);
1243 : :
1244 : : // inner attributes
1245 : 0 : str += append_attributes (inner_attrs, INNER);
1246 : :
1247 : : // statements
1248 : 0 : str += "\n" + indent_spaces (stay) + "statements: ";
1249 : 0 : if (statements.empty ())
1250 : : {
1251 : 0 : str += "none";
1252 : : }
1253 : : else
1254 : : {
1255 : 0 : for (const auto &stmt : statements)
1256 : : {
1257 : : // DEBUG: null pointer check
1258 : 0 : if (stmt == nullptr)
1259 : : {
1260 : 0 : rust_debug (
1261 : : "something really terrible has gone wrong - null pointer "
1262 : : "stmt in block expr.");
1263 : 0 : return "NULL_POINTER_MARK";
1264 : : }
1265 : :
1266 : 0 : str += "\n" + indent_spaces (stay) + stmt->as_string ();
1267 : : }
1268 : : }
1269 : :
1270 : : // final expression
1271 : 0 : str += "\n" + indent_spaces (stay) + "final expression: ";
1272 : 0 : if (expr == nullptr)
1273 : 0 : str += "none";
1274 : : else
1275 : 0 : str += "\n" + expr->as_string ();
1276 : :
1277 : 0 : str += "\n" + indent_spaces (out);
1278 : 0 : return str;
1279 : 0 : }
1280 : :
1281 : : std::string
1282 : 0 : AnonConst::as_string () const
1283 : : {
1284 : 0 : std::string str = "AnonConst: ";
1285 : :
1286 : 0 : if (kind == AnonConst::Kind::DeferredInference)
1287 : 0 : str += "_";
1288 : : else
1289 : 0 : str += expr.value ()->as_string ();
1290 : :
1291 : 0 : return str;
1292 : : }
1293 : :
1294 : : std::string
1295 : 0 : ConstBlock::as_string () const
1296 : : {
1297 : 0 : return "ConstBlock: " + expr.as_string ();
1298 : : }
1299 : :
1300 : : std::string
1301 : 0 : TraitImpl::as_string () const
1302 : : {
1303 : 0 : std::string str = VisItem::as_string ();
1304 : :
1305 : 0 : if (has_unsafe)
1306 : 0 : str += "unsafe ";
1307 : :
1308 : 0 : str += "impl ";
1309 : :
1310 : : // generic params
1311 : 0 : str += "\n Generic params: ";
1312 : 0 : if (!has_generics ())
1313 : : {
1314 : 0 : str += "none";
1315 : : }
1316 : : else
1317 : : {
1318 : 0 : for (const auto ¶m : generic_params)
1319 : 0 : str += "\n " + param->as_string ();
1320 : : }
1321 : :
1322 : 0 : str += "\n Has exclam: ";
1323 : 0 : if (has_exclam)
1324 : 0 : str += "true";
1325 : : else
1326 : 0 : str += "false";
1327 : :
1328 : 0 : str += "\n TypePath (to trait): " + trait_path.as_string ();
1329 : :
1330 : 0 : str += "\n Type (struct to impl on): " + trait_type->as_string ();
1331 : :
1332 : 0 : str += "\n Where clause: ";
1333 : 0 : if (!has_where_clause ())
1334 : 0 : str += "none";
1335 : : else
1336 : 0 : str += where_clause.as_string ();
1337 : :
1338 : : // inner attributes
1339 : 0 : str += append_attributes (inner_attrs, INNER);
1340 : :
1341 : 0 : str += "\n trait impl items: ";
1342 : 0 : if (!has_impl_items ())
1343 : : {
1344 : 0 : str += "none";
1345 : : }
1346 : : else
1347 : : {
1348 : 0 : for (const auto &item : impl_items)
1349 : 0 : str += "\n " + item->as_string ();
1350 : : }
1351 : :
1352 : 0 : return str;
1353 : : }
1354 : :
1355 : : std::string
1356 : 0 : TypeAlias::as_string () const
1357 : : {
1358 : 0 : std::string str = VisItem::as_string ();
1359 : :
1360 : 0 : str += " " + new_type_name.as_string ();
1361 : :
1362 : : // generic params
1363 : 0 : str += "\n Generic params: ";
1364 : 0 : if (!has_generics ())
1365 : : {
1366 : 0 : str += "none";
1367 : : }
1368 : : else
1369 : : {
1370 : : auto i = generic_params.begin ();
1371 : : auto e = generic_params.end ();
1372 : :
1373 : 0 : for (; i != e; i++)
1374 : : {
1375 : 0 : str += (*i)->as_string ();
1376 : 0 : if (e != i + 1)
1377 : 0 : str += ", ";
1378 : : }
1379 : : }
1380 : :
1381 : 0 : str += "\n Where clause: ";
1382 : 0 : if (!has_where_clause ())
1383 : 0 : str += "none";
1384 : : else
1385 : 0 : str += where_clause.as_string ();
1386 : :
1387 : 0 : str += "\n Type: " + existing_type->as_string ();
1388 : :
1389 : 0 : return str;
1390 : : }
1391 : :
1392 : : std::string
1393 : 0 : ExternBlock::as_string () const
1394 : : {
1395 : 0 : std::string str = VisItem::as_string ();
1396 : :
1397 : 0 : str += "extern ";
1398 : 0 : if (has_abi ())
1399 : 0 : str += "\"" + abi + "\" ";
1400 : :
1401 : 0 : str += append_attributes (inner_attrs, INNER);
1402 : :
1403 : 0 : str += "\n external items: ";
1404 : 0 : if (!has_extern_items ())
1405 : : {
1406 : 0 : str += "none";
1407 : : }
1408 : : else
1409 : : {
1410 : 0 : for (const auto &item : extern_items)
1411 : 0 : str += "\n " + item->as_string ();
1412 : : }
1413 : :
1414 : 0 : return str;
1415 : : }
1416 : :
1417 : : std::string
1418 : 0 : MacroRule::as_string () const
1419 : : {
1420 : 0 : std::string str ("Macro rule: ");
1421 : :
1422 : 0 : str += "\n Matcher: \n ";
1423 : 0 : str += matcher.as_string ();
1424 : :
1425 : 0 : str += "\n Transcriber: \n ";
1426 : 0 : str += transcriber.as_string ();
1427 : :
1428 : 0 : return str;
1429 : : }
1430 : :
1431 : : std::string
1432 : 0 : MacroRulesDefinition::as_string () const
1433 : : {
1434 : 0 : std::string str;
1435 : :
1436 : : // get outer attrs
1437 : 0 : str += append_attributes (outer_attrs, OUTER);
1438 : :
1439 : : // TODO: deal with macro_2_0
1440 : 0 : str += "macro_rules!";
1441 : :
1442 : 0 : str += rule_name.as_string ();
1443 : :
1444 : 0 : str += "\n Macro rules: ";
1445 : 0 : if (rules.empty ())
1446 : : {
1447 : 0 : str += "none";
1448 : : }
1449 : : else
1450 : : {
1451 : 0 : for (const auto &rule : rules)
1452 : 0 : str += "\n " + rule.as_string ();
1453 : : }
1454 : :
1455 : 0 : str += "\n Delim type: ";
1456 : 0 : switch (delim_type)
1457 : : {
1458 : 0 : case PARENS:
1459 : 0 : str += "parentheses";
1460 : 0 : break;
1461 : 0 : case SQUARE:
1462 : 0 : str += "square";
1463 : 0 : break;
1464 : 0 : case CURLY:
1465 : 0 : str += "curly";
1466 : 0 : break;
1467 : 0 : default:
1468 : 0 : return "ERROR_MARK_STRING - delim type in macro invocation";
1469 : : }
1470 : :
1471 : 0 : return str;
1472 : 0 : }
1473 : :
1474 : : std::string
1475 : 0 : MacroInvocation::as_string () const
1476 : : {
1477 : 0 : std::string str = "MacroInvocation: ";
1478 : 0 : auto is_builtin = kind == InvocKind::Builtin;
1479 : :
1480 : 0 : if (is_builtin)
1481 : 0 : str += "[builtin] ";
1482 : : else
1483 : 0 : str += "[regular] ";
1484 : :
1485 : 0 : str += append_attributes (outer_attrs, OUTER);
1486 : :
1487 : 0 : str += "\n " + invoc_data.as_string ();
1488 : :
1489 : 0 : str += "\n has semicolon: ";
1490 : 0 : str += has_semicolon () ? "true" : "false";
1491 : :
1492 : 0 : if (is_builtin)
1493 : : {
1494 : 0 : str += "[PENDING EAGER INVOCATIONS]: ";
1495 : 0 : for (auto &pending : pending_eager_invocs)
1496 : : {
1497 : 0 : str += pending->as_string ();
1498 : 0 : str += "\n";
1499 : : }
1500 : : }
1501 : :
1502 : 0 : return str;
1503 : : }
1504 : :
1505 : : std::string
1506 : 0 : MacroInvocData::as_string () const
1507 : : {
1508 : 0 : return path.as_string () + "!" + token_tree.as_string ();
1509 : : }
1510 : :
1511 : : std::string
1512 : 0 : ExprStmt::as_string () const
1513 : : {
1514 : 0 : std::string str = indent_spaces (enter) + "ExprStmt: \n";
1515 : :
1516 : 0 : if (expr == nullptr)
1517 : : {
1518 : 0 : str += "none (this should not happen and is an error)";
1519 : : }
1520 : : else
1521 : : {
1522 : 0 : indent_spaces (enter);
1523 : 0 : str += expr->as_string ();
1524 : 0 : if (semicolon_followed)
1525 : 0 : str += ";";
1526 : 0 : indent_spaces (out);
1527 : : }
1528 : :
1529 : 0 : indent_spaces (out);
1530 : 0 : return str;
1531 : : }
1532 : :
1533 : : std::string
1534 : 0 : ClosureParam::as_string () const
1535 : : {
1536 : 0 : std::string str (pattern->as_string ());
1537 : :
1538 : 0 : if (has_type_given ())
1539 : 0 : str += " : " + type->as_string ();
1540 : :
1541 : 0 : return str;
1542 : : }
1543 : :
1544 : : std::string
1545 : 0 : ClosureExpr::as_string () const
1546 : : {
1547 : 0 : std::string str = "ClosureExpr:";
1548 : :
1549 : 0 : str += append_attributes (outer_attrs, OUTER);
1550 : :
1551 : 0 : str += "\n Has move: ";
1552 : 0 : if (has_move)
1553 : 0 : str += "true";
1554 : : else
1555 : 0 : str += "false";
1556 : :
1557 : 0 : str += "\n Params: ";
1558 : 0 : if (params.empty ())
1559 : : {
1560 : 0 : str += "none";
1561 : : }
1562 : : else
1563 : : {
1564 : 0 : for (const auto ¶m : params)
1565 : 0 : str += "\n " + param.as_string ();
1566 : : }
1567 : :
1568 : 0 : return str;
1569 : : }
1570 : :
1571 : : std::string
1572 : 0 : ClosureExprInnerTyped::as_string () const
1573 : : {
1574 : 0 : std::string str = ClosureExpr::as_string ();
1575 : :
1576 : 0 : str += "\n Return type: " + return_type->as_string ();
1577 : :
1578 : 0 : str += "\n Body: " + expr->as_string ();
1579 : :
1580 : 0 : return str;
1581 : : }
1582 : :
1583 : : std::string
1584 : 0 : QualifiedPathType::as_string () const
1585 : : {
1586 : 0 : std::string str ("<");
1587 : 0 : str += type_to_invoke_on->as_string ();
1588 : :
1589 : 0 : if (has_as_clause ())
1590 : 0 : str += " as " + trait_path.as_string ();
1591 : :
1592 : 0 : return str + ">";
1593 : 0 : }
1594 : :
1595 : : std::string
1596 : 0 : BorrowExpr::as_string () const
1597 : : {
1598 : : /* TODO: find way to incorporate outer attrs - may have to represent in
1599 : : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1600 : :
1601 : 0 : std::string str ("&");
1602 : :
1603 : 0 : if (raw_borrow)
1604 : : {
1605 : 0 : str += "raw ";
1606 : 0 : str += get_is_mut () ? "const " : "mut ";
1607 : : }
1608 : : else
1609 : : {
1610 : 0 : if (double_borrow)
1611 : 0 : str += "&";
1612 : :
1613 : 0 : if (get_is_mut ())
1614 : 0 : str += "mut ";
1615 : : }
1616 : 0 : str += main_or_left_expr->as_string ();
1617 : :
1618 : 0 : return str;
1619 : : }
1620 : :
1621 : : std::string
1622 : 0 : BoxExpr::as_string () const
1623 : : {
1624 : 0 : return "box " + expr->as_string ();
1625 : : }
1626 : :
1627 : : void
1628 : 16 : BoxExpr::accept_vis (ASTVisitor &vis)
1629 : : {
1630 : 16 : vis.visit (*this);
1631 : 16 : }
1632 : :
1633 : : std::string
1634 : 0 : ReturnExpr::as_string () const
1635 : : {
1636 : : /* TODO: find way to incorporate outer attrs - may have to represent in
1637 : : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1638 : :
1639 : 0 : std::string str ("return ");
1640 : :
1641 : 0 : if (has_returned_expr ())
1642 : 0 : str += return_expr->as_string ();
1643 : :
1644 : 0 : return str;
1645 : : }
1646 : :
1647 : : std::string
1648 : 0 : TryExpr::as_string () const
1649 : : {
1650 : : /* TODO: find way to incorporate outer attrs - may have to represent in
1651 : : * different style (i.e. something more like BorrowExpr: \n outer attrs) */
1652 : :
1653 : 0 : std::string str ("try ");
1654 : :
1655 : 0 : str += block_expr->as_string ();
1656 : :
1657 : 0 : return str;
1658 : : }
1659 : :
1660 : : std::string
1661 : 0 : RangeToExpr::as_string () const
1662 : : {
1663 : 0 : return ".." + to->as_string ();
1664 : : }
1665 : :
1666 : : std::string
1667 : 0 : ContinueExpr::as_string () const
1668 : : {
1669 : : // TODO: rewrite format to allow outer attributes
1670 : 0 : std::string str ("continue ");
1671 : :
1672 : 0 : if (has_label ())
1673 : 0 : str += get_label_unchecked ().as_string ();
1674 : :
1675 : 0 : return str;
1676 : : }
1677 : :
1678 : : std::string
1679 : 0 : NegationExpr::as_string () const
1680 : : {
1681 : : // TODO: rewrite formula to allow outer attributes
1682 : 0 : std::string str;
1683 : :
1684 : 0 : switch (expr_type)
1685 : : {
1686 : 0 : case NegationOperator::NEGATE:
1687 : 0 : str = "-";
1688 : 0 : break;
1689 : 0 : case NegationOperator::NOT:
1690 : 0 : str = "!";
1691 : 0 : break;
1692 : 0 : default:
1693 : 0 : return "ERROR_MARK_STRING - negation expr";
1694 : : }
1695 : :
1696 : 0 : str += main_or_left_expr->as_string ();
1697 : :
1698 : 0 : return str;
1699 : 0 : }
1700 : :
1701 : : std::string
1702 : 0 : RangeFromExpr::as_string () const
1703 : : {
1704 : 0 : return from->as_string () + "..";
1705 : : }
1706 : :
1707 : : std::string
1708 : 0 : RangeFullExpr::as_string () const
1709 : : {
1710 : 0 : return "..";
1711 : : }
1712 : :
1713 : : std::string
1714 : 0 : ArrayIndexExpr::as_string () const
1715 : : {
1716 : : // TODO: rewrite formula to allow outer attributes
1717 : 0 : return array_expr->as_string () + "[" + index_expr->as_string () + "]";
1718 : : }
1719 : :
1720 : : std::string
1721 : 0 : AssignmentExpr::as_string () const
1722 : : {
1723 : 0 : std::string str ("AssignmentExpr: ");
1724 : :
1725 : 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
1726 : : {
1727 : 0 : str += "error (either or both expressions are null)";
1728 : : }
1729 : : else
1730 : : {
1731 : : // left expr
1732 : 0 : str += "\n left: " + main_or_left_expr->as_string ();
1733 : :
1734 : : // right expr
1735 : 0 : str += "\n right: " + right_expr->as_string ();
1736 : : }
1737 : :
1738 : 0 : return str;
1739 : : }
1740 : :
1741 : : std::string
1742 : 0 : AsyncBlockExpr::as_string () const
1743 : : {
1744 : 0 : std::string str = "AsyncBlockExpr: ";
1745 : :
1746 : : // get outer attributes
1747 : : // str += "\n " + Expr::as_string ();
1748 : 0 : str += append_attributes (outer_attrs, OUTER);
1749 : :
1750 : 0 : str += "\n Has move: ";
1751 : 0 : str += has_move ? "true" : "false";
1752 : :
1753 : 0 : return str + "\n" + block_expr->as_string ();
1754 : 0 : }
1755 : :
1756 : : std::string
1757 : 0 : ComparisonExpr::as_string () const
1758 : : {
1759 : : // TODO: rewrite to better reflect non-literal expressions
1760 : 0 : std::string str (main_or_left_expr->as_string ());
1761 : :
1762 : 0 : switch (expr_type)
1763 : : {
1764 : 0 : case ComparisonOperator::EQUAL:
1765 : 0 : str += " == ";
1766 : 0 : break;
1767 : 0 : case ComparisonOperator::NOT_EQUAL:
1768 : 0 : str += " != ";
1769 : 0 : break;
1770 : 0 : case ComparisonOperator::GREATER_THAN:
1771 : 0 : str += " > ";
1772 : 0 : break;
1773 : 0 : case ComparisonOperator::LESS_THAN:
1774 : 0 : str += " < ";
1775 : 0 : break;
1776 : 0 : case ComparisonOperator::GREATER_OR_EQUAL:
1777 : 0 : str += " >= ";
1778 : 0 : break;
1779 : 0 : case ComparisonOperator::LESS_OR_EQUAL:
1780 : 0 : str += " <= ";
1781 : 0 : break;
1782 : 0 : default:
1783 : 0 : return "ERROR_MARK_STRING - comparison expr";
1784 : : }
1785 : :
1786 : 0 : str += right_expr->as_string ();
1787 : :
1788 : 0 : return str;
1789 : 0 : }
1790 : :
1791 : : std::string
1792 : 0 : MethodCallExpr::as_string () const
1793 : : {
1794 : 0 : std::string str = "MethodCallExpr: ";
1795 : :
1796 : 0 : str += append_attributes (outer_attrs, OUTER);
1797 : :
1798 : 0 : str += "\n Object (receiver) expr: \n";
1799 : 0 : str += receiver->as_string ();
1800 : :
1801 : 0 : str += "\n Method path segment: \n";
1802 : 0 : str += method_name.as_string ();
1803 : :
1804 : 0 : str += "\n Call params:";
1805 : 0 : if (params.empty ())
1806 : : {
1807 : 0 : str += "none";
1808 : : }
1809 : : else
1810 : : {
1811 : 0 : for (const auto ¶m : params)
1812 : : {
1813 : 0 : if (param == nullptr)
1814 : 0 : return "ERROR_MARK_STRING - method call expr param is null";
1815 : :
1816 : 0 : str += "\n " + param->as_string ();
1817 : : }
1818 : : }
1819 : :
1820 : 0 : return str;
1821 : 0 : }
1822 : :
1823 : : std::string
1824 : 0 : TupleIndexExpr::as_string () const
1825 : : {
1826 : : // TODO: rewrite dump to better reflect non-literal exprs
1827 : 0 : return tuple_expr->as_string () + "." + std::to_string (tuple_index);
1828 : : }
1829 : :
1830 : : std::string
1831 : 0 : DereferenceExpr::as_string () const
1832 : : {
1833 : : // TODO: rewrite dump to better reflect non-literal exprs
1834 : 0 : return "*" + main_or_left_expr->as_string ();
1835 : : }
1836 : :
1837 : : std::string
1838 : 0 : FieldAccessExpr::as_string () const
1839 : : {
1840 : : // TODO: rewrite dump to better reflect non-literal exprs
1841 : 0 : return receiver->as_string () + "." + field.as_string ();
1842 : : }
1843 : :
1844 : : std::string
1845 : 0 : LazyBooleanExpr::as_string () const
1846 : : {
1847 : : // TODO: rewrite dump to better reflect non-literal exprs
1848 : 0 : std::string str (main_or_left_expr->as_string ());
1849 : :
1850 : 0 : switch (expr_type)
1851 : : {
1852 : 0 : case LazyBooleanOperator::LOGICAL_OR:
1853 : 0 : str += " || ";
1854 : 0 : break;
1855 : 0 : case LazyBooleanOperator::LOGICAL_AND:
1856 : 0 : str += " && ";
1857 : 0 : break;
1858 : 0 : default:
1859 : 0 : return "ERROR_MARK_STRING - lazy boolean expr out of bounds";
1860 : : }
1861 : :
1862 : 0 : str += right_expr->as_string ();
1863 : :
1864 : 0 : return str;
1865 : 0 : }
1866 : :
1867 : : std::string
1868 : 0 : RangeFromToExpr::as_string () const
1869 : : {
1870 : : // TODO: rewrite dump to better reflect non-literal exprs
1871 : 0 : return from->as_string () + ".." + to->as_string ();
1872 : : }
1873 : :
1874 : : std::string
1875 : 0 : RangeToInclExpr::as_string () const
1876 : : {
1877 : : // TODO: rewrite dump to better reflect non-literal exprs
1878 : 0 : return "..=" + to->as_string ();
1879 : : }
1880 : :
1881 : : std::string
1882 : 0 : UnsafeBlockExpr::as_string () const
1883 : : {
1884 : 0 : std::string str = "UnsafeBlockExpr:" + indent_spaces (enter);
1885 : :
1886 : : // get outer attributes
1887 : 0 : str += append_attributes (outer_attrs, OUTER);
1888 : :
1889 : 0 : str += indent_spaces (stay) + expr->as_string () + "\n" + indent_spaces (out);
1890 : :
1891 : 0 : return str;
1892 : : }
1893 : :
1894 : : std::string
1895 : 0 : ClosureExprInner::as_string () const
1896 : : {
1897 : 0 : std::string str = ClosureExpr::as_string ();
1898 : :
1899 : 0 : str += "\n Expression: " + closure_inner->as_string ();
1900 : :
1901 : 0 : return str;
1902 : : }
1903 : :
1904 : : std::string
1905 : 0 : IfExpr::as_string () const
1906 : : {
1907 : 0 : std::string str = "IfExpr: ";
1908 : :
1909 : 0 : str += append_attributes (outer_attrs, OUTER);
1910 : :
1911 : 0 : str += "\n Condition expr: " + condition->as_string ();
1912 : :
1913 : 0 : str += "\n If block expr: " + if_block->as_string ();
1914 : :
1915 : 0 : return str;
1916 : : }
1917 : :
1918 : : std::string
1919 : 0 : IfExprConseqElse::as_string () const
1920 : : {
1921 : 0 : std::string str = IfExpr::as_string ();
1922 : :
1923 : 0 : str += "\n Else expr: " + else_block->as_string ();
1924 : :
1925 : 0 : return str;
1926 : : }
1927 : :
1928 : : std::string
1929 : 0 : IfLetExpr::as_string () const
1930 : : {
1931 : 0 : std::string str = "IfLetExpr: ";
1932 : :
1933 : 0 : str += append_attributes (outer_attrs, OUTER);
1934 : :
1935 : 0 : str += "\n Condition match arm patterns: ";
1936 : 0 : if (match_arm_patterns.empty ())
1937 : : {
1938 : 0 : str += "none";
1939 : : }
1940 : : else
1941 : : {
1942 : 0 : for (const auto &pattern : match_arm_patterns)
1943 : 0 : str += "\n " + pattern->as_string ();
1944 : : }
1945 : :
1946 : 0 : str += "\n Scrutinee expr: " + value->as_string ();
1947 : :
1948 : 0 : str += "\n If let block expr: " + if_block->as_string ();
1949 : :
1950 : 0 : return str;
1951 : : }
1952 : :
1953 : : std::string
1954 : 0 : IfLetExprConseqElse::as_string () const
1955 : : {
1956 : 0 : std::string str = IfLetExpr::as_string ();
1957 : :
1958 : 0 : str += "\n Else expr: " + else_block->as_string ();
1959 : :
1960 : 0 : return str;
1961 : : }
1962 : :
1963 : : std::string
1964 : 0 : RangeFromToInclExpr::as_string () const
1965 : : {
1966 : : // TODO: rewrite to allow dumps with non-literal exprs
1967 : 0 : return from->as_string () + "..=" + to->as_string ();
1968 : : }
1969 : :
1970 : : std::string
1971 : 0 : ErrorPropagationExpr::as_string () const
1972 : : {
1973 : : // TODO: rewrite to allow dumps with non-literal exprs
1974 : 0 : return main_or_left_expr->as_string () + "?";
1975 : : }
1976 : :
1977 : : std::string
1978 : 0 : CompoundAssignmentExpr::as_string () const
1979 : : {
1980 : 0 : std::string operator_str;
1981 : 0 : operator_str.reserve (1);
1982 : :
1983 : : // get operator string
1984 : 0 : switch (expr_type)
1985 : : {
1986 : 0 : case CompoundAssignmentOperator::ADD:
1987 : 0 : operator_str = "+";
1988 : 0 : break;
1989 : 0 : case CompoundAssignmentOperator::SUBTRACT:
1990 : 0 : operator_str = "-";
1991 : 0 : break;
1992 : 0 : case CompoundAssignmentOperator::MULTIPLY:
1993 : 0 : operator_str = "*";
1994 : 0 : break;
1995 : 0 : case CompoundAssignmentOperator::DIVIDE:
1996 : 0 : operator_str = "/";
1997 : 0 : break;
1998 : 0 : case CompoundAssignmentOperator::MODULUS:
1999 : 0 : operator_str = "%";
2000 : 0 : break;
2001 : 0 : case CompoundAssignmentOperator::BITWISE_AND:
2002 : 0 : operator_str = "&";
2003 : 0 : break;
2004 : 0 : case CompoundAssignmentOperator::BITWISE_OR:
2005 : 0 : operator_str = "|";
2006 : 0 : break;
2007 : 0 : case CompoundAssignmentOperator::BITWISE_XOR:
2008 : 0 : operator_str = "^";
2009 : 0 : break;
2010 : 0 : case CompoundAssignmentOperator::LEFT_SHIFT:
2011 : 0 : operator_str = "<<";
2012 : 0 : break;
2013 : 0 : case CompoundAssignmentOperator::RIGHT_SHIFT:
2014 : 0 : operator_str = ">>";
2015 : 0 : break;
2016 : 0 : default:
2017 : 0 : operator_str = "invalid operator. wtf";
2018 : 0 : break;
2019 : : }
2020 : :
2021 : 0 : operator_str += "=";
2022 : :
2023 : 0 : std::string str ("CompoundAssignmentExpr: ");
2024 : 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
2025 : : {
2026 : 0 : str += "error. this is probably a parsing failure.";
2027 : : }
2028 : : else
2029 : : {
2030 : 0 : str += "\n left: " + main_or_left_expr->as_string ();
2031 : 0 : str += "\n right: " + right_expr->as_string ();
2032 : 0 : str += "\n operator: " + operator_str;
2033 : : }
2034 : :
2035 : 0 : return str;
2036 : 0 : }
2037 : :
2038 : : std::string
2039 : 0 : ArithmeticOrLogicalExpr::as_string () const
2040 : : {
2041 : 0 : std::string operator_str;
2042 : 0 : operator_str.reserve (1);
2043 : :
2044 : : // get operator string
2045 : 0 : switch (expr_type)
2046 : : {
2047 : 0 : case ArithmeticOrLogicalOperator::ADD:
2048 : 0 : operator_str = "+";
2049 : 0 : break;
2050 : 0 : case ArithmeticOrLogicalOperator::SUBTRACT:
2051 : 0 : operator_str = "-";
2052 : 0 : break;
2053 : 0 : case ArithmeticOrLogicalOperator::MULTIPLY:
2054 : 0 : operator_str = "*";
2055 : 0 : break;
2056 : 0 : case ArithmeticOrLogicalOperator::DIVIDE:
2057 : 0 : operator_str = "/";
2058 : 0 : break;
2059 : 0 : case ArithmeticOrLogicalOperator::MODULUS:
2060 : 0 : operator_str = "%";
2061 : 0 : break;
2062 : 0 : case ArithmeticOrLogicalOperator::BITWISE_AND:
2063 : 0 : operator_str = "&";
2064 : 0 : break;
2065 : 0 : case ArithmeticOrLogicalOperator::BITWISE_OR:
2066 : 0 : operator_str = "|";
2067 : 0 : break;
2068 : 0 : case ArithmeticOrLogicalOperator::BITWISE_XOR:
2069 : 0 : operator_str = "^";
2070 : 0 : break;
2071 : 0 : case ArithmeticOrLogicalOperator::LEFT_SHIFT:
2072 : 0 : operator_str = "<<";
2073 : 0 : break;
2074 : 0 : case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
2075 : 0 : operator_str = ">>";
2076 : 0 : break;
2077 : 0 : default:
2078 : 0 : operator_str = "invalid operator. wtf";
2079 : 0 : break;
2080 : : }
2081 : :
2082 : 0 : std::string str ("ArithmeticOrLogicalExpr: ");
2083 : 0 : if (main_or_left_expr == nullptr || right_expr == nullptr)
2084 : : {
2085 : 0 : str += "error. this is probably a parsing failure.";
2086 : : }
2087 : : else
2088 : : {
2089 : 0 : str += main_or_left_expr->as_string () + " ";
2090 : 0 : str += operator_str + " ";
2091 : 0 : str += right_expr->as_string ();
2092 : : }
2093 : :
2094 : 0 : return str;
2095 : 0 : }
2096 : :
2097 : : std::string
2098 : 0 : CallExpr::as_string () const
2099 : : {
2100 : 0 : std::string str = "CallExpr: ";
2101 : :
2102 : 0 : str += append_attributes (outer_attrs, OUTER);
2103 : :
2104 : 0 : str += "\n Function expr: ";
2105 : 0 : str += function->as_string ();
2106 : :
2107 : 0 : str += "\n Call params:";
2108 : 0 : if (!has_params ())
2109 : : {
2110 : 0 : str += "none";
2111 : : }
2112 : : else
2113 : : {
2114 : 0 : for (const auto ¶m : params)
2115 : : {
2116 : 0 : if (param == nullptr)
2117 : 0 : return "ERROR_MARK_STRING - call expr param is null";
2118 : :
2119 : 0 : str += "\n " + param->as_string ();
2120 : : }
2121 : : }
2122 : :
2123 : 0 : return str;
2124 : 0 : }
2125 : :
2126 : : std::string
2127 : 0 : WhileLoopExpr::as_string () const
2128 : : {
2129 : 0 : std::string str = "WhileLoopExpr: ";
2130 : :
2131 : 0 : str += append_attributes (outer_attrs, OUTER);
2132 : :
2133 : 0 : str += "\n Label: ";
2134 : 0 : if (!has_loop_label ())
2135 : 0 : str += "none";
2136 : : else
2137 : 0 : str += get_loop_label ().as_string ();
2138 : :
2139 : 0 : str += "\n Conditional expr: " + condition->as_string ();
2140 : :
2141 : 0 : str += "\n Loop block: " + loop_block->as_string ();
2142 : :
2143 : 0 : return str;
2144 : : }
2145 : :
2146 : : std::string
2147 : 0 : WhileLetLoopExpr::as_string () const
2148 : : {
2149 : 0 : std::string str = "WhileLetLoopExpr: ";
2150 : :
2151 : 0 : str += append_attributes (outer_attrs, OUTER);
2152 : :
2153 : 0 : str += "\n Label: ";
2154 : 0 : if (!has_loop_label ())
2155 : 0 : str += "none";
2156 : : else
2157 : 0 : str += get_loop_label ().as_string ();
2158 : :
2159 : 0 : str += "\n Match arm patterns: ";
2160 : 0 : if (match_arm_patterns.empty ())
2161 : : {
2162 : 0 : str += "none";
2163 : : }
2164 : : else
2165 : : {
2166 : 0 : for (const auto &pattern : match_arm_patterns)
2167 : 0 : str += "\n " + pattern->as_string ();
2168 : : }
2169 : :
2170 : 0 : str += "\n Scrutinee expr: " + scrutinee->as_string ();
2171 : :
2172 : 0 : str += "\n Loop block: " + loop_block->as_string ();
2173 : :
2174 : 0 : return str;
2175 : : }
2176 : :
2177 : : std::string
2178 : 0 : LoopExpr::as_string () const
2179 : : {
2180 : 0 : std::string str = "LoopExpr: (infinite loop)";
2181 : :
2182 : 0 : str += append_attributes (outer_attrs, OUTER);
2183 : :
2184 : 0 : str += "\n Label: ";
2185 : 0 : if (!has_loop_label ())
2186 : 0 : str += "none";
2187 : : else
2188 : 0 : str += get_loop_label ().as_string ();
2189 : :
2190 : 0 : str += "\n Loop block: " + loop_block->as_string ();
2191 : :
2192 : 0 : return str;
2193 : : }
2194 : :
2195 : : std::string
2196 : 0 : ArrayExpr::as_string () const
2197 : : {
2198 : 0 : std::string str = "ArrayExpr:";
2199 : :
2200 : 0 : str += append_attributes (outer_attrs, OUTER);
2201 : :
2202 : : // inner attributes
2203 : 0 : str += append_attributes (inner_attrs, INNER);
2204 : :
2205 : 0 : str += "\n Array elems: ";
2206 : 0 : str += internal_elements->as_string ();
2207 : :
2208 : 0 : return str;
2209 : : }
2210 : :
2211 : : std::string
2212 : 0 : AwaitExpr::as_string () const
2213 : : {
2214 : : // TODO: rewrite dump to allow non-literal exprs
2215 : 0 : return awaited_expr->as_string () + ".await";
2216 : : }
2217 : :
2218 : : std::string
2219 : 0 : BreakExpr::as_string () const
2220 : : {
2221 : : // TODO: rewrite dump to allow outer attrs, non-literal exprs
2222 : 0 : std::string str ("break ");
2223 : :
2224 : 0 : if (has_label ())
2225 : 0 : str += get_label_unchecked ().as_string () + " ";
2226 : :
2227 : 0 : if (has_break_expr ())
2228 : 0 : str += break_expr->as_string ();
2229 : :
2230 : 0 : return str;
2231 : : }
2232 : :
2233 : : std::string
2234 : 0 : LoopLabel::as_string () const
2235 : : {
2236 : 0 : return label.as_string () + ": (label) ";
2237 : : }
2238 : :
2239 : : std::string
2240 : 0 : MatchArm::as_string () const
2241 : : {
2242 : : // outer attributes
2243 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
2244 : :
2245 : 0 : str += "\nPatterns: ";
2246 : 0 : if (match_arm_patterns.empty ())
2247 : : {
2248 : 0 : str += "none";
2249 : : }
2250 : : else
2251 : : {
2252 : 0 : for (const auto &pattern : match_arm_patterns)
2253 : 0 : str += "\n " + pattern->as_string ();
2254 : : }
2255 : :
2256 : 0 : str += "\nGuard expr: ";
2257 : 0 : if (!has_match_arm_guard ())
2258 : 0 : str += "none";
2259 : : else
2260 : 0 : str += guard_expr->as_string ();
2261 : :
2262 : 0 : return str;
2263 : : }
2264 : :
2265 : : std::string
2266 : 0 : MatchCase::as_string () const
2267 : : {
2268 : 0 : std::string str ("MatchCase: (match arm) ");
2269 : :
2270 : 0 : str += "\n Match arm matcher: \n" + arm.as_string ();
2271 : 0 : str += "\n Expr: " + expr->as_string ();
2272 : :
2273 : 0 : return str;
2274 : : }
2275 : :
2276 : : std::string
2277 : 0 : MatchExpr::as_string () const
2278 : : {
2279 : 0 : std::string str ("MatchExpr:");
2280 : :
2281 : 0 : str += append_attributes (outer_attrs, OUTER);
2282 : :
2283 : 0 : str += "\n Scrutinee expr: " + branch_value->as_string ();
2284 : :
2285 : : // inner attributes
2286 : 0 : str += append_attributes (inner_attrs, INNER);
2287 : :
2288 : : // match arms
2289 : 0 : str += "\n Match arms: ";
2290 : 0 : if (match_arms.empty ())
2291 : : {
2292 : 0 : str += "none";
2293 : : }
2294 : : else
2295 : : {
2296 : 0 : for (const auto &arm : match_arms)
2297 : 0 : str += "\n " + arm.as_string ();
2298 : : }
2299 : :
2300 : 0 : return str;
2301 : : }
2302 : :
2303 : : std::string
2304 : 0 : TupleExpr::as_string () const
2305 : : {
2306 : 0 : std::string str ("TupleExpr:");
2307 : :
2308 : 0 : str += append_attributes (outer_attrs, OUTER);
2309 : :
2310 : : // inner attributes
2311 : 0 : str += append_attributes (inner_attrs, INNER);
2312 : :
2313 : 0 : str += "\n Tuple elements: ";
2314 : 0 : if (tuple_elems.empty ())
2315 : : {
2316 : 0 : str += "none";
2317 : : }
2318 : : else
2319 : : {
2320 : 0 : for (const auto &elem : tuple_elems)
2321 : 0 : str += "\n " + elem->as_string ();
2322 : : }
2323 : :
2324 : 0 : return str;
2325 : : }
2326 : :
2327 : : std::string
2328 : 0 : FunctionParam::as_string () const
2329 : : {
2330 : : // TODO: rewrite dump to allow non-literal types
2331 : 0 : return param_name->as_string () + " : " + type->as_string ();
2332 : : }
2333 : :
2334 : : void
2335 : 186069 : FunctionParam::accept_vis (ASTVisitor &vis)
2336 : : {
2337 : 186069 : vis.visit (*this);
2338 : 186069 : }
2339 : :
2340 : : void
2341 : 144648 : SelfParam::accept_vis (ASTVisitor &vis)
2342 : : {
2343 : 144648 : vis.visit (*this);
2344 : 144648 : }
2345 : :
2346 : : void
2347 : 11932 : VariadicParam::accept_vis (ASTVisitor &vis)
2348 : : {
2349 : 11932 : vis.visit (*this);
2350 : 11932 : }
2351 : :
2352 : : std::string
2353 : 0 : VariadicParam::as_string () const
2354 : : {
2355 : 0 : if (has_pattern ())
2356 : 0 : return get_pattern ().as_string () + " : ...";
2357 : : else
2358 : 0 : return "...";
2359 : : }
2360 : :
2361 : : std::string
2362 : 0 : FunctionQualifiers::as_string () const
2363 : : {
2364 : 0 : std::string str;
2365 : :
2366 : 0 : if (is_async ())
2367 : 0 : str += "async ";
2368 : 0 : if (is_const ())
2369 : 0 : str += "const ";
2370 : 0 : if (is_unsafe ())
2371 : 0 : str += "unsafe ";
2372 : :
2373 : 0 : if (has_extern)
2374 : : {
2375 : 0 : str += "extern";
2376 : 0 : if (extern_abi != "")
2377 : 0 : str += " \"" + extern_abi + "\"";
2378 : : }
2379 : :
2380 : 0 : return str;
2381 : : }
2382 : :
2383 : : std::string
2384 : 0 : TraitBound::as_string () const
2385 : : {
2386 : 0 : std::string str ("TraitBound:");
2387 : :
2388 : 0 : str += "\n Has opening question mark: ";
2389 : 0 : if (opening_question_mark)
2390 : 0 : str += "true";
2391 : : else
2392 : 0 : str += "false";
2393 : :
2394 : 0 : str += "\n For lifetimes: ";
2395 : 0 : if (!has_for_lifetimes ())
2396 : : {
2397 : 0 : str += "none";
2398 : : }
2399 : : else
2400 : : {
2401 : 0 : for (const auto &lifetime : for_lifetimes)
2402 : 0 : str += "\n " + lifetime.as_string ();
2403 : : }
2404 : :
2405 : 0 : str += "\n Type path: " + type_path.as_string ();
2406 : :
2407 : 0 : return str;
2408 : : }
2409 : :
2410 : : std::string
2411 : 0 : MacroMatcher::as_string () const
2412 : : {
2413 : 0 : std::string str ("Macro matcher: ");
2414 : :
2415 : 0 : str += "\n Delim type: ";
2416 : :
2417 : 0 : switch (delim_type)
2418 : : {
2419 : 0 : case PARENS:
2420 : 0 : str += "parentheses";
2421 : 0 : break;
2422 : 0 : case SQUARE:
2423 : 0 : str += "square";
2424 : 0 : break;
2425 : 0 : case CURLY:
2426 : 0 : str += "curly";
2427 : 0 : break;
2428 : 0 : default:
2429 : 0 : return "ERROR_MARK_STRING - macro matcher delim";
2430 : : }
2431 : :
2432 : 0 : str += "\n Matches: ";
2433 : :
2434 : 0 : if (matches.empty ())
2435 : : {
2436 : 0 : str += "none";
2437 : : }
2438 : : else
2439 : : {
2440 : 0 : for (const auto &match : matches)
2441 : 0 : str += "\n " + match->as_string ();
2442 : : }
2443 : :
2444 : 0 : return str;
2445 : 0 : }
2446 : :
2447 : : std::string
2448 : 0 : LifetimeParam::as_string () const
2449 : : {
2450 : 0 : std::string str ("LifetimeParam: ");
2451 : :
2452 : 0 : str += "\n Outer attribute:";
2453 : 0 : if (!has_outer_attribute ())
2454 : 0 : str += "none";
2455 : 0 : for (auto &attr : outer_attrs)
2456 : 0 : str += " " + attr.as_string ();
2457 : :
2458 : 0 : str += "\n Lifetime: " + lifetime.as_string ();
2459 : :
2460 : 0 : str += "\n Lifetime bounds: ";
2461 : 0 : if (!has_lifetime_bounds ())
2462 : : {
2463 : 0 : str += "none";
2464 : : }
2465 : : else
2466 : : {
2467 : 0 : for (const auto &bound : lifetime_bounds)
2468 : 0 : str += "\n " + bound.as_string ();
2469 : : }
2470 : :
2471 : 0 : return str;
2472 : : }
2473 : :
2474 : : std::string
2475 : 0 : MacroMatchFragment::as_string () const
2476 : : {
2477 : 0 : return "$" + ident.as_string () + ": " + frag_spec.as_string ();
2478 : : }
2479 : :
2480 : : std::string
2481 : 0 : MacroMatchRepetition::as_string () const
2482 : : {
2483 : 0 : std::string str ("Macro match repetition: ");
2484 : :
2485 : 0 : str += "\n Matches: ";
2486 : 0 : if (matches.empty ())
2487 : : {
2488 : 0 : str += "none";
2489 : : }
2490 : : else
2491 : : {
2492 : 0 : for (const auto &match : matches)
2493 : 0 : str += "\n " + match->as_string ();
2494 : : }
2495 : :
2496 : 0 : str += "\n Sep: ";
2497 : 0 : if (!has_sep ())
2498 : 0 : str += "none";
2499 : : else
2500 : 0 : str += sep->as_string ();
2501 : :
2502 : 0 : str += "\n Op: ";
2503 : 0 : switch (op)
2504 : : {
2505 : 0 : case ANY:
2506 : 0 : str += "*";
2507 : 0 : break;
2508 : 0 : case ONE_OR_MORE:
2509 : 0 : str += "+";
2510 : 0 : break;
2511 : 0 : case ZERO_OR_ONE:
2512 : 0 : str += "?";
2513 : 0 : break;
2514 : 0 : case NONE:
2515 : 0 : str += "no op? shouldn't be allowed";
2516 : 0 : break;
2517 : 0 : default:
2518 : 0 : return "ERROR_MARK_STRING - unknown op in macro match repetition";
2519 : : }
2520 : :
2521 : 0 : return str;
2522 : 0 : }
2523 : :
2524 : : std::string
2525 : 82 : Lifetime::as_string () const
2526 : : {
2527 : 82 : switch (lifetime_type)
2528 : : {
2529 : 82 : case NAMED:
2530 : 82 : return "'" + lifetime_name;
2531 : 0 : case STATIC:
2532 : 0 : return "'static";
2533 : 0 : case WILDCARD:
2534 : 0 : return "'_";
2535 : 0 : default:
2536 : 0 : return "ERROR-MARK-STRING: lifetime type failure";
2537 : : }
2538 : : }
2539 : :
2540 : : std::string
2541 : 0 : TypeParam::as_string () const
2542 : : {
2543 : 0 : std::string str ("TypeParam: ");
2544 : :
2545 : 0 : str += "\n Outer attribute:";
2546 : 0 : if (!has_outer_attribute ())
2547 : 0 : str += "none";
2548 : 0 : for (auto &attr : outer_attrs)
2549 : 0 : str += " " + attr.as_string ();
2550 : :
2551 : 0 : str += "\n Identifier: " + type_representation.as_string ();
2552 : :
2553 : 0 : str += "\n Type param bounds: ";
2554 : 0 : if (!has_type_param_bounds ())
2555 : : {
2556 : 0 : str += "none";
2557 : : }
2558 : : else
2559 : : {
2560 : 0 : for (const auto &bound : type_param_bounds)
2561 : 0 : str += "\n " + bound->as_string ();
2562 : : }
2563 : :
2564 : 0 : str += "\n Type: ";
2565 : 0 : if (!has_type ())
2566 : 0 : str += "none";
2567 : : else
2568 : 0 : str += type->as_string ();
2569 : :
2570 : 0 : return str;
2571 : : }
2572 : :
2573 : : std::string
2574 : 0 : ForLoopExpr::as_string () const
2575 : : {
2576 : 0 : std::string str = "ForLoopExpr: ";
2577 : :
2578 : 0 : str += append_attributes (outer_attrs, OUTER);
2579 : :
2580 : 0 : str += "\n Label: ";
2581 : 0 : if (!has_loop_label ())
2582 : 0 : str += "none";
2583 : : else
2584 : 0 : str += get_loop_label ().as_string ();
2585 : :
2586 : 0 : str += "\n Pattern: " + pattern->as_string ();
2587 : :
2588 : 0 : str += "\n Iterator expr: " + iterator_expr->as_string ();
2589 : :
2590 : 0 : str += "\n Loop block: " + loop_block->as_string ();
2591 : :
2592 : 0 : return str;
2593 : : }
2594 : :
2595 : : std::string
2596 : 0 : LetStmt::as_string () const
2597 : : {
2598 : : // TODO: rewrite to work with non-linearisable types and exprs
2599 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
2600 : :
2601 : 0 : str += "\n" + indent_spaces (stay) + "let " + variables_pattern->as_string ();
2602 : :
2603 : 0 : if (has_type ())
2604 : 0 : str += " : " + type->as_string ();
2605 : :
2606 : 0 : if (has_init_expr ())
2607 : 0 : str += " = " + init_expr->as_string ();
2608 : :
2609 : 0 : return str;
2610 : : }
2611 : :
2612 : : std::string
2613 : 0 : InferredType::as_string () const
2614 : : {
2615 : 0 : return "_ (inferred)";
2616 : : }
2617 : :
2618 : : std::string
2619 : 0 : TypeCastExpr::as_string () const
2620 : : {
2621 : : // TODO: rewrite to work with non-linearisable exprs and types
2622 : 0 : return main_or_left_expr->as_string () + " as "
2623 : 0 : + type_to_convert_to->as_string ();
2624 : : }
2625 : :
2626 : : std::string
2627 : 0 : ImplTraitType::as_string () const
2628 : : {
2629 : 0 : std::string str ("ImplTraitType: \n TypeParamBounds: ");
2630 : :
2631 : 0 : if (type_param_bounds.empty ())
2632 : : {
2633 : 0 : str += "none";
2634 : : }
2635 : : else
2636 : : {
2637 : 0 : for (const auto &bound : type_param_bounds)
2638 : 0 : str += "\n " + bound->as_string ();
2639 : : }
2640 : :
2641 : 0 : return str;
2642 : : }
2643 : :
2644 : : std::string
2645 : 0 : ReferenceType::as_string () const
2646 : : {
2647 : : // TODO: rewrite to work with non-linearisable types
2648 : 0 : std::string str ("&");
2649 : :
2650 : 0 : if (has_lifetime ())
2651 : 0 : str += get_lifetime ().as_string () + " ";
2652 : :
2653 : 0 : if (has_mut)
2654 : 0 : str += "mut ";
2655 : :
2656 : 0 : str += type->as_string ();
2657 : :
2658 : 0 : return str;
2659 : : }
2660 : :
2661 : : std::string
2662 : 0 : RawPointerType::as_string () const
2663 : : {
2664 : : // TODO: rewrite to work with non-linearisable types
2665 : 0 : std::string str ("*");
2666 : :
2667 : 0 : switch (pointer_type)
2668 : : {
2669 : 0 : case MUT:
2670 : 0 : str += "mut ";
2671 : 0 : break;
2672 : 0 : case CONST:
2673 : 0 : str += "const ";
2674 : 0 : break;
2675 : 0 : default:
2676 : 0 : return "ERROR_MARK_STRING - unknown pointer type in raw pointer type";
2677 : : }
2678 : :
2679 : 0 : str += type->as_string ();
2680 : :
2681 : 0 : return str;
2682 : 0 : }
2683 : :
2684 : : std::string
2685 : 0 : TraitObjectType::as_string () const
2686 : : {
2687 : 0 : std::string str ("TraitObjectType: \n Has dyn dispatch: ");
2688 : :
2689 : 0 : if (has_dyn)
2690 : 0 : str += "true";
2691 : : else
2692 : 0 : str += "false";
2693 : :
2694 : 0 : str += "\n TypeParamBounds: ";
2695 : 0 : if (type_param_bounds.empty ())
2696 : : {
2697 : 0 : str += "none";
2698 : : }
2699 : : else
2700 : : {
2701 : 0 : for (const auto &bound : type_param_bounds)
2702 : 0 : str += "\n " + bound->as_string ();
2703 : : }
2704 : :
2705 : 0 : return str;
2706 : : }
2707 : :
2708 : : std::string
2709 : 0 : BareFunctionType::as_string () const
2710 : : {
2711 : 0 : std::string str ("BareFunctionType: \n For lifetimes: ");
2712 : :
2713 : 0 : if (!has_for_lifetimes ())
2714 : : {
2715 : 0 : str += "none";
2716 : : }
2717 : : else
2718 : : {
2719 : 0 : for (const auto &for_lifetime : for_lifetimes)
2720 : 0 : str += "\n " + for_lifetime.as_string ();
2721 : : }
2722 : :
2723 : 0 : str += "\n Qualifiers: " + function_qualifiers.as_string ();
2724 : :
2725 : 0 : str += "\n Params: ";
2726 : 0 : if (params.empty ())
2727 : : {
2728 : 0 : str += "none";
2729 : : }
2730 : : else
2731 : : {
2732 : 0 : for (const auto ¶m : params)
2733 : 0 : str += "\n " + param.as_string ();
2734 : : }
2735 : :
2736 : 0 : str += "\n Is variadic: ";
2737 : 0 : if (_is_variadic)
2738 : 0 : str += "true";
2739 : : else
2740 : 0 : str += "false";
2741 : :
2742 : 0 : str += "\n Return type: ";
2743 : 0 : if (!has_return_type ())
2744 : 0 : str += "none (void)";
2745 : : else
2746 : 0 : str += return_type->as_string ();
2747 : :
2748 : 0 : return str;
2749 : : }
2750 : :
2751 : : std::string
2752 : 0 : ImplTraitTypeOneBound::as_string () const
2753 : : {
2754 : 0 : std::string str ("ImplTraitTypeOneBound: \n TraitBound: ");
2755 : :
2756 : 0 : return str + trait_bound->as_string ();
2757 : 0 : }
2758 : :
2759 : : std::string
2760 : 0 : TraitObjectTypeOneBound::as_string () const
2761 : : {
2762 : 0 : std::string str ("TraitObjectTypeOneBound: \n Has dyn dispatch: ");
2763 : :
2764 : 0 : if (has_dyn)
2765 : 0 : str += "true";
2766 : : else
2767 : 0 : str += "false";
2768 : :
2769 : 0 : str += "\n TraitBound: " + trait_bound.as_string ();
2770 : :
2771 : 0 : return str;
2772 : : }
2773 : :
2774 : : std::string
2775 : 0 : ArrayType::as_string () const
2776 : : {
2777 : : // TODO: rewrite to work with non-linearisable types and exprs
2778 : 0 : return "[" + elem_type->as_string () + "; " + size.as_string () + "]";
2779 : : }
2780 : :
2781 : : std::string
2782 : 0 : SliceType::as_string () const
2783 : : {
2784 : : // TODO: rewrite to work with non-linearisable types
2785 : 0 : return "[" + elem_type->as_string () + "]";
2786 : : }
2787 : :
2788 : : std::string
2789 : 0 : TupleType::as_string () const
2790 : : {
2791 : : // TODO: rewrite to work with non-linearisable types
2792 : 0 : std::string str ("(");
2793 : :
2794 : 0 : if (!is_unit_type ())
2795 : : {
2796 : : auto i = elems.begin ();
2797 : : auto e = elems.end ();
2798 : :
2799 : 0 : for (; i != e; i++)
2800 : : {
2801 : 0 : str += (*i)->as_string ();
2802 : 0 : if (e != i + 1)
2803 : 0 : str += ", ";
2804 : : }
2805 : : }
2806 : :
2807 : 0 : str += ")";
2808 : :
2809 : 0 : return str;
2810 : : }
2811 : :
2812 : : std::string
2813 : 0 : StructExpr::as_string () const
2814 : : {
2815 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
2816 : 0 : indent_spaces (enter);
2817 : 0 : str += "\n" + indent_spaces (stay) + "StructExpr:";
2818 : 0 : indent_spaces (enter);
2819 : 0 : str += "\n" + indent_spaces (stay) + "PathInExpr:\n";
2820 : 0 : str += indent_spaces (stay) + struct_name.as_string ();
2821 : 0 : indent_spaces (out);
2822 : 0 : indent_spaces (out);
2823 : 0 : return str;
2824 : : }
2825 : :
2826 : : std::string
2827 : 0 : StructExprStruct::as_string () const
2828 : : {
2829 : : // TODO: doesn't this require data from StructExpr?
2830 : 0 : std::string str ("StructExprStruct (or subclass): ");
2831 : :
2832 : 0 : str += "\n Path: " + get_struct_name ().as_string ();
2833 : :
2834 : : // inner attributes
2835 : 0 : str += append_attributes (inner_attrs, INNER);
2836 : :
2837 : 0 : return str;
2838 : : }
2839 : :
2840 : : std::string
2841 : 0 : StructBase::as_string () const
2842 : : {
2843 : 0 : if (base_struct != nullptr)
2844 : 0 : return base_struct->as_string ();
2845 : : else
2846 : 0 : return "ERROR_MARK_STRING - invalid struct base had as string applied";
2847 : : }
2848 : :
2849 : : std::string
2850 : 0 : StructExprFieldWithVal::as_string () const
2851 : : {
2852 : : // used to get value string
2853 : 0 : return value->as_string ();
2854 : : }
2855 : :
2856 : : std::string
2857 : 0 : StructExprFieldIdentifierValue::as_string () const
2858 : : {
2859 : : // TODO: rewrite to work with non-linearisable exprs
2860 : 0 : return field_name.as_string () + " : " + StructExprFieldWithVal::as_string ();
2861 : : }
2862 : :
2863 : : std::string
2864 : 0 : StructExprFieldIndexValue::as_string () const
2865 : : {
2866 : : // TODO: rewrite to work with non-linearisable exprs
2867 : 0 : return std::to_string (index) + " : " + StructExprFieldWithVal::as_string ();
2868 : : }
2869 : :
2870 : : std::string
2871 : 0 : StructExprStructFields::as_string () const
2872 : : {
2873 : 0 : std::string str = StructExprStruct::as_string ();
2874 : :
2875 : 0 : str += "\n Fields: ";
2876 : 0 : if (fields.empty ())
2877 : : {
2878 : 0 : str += "none";
2879 : : }
2880 : : else
2881 : : {
2882 : 0 : for (const auto &field : fields)
2883 : 0 : str += "\n " + field->as_string ();
2884 : : }
2885 : :
2886 : 0 : str += "\n Struct base: ";
2887 : 0 : if (!has_struct_base ())
2888 : 0 : str += "none";
2889 : : else
2890 : 0 : str += struct_base.as_string ();
2891 : :
2892 : 0 : return str;
2893 : : }
2894 : :
2895 : : std::string
2896 : 0 : EnumItem::as_string () const
2897 : : {
2898 : 0 : std::string str = VisItem::as_string ();
2899 : 0 : str += variant_name.as_string ();
2900 : :
2901 : 0 : return str;
2902 : : }
2903 : :
2904 : : std::string
2905 : 0 : EnumItemTuple::as_string () const
2906 : : {
2907 : 0 : std::string str = EnumItem::as_string ();
2908 : :
2909 : : // add tuple opening parens
2910 : 0 : str += "(";
2911 : :
2912 : : // tuple fields
2913 : 0 : if (has_tuple_fields ())
2914 : : {
2915 : : auto i = tuple_fields.begin ();
2916 : : auto e = tuple_fields.end ();
2917 : :
2918 : 0 : for (; i != e; i++)
2919 : : {
2920 : 0 : str += (*i).as_string ();
2921 : 0 : if (e != i + 1)
2922 : 0 : str += ", ";
2923 : : }
2924 : : }
2925 : :
2926 : : // add tuple closing parens
2927 : 0 : str += ")";
2928 : :
2929 : 0 : return str;
2930 : : }
2931 : :
2932 : : std::string
2933 : 0 : TupleField::as_string () const
2934 : : {
2935 : : // TODO: rewrite to work with non-linearisable exprs
2936 : :
2937 : : // outer attributes
2938 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
2939 : :
2940 : 0 : if (has_visibility ())
2941 : 0 : str += "\n" + visibility.as_string ();
2942 : :
2943 : 0 : str += " " + field_type->as_string ();
2944 : :
2945 : 0 : return str;
2946 : : }
2947 : :
2948 : : std::string
2949 : 0 : EnumItemStruct::as_string () const
2950 : : {
2951 : 0 : std::string str = EnumItem::as_string ();
2952 : :
2953 : : // add struct opening parens
2954 : 0 : str += "{";
2955 : :
2956 : : // tuple fields
2957 : 0 : if (has_struct_fields ())
2958 : : {
2959 : : auto i = struct_fields.begin ();
2960 : : auto e = struct_fields.end ();
2961 : :
2962 : 0 : for (; i != e; i++)
2963 : : {
2964 : 0 : str += (*i).as_string ();
2965 : 0 : if (e != i + 1)
2966 : 0 : str += ", ";
2967 : : }
2968 : : }
2969 : :
2970 : : // add struct closing parens
2971 : 0 : str += "}";
2972 : :
2973 : 0 : return str;
2974 : : }
2975 : :
2976 : : std::string
2977 : 0 : StructField::as_string () const
2978 : : {
2979 : : // TODO: rewrite to work with non-linearisable exprs
2980 : : // outer attributes
2981 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
2982 : :
2983 : 0 : if (has_visibility ())
2984 : 0 : str += "\n" + visibility.as_string ();
2985 : :
2986 : 0 : str += " " + field_name.as_string () + " : " + field_type->as_string ();
2987 : :
2988 : 0 : return str;
2989 : : }
2990 : :
2991 : : std::string
2992 : 0 : EnumItemDiscriminant::as_string () const
2993 : : {
2994 : : // TODO: rewrite to work with non-linearisable exprs
2995 : 0 : std::string str = EnumItem::as_string ();
2996 : :
2997 : : // add equal and expression
2998 : 0 : str += " = " + expression->as_string ();
2999 : :
3000 : 0 : return str;
3001 : : }
3002 : :
3003 : : std::string
3004 : 0 : ExternalTypeItem::as_string () const
3005 : : {
3006 : 0 : auto str = append_attributes (outer_attrs, OUTER);
3007 : :
3008 : 0 : str += "type " + item_name.as_string () + ";";
3009 : :
3010 : 0 : return str;
3011 : : }
3012 : :
3013 : : std::string
3014 : 0 : ExternalStaticItem::as_string () const
3015 : : {
3016 : : // outer attributes
3017 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
3018 : :
3019 : : // start visibility on new line and with a space
3020 : 0 : str += "\n" + visibility.as_string () + " ";
3021 : :
3022 : 0 : str += "static ";
3023 : :
3024 : 0 : if (has_mut)
3025 : 0 : str += "mut ";
3026 : :
3027 : : // add name
3028 : 0 : str += item_name.as_string ();
3029 : :
3030 : : // add type on new line
3031 : 0 : str += "\n Type: " + item_type->as_string ();
3032 : :
3033 : 0 : return str;
3034 : : }
3035 : :
3036 : : std::string
3037 : 0 : TraitItemConst::as_string () const
3038 : : {
3039 : : // TODO: rewrite to work with non-linearisable exprs
3040 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
3041 : :
3042 : 0 : str += "\nconst " + name.as_string () + " : " + type->as_string ();
3043 : :
3044 : 0 : if (has_expression ())
3045 : 0 : str += " = " + expr->as_string ();
3046 : :
3047 : 0 : return str;
3048 : : }
3049 : :
3050 : : std::string
3051 : 0 : TraitItemType::as_string () const
3052 : : {
3053 : 0 : std::string str = append_attributes (outer_attrs, OUTER);
3054 : :
3055 : 0 : str += "\ntype " + name.as_string ();
3056 : :
3057 : 0 : str += "\n Type param bounds: ";
3058 : 0 : if (!has_type_param_bounds ())
3059 : : {
3060 : 0 : str += "none";
3061 : : }
3062 : : else
3063 : : {
3064 : 0 : for (const auto &bound : type_param_bounds)
3065 : : {
3066 : : // DEBUG: null pointer check
3067 : 0 : if (bound == nullptr)
3068 : : {
3069 : 0 : rust_debug (
3070 : : "something really terrible has gone wrong - null pointer "
3071 : : "type param bound in trait item type.");
3072 : 0 : return "NULL_POINTER_MARK";
3073 : : }
3074 : :
3075 : 0 : str += "\n " + bound->as_string ();
3076 : : }
3077 : : }
3078 : :
3079 : 0 : return str;
3080 : 0 : }
3081 : :
3082 : : std::string
3083 : 0 : SelfParam::as_string () const
3084 : : {
3085 : : // TODO: rewrite to allow non-linearisable types
3086 : 0 : if (is_error ())
3087 : : {
3088 : 0 : return "error";
3089 : : }
3090 : : else
3091 : : {
3092 : 0 : if (has_type ())
3093 : : {
3094 : : // type (i.e. not ref, no lifetime)
3095 : 0 : std::string str;
3096 : :
3097 : 0 : if (is_mut)
3098 : 0 : str += "mut ";
3099 : :
3100 : 0 : str += "self : ";
3101 : :
3102 : 0 : str += type->as_string ();
3103 : :
3104 : 0 : return str;
3105 : 0 : }
3106 : 0 : else if (has_lifetime ())
3107 : : {
3108 : : // ref and lifetime
3109 : 0 : std::string str = "&" + get_lifetime ().as_string () + " ";
3110 : :
3111 : 0 : if (is_mut)
3112 : 0 : str += "mut ";
3113 : :
3114 : 0 : str += "self";
3115 : :
3116 : 0 : return str;
3117 : 0 : }
3118 : 0 : else if (has_ref)
3119 : : {
3120 : : // ref with no lifetime
3121 : 0 : std::string str = "&";
3122 : :
3123 : 0 : if (is_mut)
3124 : 0 : str += " mut ";
3125 : :
3126 : 0 : str += "self";
3127 : :
3128 : 0 : return str;
3129 : 0 : }
3130 : : else
3131 : : {
3132 : : // no ref, no type
3133 : 0 : std::string str;
3134 : :
3135 : 0 : if (is_mut)
3136 : 0 : str += "mut ";
3137 : :
3138 : 0 : str += "self";
3139 : :
3140 : 0 : return str;
3141 : 0 : }
3142 : : }
3143 : : }
3144 : :
3145 : : std::string
3146 : 0 : ArrayElemsCopied::as_string () const
3147 : : {
3148 : : // TODO: rewrite to allow non-linearisable exprs
3149 : 0 : return elem_to_copy->as_string () + "; " + num_copies->as_string ();
3150 : : }
3151 : :
3152 : : std::string
3153 : 0 : LifetimeWhereClauseItem::as_string () const
3154 : : {
3155 : 0 : std::string str ("Lifetime: ");
3156 : :
3157 : 0 : str += lifetime.as_string ();
3158 : :
3159 : 0 : str += "\nLifetime bounds: ";
3160 : :
3161 : 0 : for (const auto &bound : lifetime_bounds)
3162 : 0 : str += "\n " + bound.as_string ();
3163 : :
3164 : 0 : return str;
3165 : : }
3166 : :
3167 : : std::string
3168 : 0 : TypeBoundWhereClauseItem::as_string () const
3169 : : {
3170 : 0 : std::string str ("For lifetimes: ");
3171 : :
3172 : 0 : if (!has_for_lifetimes ())
3173 : : {
3174 : 0 : str += "none";
3175 : : }
3176 : : else
3177 : : {
3178 : 0 : for (const auto &for_lifetime : for_lifetimes)
3179 : 0 : str += "\n " + for_lifetime.as_string ();
3180 : : }
3181 : :
3182 : 0 : str += "\nType: " + bound_type->as_string ();
3183 : :
3184 : 0 : str += "\nType param bounds bounds: ";
3185 : :
3186 : 0 : for (const auto &bound : type_param_bounds)
3187 : : {
3188 : : // debug null pointer check
3189 : 0 : if (bound == nullptr)
3190 : 0 : return "NULL_POINTER_MARK - type param bounds";
3191 : :
3192 : 0 : str += "\n " + bound->as_string ();
3193 : : }
3194 : :
3195 : 0 : return str;
3196 : 0 : }
3197 : :
3198 : : std::string
3199 : 0 : ArrayElemsValues::as_string () const
3200 : : {
3201 : 0 : std::string str;
3202 : :
3203 : 0 : for (const auto &expr : values)
3204 : : {
3205 : : // DEBUG: null pointer check
3206 : 0 : if (expr == nullptr)
3207 : : {
3208 : 0 : rust_debug ("something really terrible has gone wrong - null pointer "
3209 : : "expr in array elems values.");
3210 : 0 : return "NULL_POINTER_MARK";
3211 : : }
3212 : :
3213 : 0 : str += "\n " + expr->as_string ();
3214 : : }
3215 : :
3216 : 0 : return str;
3217 : 0 : }
3218 : :
3219 : : std::string
3220 : 0 : MaybeNamedParam::as_string () const
3221 : : {
3222 : : // TODO: rewrite to allow using non-linearisable types in dump
3223 : 0 : std::string str;
3224 : :
3225 : 0 : switch (param_kind)
3226 : : {
3227 : : case UNNAMED:
3228 : : break;
3229 : 0 : case IDENTIFIER:
3230 : 0 : str = name.as_string () + " : ";
3231 : 0 : break;
3232 : 0 : case WILDCARD:
3233 : 0 : str = "_ : ";
3234 : 0 : break;
3235 : 0 : default:
3236 : 0 : return "ERROR_MARK_STRING - maybe named param unrecognised param kind";
3237 : : }
3238 : :
3239 : 0 : str += param_type->as_string ();
3240 : :
3241 : 0 : return str;
3242 : 0 : }
3243 : :
3244 : 3800 : MetaItemInner::~MetaItemInner () = default;
3245 : :
3246 : : std::unique_ptr<MetaNameValueStr>
3247 : 0 : MetaItemInner::to_meta_name_value_str () const
3248 : : {
3249 : 0 : if (is_key_value_pair ())
3250 : : {
3251 : 0 : auto converted_item = static_cast<const MetaNameValueStr *> (this);
3252 : 0 : return converted_item->to_meta_name_value_str ();
3253 : : }
3254 : : // TODO actually parse foo = bar
3255 : 0 : return nullptr;
3256 : : }
3257 : :
3258 : : std::string
3259 : 124 : MetaItemSeq::as_string () const
3260 : : {
3261 : 124 : std::string path_str = path.as_string () + "(";
3262 : :
3263 : 124 : auto i = seq.begin ();
3264 : 124 : auto e = seq.end ();
3265 : :
3266 : 278 : for (; i != e; i++)
3267 : : {
3268 : 308 : path_str += (*i)->as_string ();
3269 : 154 : if (e != i + 1)
3270 : 30 : path_str += ", ";
3271 : : }
3272 : :
3273 : 124 : return path_str + ")";
3274 : 124 : }
3275 : :
3276 : : std::string
3277 : 0 : MetaListPaths::as_string () const
3278 : : {
3279 : 0 : std::string str = ident.as_string () + "(";
3280 : :
3281 : 0 : auto i = paths.begin ();
3282 : 0 : auto e = paths.end ();
3283 : :
3284 : 0 : for (; i != e; i++)
3285 : : {
3286 : 0 : str += (*i).as_string ();
3287 : 0 : if (e != i + 1)
3288 : 0 : str += ", ";
3289 : : }
3290 : :
3291 : 0 : return str + ")";
3292 : 0 : }
3293 : :
3294 : : std::string
3295 : 0 : MetaListNameValueStr::as_string () const
3296 : : {
3297 : 0 : std::string str = ident.as_string () + "(";
3298 : :
3299 : 0 : auto i = strs.begin ();
3300 : 0 : auto e = strs.end ();
3301 : :
3302 : 0 : for (; i != e; i++)
3303 : : {
3304 : 0 : str += (*i).as_string ();
3305 : 0 : if (e != i + 1)
3306 : 0 : str += ", ";
3307 : : }
3308 : :
3309 : 0 : return str + ")";
3310 : 0 : }
3311 : :
3312 : : std::string
3313 : 2110 : AttrInputMetaItemContainer::as_string () const
3314 : : {
3315 : 2110 : std::string str = "(";
3316 : :
3317 : 2110 : auto i = items.begin ();
3318 : 2110 : auto e = items.end ();
3319 : :
3320 : 4220 : for (; i != e; i++)
3321 : : {
3322 : 4220 : str += (*i)->as_string ();
3323 : 2110 : if (e != i + 1)
3324 : 0 : str += ", ";
3325 : : }
3326 : :
3327 : 2110 : return str + ")";
3328 : 2110 : }
3329 : :
3330 : : std::string
3331 : 0 : AttrInputMacro::as_string () const
3332 : : {
3333 : 0 : return " = " + macro->as_string ();
3334 : : }
3335 : :
3336 : : /* Override that calls the function recursively on all items contained within
3337 : : * the module. */
3338 : : void
3339 : 0 : Module::add_crate_name (std::vector<std::string> &names) const
3340 : : {
3341 : : /* TODO: test whether module has been 'cfg'-ed out to determine whether to
3342 : : * exclude it from search */
3343 : :
3344 : 0 : for (const auto &item : items)
3345 : 0 : item->add_crate_name (names);
3346 : 0 : }
3347 : :
3348 : : static bool
3349 : 76 : file_exists (const std::string path)
3350 : : {
3351 : : // Simply check if the file exists
3352 : : // FIXME: This does not work on Windows
3353 : 0 : return access (path.c_str (), F_OK) != -1;
3354 : : }
3355 : :
3356 : : static std::string
3357 : 77 : filename_from_path_attribute (std::vector<Attribute> &outer_attrs)
3358 : : {
3359 : : // An out-of-line module cannot have inner attributes. Additionally, the
3360 : : // default name is specified as `""` so that the caller can detect the case
3361 : : // of "no path given" and use the default path logic (`name.rs` or
3362 : : // `name/mod.rs`).
3363 : 77 : return extract_module_path ({}, outer_attrs, "");
3364 : : }
3365 : :
3366 : : void
3367 : 77 : Module::process_file_path ()
3368 : : {
3369 : 77 : rust_assert (kind == Module::ModuleKind::UNLOADED);
3370 : 77 : rust_assert (module_file.empty ());
3371 : :
3372 : : // This corresponds to the path of the file 'including' the module. So the
3373 : : // file that contains the 'mod <file>;' directive
3374 : 77 : std::string including_fpath (outer_filename);
3375 : :
3376 : 77 : std::string expected_file_path = module_name.as_string () + ".rs";
3377 : 77 : std::string expected_dir_path = "mod.rs";
3378 : :
3379 : 77 : auto dir_slash_pos = including_fpath.rfind (file_separator);
3380 : 77 : std::string current_directory_name;
3381 : 77 : std::string including_fname;
3382 : :
3383 : : // If we haven't found a file_separator, then we may have to look for files in
3384 : : // the current directory ('.')
3385 : 77 : if (dir_slash_pos == std::string::npos)
3386 : : {
3387 : 0 : including_fname = std::move (including_fpath);
3388 : 0 : including_fpath = std::string (".") + file_separator + including_fname;
3389 : 0 : dir_slash_pos = 1;
3390 : : }
3391 : : else
3392 : : {
3393 : 77 : including_fname = including_fpath.substr (dir_slash_pos + 1);
3394 : : }
3395 : :
3396 : 77 : current_directory_name
3397 : 154 : = including_fpath.substr (0, dir_slash_pos) + file_separator;
3398 : :
3399 : 77 : auto path_string = filename_from_path_attribute (get_outer_attrs ());
3400 : :
3401 : 77 : std::string including_subdir;
3402 : 77 : if (path_string.empty () && module_scope.empty ()
3403 : 114 : && get_file_subdir (including_fname, including_subdir))
3404 : 74 : current_directory_name += including_subdir + file_separator;
3405 : :
3406 : : // Handle inline module declarations adding path components.
3407 : 82 : for (auto const &name : module_scope)
3408 : : {
3409 : 5 : current_directory_name.append (name);
3410 : 5 : current_directory_name.append (file_separator);
3411 : : }
3412 : :
3413 : 77 : if (!path_string.empty ())
3414 : : {
3415 : 39 : module_file = current_directory_name + path_string;
3416 : 39 : return;
3417 : : }
3418 : :
3419 : : // FIXME: We also have to search for
3420 : : // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via
3421 : : // the concept of `DirOwnernship`, which is based on whether or not the
3422 : : // current file is titled `mod.rs`.
3423 : :
3424 : : // First, we search for <directory>/<module_name>.rs
3425 : 38 : std::string file_mod_path = current_directory_name + expected_file_path;
3426 : 76 : bool file_mod_found = file_exists (file_mod_path);
3427 : :
3428 : : // Then, search for <directory>/<module_name>/mod.rs
3429 : 38 : std::string dir_mod_path = current_directory_name + module_name.as_string ()
3430 : 38 : + file_separator + expected_dir_path;
3431 : 76 : bool dir_mod_found = file_exists (dir_mod_path);
3432 : :
3433 : 38 : bool multiple_candidates_found = file_mod_found && dir_mod_found;
3434 : 38 : bool no_candidates_found = !file_mod_found && !dir_mod_found;
3435 : :
3436 : 38 : if (multiple_candidates_found)
3437 : 0 : rust_error_at (locus,
3438 : : "two candidates found for module %s: %s.rs and %s%smod.rs",
3439 : 0 : module_name.as_string ().c_str (),
3440 : 0 : module_name.as_string ().c_str (),
3441 : 0 : module_name.as_string ().c_str (), file_separator);
3442 : :
3443 : 38 : if (no_candidates_found)
3444 : 21 : rust_error_at (locus, "no candidate found for module %s",
3445 : 21 : module_name.as_string ().c_str ());
3446 : :
3447 : 38 : if (no_candidates_found || multiple_candidates_found)
3448 : 21 : return;
3449 : :
3450 : 32 : module_file = std::move (file_mod_found ? file_mod_path : dir_mod_path);
3451 : 98 : }
3452 : :
3453 : : void
3454 : 77 : Module::load_items ()
3455 : : {
3456 : 77 : process_file_path ();
3457 : :
3458 : : // We will already have errored out appropriately in the process_file_path ()
3459 : : // method
3460 : 77 : if (module_file.empty ())
3461 : 28 : return;
3462 : :
3463 : 56 : RAIIFile file_wrap (module_file.c_str ());
3464 : 56 : Linemap *linemap = Session::get_instance ().linemap;
3465 : 56 : if (!file_wrap.ok ())
3466 : : {
3467 : 7 : rust_error_at (get_locus (), "cannot open module file %s: %m",
3468 : : module_file.c_str ());
3469 : 7 : return;
3470 : : }
3471 : :
3472 : 49 : rust_debug ("Attempting to parse file %s", module_file.c_str ());
3473 : :
3474 : 49 : Lexer lex (module_file.c_str (), std::move (file_wrap), linemap);
3475 : 49 : Parser<Lexer> parser (lex);
3476 : :
3477 : : // we need to parse any possible inner attributes for this module
3478 : 49 : inner_attrs = parser.parse_inner_attributes ();
3479 : 49 : auto parsed_items = parser.parse_items ();
3480 : 49 : for (const auto &error : parser.get_errors ())
3481 : 0 : error.emit ();
3482 : :
3483 : 49 : items = std::move (parsed_items);
3484 : 49 : kind = ModuleKind::LOADED;
3485 : 105 : }
3486 : :
3487 : : void
3488 : 897 : Attribute::parse_attr_to_meta_item ()
3489 : : {
3490 : : // only parse if has attribute input and not already parsed
3491 : 897 : if (!has_attr_input () || is_parsed_to_meta_item ())
3492 : 253 : return;
3493 : :
3494 : 644 : auto res = attr_input->parse_to_meta_item ();
3495 : 644 : std::unique_ptr<AttrInput> converted_input (res);
3496 : :
3497 : 644 : if (converted_input != nullptr)
3498 : 644 : attr_input = std::move (converted_input);
3499 : 644 : }
3500 : :
3501 : : AttrInputMetaItemContainer *
3502 : 2151 : DelimTokenTree::parse_to_meta_item () const
3503 : : {
3504 : : // must have token trees
3505 : 2151 : if (token_trees.empty ())
3506 : : return nullptr;
3507 : :
3508 : : /* assume top-level delim token tree in attribute - convert all nested ones
3509 : : * to token stream */
3510 : 2151 : std::vector<std::unique_ptr<Token>> token_stream = to_token_stream ();
3511 : :
3512 : 2151 : AttributeParser parser (std::move (token_stream));
3513 : 2151 : std::vector<std::unique_ptr<MetaItemInner>> meta_items (
3514 : 2151 : parser.parse_meta_item_seq ());
3515 : :
3516 : 2151 : return new AttrInputMetaItemContainer (std::move (meta_items));
3517 : 2151 : }
3518 : :
3519 : 2151 : AttributeParser::AttributeParser (
3520 : 2151 : std::vector<std::unique_ptr<Token>> token_stream, int stream_start_pos)
3521 : 2151 : : lexer (new MacroInvocLexer (std::move (token_stream))),
3522 : 2151 : parser (new Parser<MacroInvocLexer> (*lexer))
3523 : : {
3524 : 2151 : if (stream_start_pos)
3525 : 0 : lexer->skip_token (stream_start_pos - 1);
3526 : 2151 : }
3527 : :
3528 : 2151 : AttributeParser::~AttributeParser () {}
3529 : :
3530 : : std::unique_ptr<MetaItemInner>
3531 : 2439 : AttributeParser::parse_meta_item_inner ()
3532 : : {
3533 : : // if first tok not identifier, not a "special" case one
3534 : 4878 : if (lexer->peek_token ()->get_id () != IDENTIFIER)
3535 : : {
3536 : 54 : switch (lexer->peek_token ()->get_id ())
3537 : : {
3538 : 27 : case CHAR_LITERAL:
3539 : 27 : case STRING_LITERAL:
3540 : 27 : case BYTE_CHAR_LITERAL:
3541 : 27 : case BYTE_STRING_LITERAL:
3542 : 27 : case RAW_STRING_LITERAL:
3543 : 27 : case INT_LITERAL:
3544 : 27 : case FLOAT_LITERAL:
3545 : 27 : case TRUE_LITERAL:
3546 : 27 : case FALSE_LITERAL:
3547 : 27 : return parse_meta_item_lit ();
3548 : :
3549 : 0 : case SUPER:
3550 : 0 : case SELF:
3551 : 0 : case CRATE:
3552 : 0 : case DOLLAR_SIGN:
3553 : 0 : case SCOPE_RESOLUTION:
3554 : 0 : return parse_path_meta_item ();
3555 : :
3556 : 0 : default:
3557 : 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3558 : : "unrecognised token '%s' in meta item",
3559 : : get_token_description (
3560 : 0 : lexer->peek_token ()->get_id ()));
3561 : 0 : return nullptr;
3562 : : }
3563 : : }
3564 : :
3565 : : // else, check for path
3566 : 4824 : if (lexer->peek_token (1)->get_id () == SCOPE_RESOLUTION)
3567 : : {
3568 : : // path
3569 : 0 : return parse_path_meta_item ();
3570 : : }
3571 : :
3572 : 4824 : auto ident = lexer->peek_token ()->get_str ();
3573 : 2412 : auto ident_locus = lexer->peek_token ()->get_locus ();
3574 : :
3575 : 4824 : if (is_end_meta_item_tok (lexer->peek_token (1)->get_id ()))
3576 : : {
3577 : : // meta word syntax
3578 : 1211 : lexer->skip_token ();
3579 : 3633 : return std::unique_ptr<MetaWord> (new MetaWord (ident, ident_locus));
3580 : : }
3581 : :
3582 : 2402 : if (lexer->peek_token (1)->get_id () == EQUAL)
3583 : : {
3584 : : // maybe meta name value str syntax - check next 2 tokens
3585 : 2186 : if (lexer->peek_token (2)->get_id () == STRING_LITERAL
3586 : 2186 : && is_end_meta_item_tok (lexer->peek_token (3)->get_id ()))
3587 : : {
3588 : : // meta name value str syntax
3589 : 1093 : const_TokenPtr value_tok = lexer->peek_token (2);
3590 : 1093 : auto value = value_tok->get_str ();
3591 : 1093 : auto locus = value_tok->get_locus ();
3592 : :
3593 : 1093 : lexer->skip_token (2);
3594 : :
3595 : 1093 : return std::unique_ptr<MetaNameValueStr> (
3596 : 2186 : new MetaNameValueStr (ident, ident_locus, std::move (value),
3597 : 3279 : locus));
3598 : 2186 : }
3599 : : else
3600 : : {
3601 : : // just interpret as path-based meta item
3602 : 0 : return parse_path_meta_item ();
3603 : : }
3604 : : }
3605 : :
3606 : 216 : if (lexer->peek_token (1)->get_id () != LEFT_PAREN)
3607 : : {
3608 : 0 : rust_error_at (lexer->peek_token (1)->get_locus (),
3609 : : "unexpected token '%s' after identifier in attribute",
3610 : 0 : get_token_description (lexer->peek_token (1)->get_id ()));
3611 : 0 : return nullptr;
3612 : : }
3613 : :
3614 : : // is it one of those special cases like not?
3615 : 216 : if (lexer->peek_token ()->get_id () == IDENTIFIER)
3616 : : {
3617 : 108 : return parse_path_meta_item ();
3618 : : }
3619 : :
3620 : 0 : auto meta_items = parse_meta_item_seq ();
3621 : :
3622 : : // pass for meta name value str
3623 : 0 : std::vector<MetaNameValueStr> meta_name_value_str_items;
3624 : 0 : for (const auto &item : meta_items)
3625 : : {
3626 : 0 : std::unique_ptr<MetaNameValueStr> converted_item
3627 : 0 : = item->to_meta_name_value_str ();
3628 : 0 : if (converted_item == nullptr)
3629 : : {
3630 : 0 : meta_name_value_str_items.clear ();
3631 : 0 : break;
3632 : : }
3633 : 0 : meta_name_value_str_items.push_back (std::move (*converted_item));
3634 : 0 : }
3635 : : // if valid, return this
3636 : 0 : if (!meta_name_value_str_items.empty ())
3637 : : {
3638 : 0 : return std::unique_ptr<MetaListNameValueStr> (
3639 : 0 : new MetaListNameValueStr (ident, ident_locus,
3640 : 0 : std::move (meta_name_value_str_items)));
3641 : : }
3642 : :
3643 : : // // pass for meta list idents
3644 : : // std::vector<Identifier> ident_items;
3645 : : // for (const auto &item : meta_items)
3646 : : // {
3647 : : // std::unique_ptr<Identifier> converted_ident (item->to_ident_item ());
3648 : : // if (converted_ident == nullptr)
3649 : : // {
3650 : : // ident_items.clear ();
3651 : : // break;
3652 : : // }
3653 : : // ident_items.push_back (std::move (*converted_ident));
3654 : : // }
3655 : : // // if valid return this
3656 : : // if (!ident_items.empty ())
3657 : : // {
3658 : : // return std::unique_ptr<MetaListIdents> (
3659 : : // new MetaListIdents (std::move (ident), std::move (ident_items)));
3660 : : // }
3661 : : // // as currently no meta list ident, currently no path. may change in future
3662 : :
3663 : : // pass for meta list paths
3664 : 0 : std::vector<SimplePath> path_items;
3665 : 0 : for (const auto &item : meta_items)
3666 : : {
3667 : 0 : SimplePath converted_path (item->to_path_item ());
3668 : 0 : if (converted_path.is_empty ())
3669 : : {
3670 : 0 : path_items.clear ();
3671 : 0 : break;
3672 : : }
3673 : 0 : path_items.push_back (std::move (converted_path));
3674 : 0 : }
3675 : 0 : if (!path_items.empty ())
3676 : : {
3677 : 0 : return std::unique_ptr<MetaListPaths> (
3678 : 0 : new MetaListPaths (ident, ident_locus, std::move (path_items)));
3679 : : }
3680 : :
3681 : 0 : rust_error_at (UNKNOWN_LOCATION, "failed to parse any meta item inner");
3682 : 0 : return nullptr;
3683 : 2412 : }
3684 : :
3685 : : bool
3686 : 3505 : AttributeParser::is_end_meta_item_tok (TokenId id) const
3687 : : {
3688 : 3505 : return id == COMMA || id == RIGHT_PAREN;
3689 : : }
3690 : :
3691 : : std::unique_ptr<MetaItem>
3692 : 108 : AttributeParser::parse_path_meta_item ()
3693 : : {
3694 : 108 : SimplePath path = parser->parse_simple_path ();
3695 : 108 : if (path.is_empty ())
3696 : : {
3697 : 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3698 : : "failed to parse simple path in attribute");
3699 : 0 : return nullptr;
3700 : : }
3701 : :
3702 : 216 : switch (lexer->peek_token ()->get_id ())
3703 : : {
3704 : 108 : case LEFT_PAREN:
3705 : 108 : {
3706 : 108 : std::vector<std::unique_ptr<MetaItemInner>> meta_items
3707 : 108 : = parse_meta_item_seq ();
3708 : :
3709 : 108 : return std::unique_ptr<MetaItemSeq> (
3710 : 216 : new MetaItemSeq (std::move (path), std::move (meta_items)));
3711 : 108 : }
3712 : 0 : case EQUAL:
3713 : 0 : {
3714 : 0 : lexer->skip_token ();
3715 : :
3716 : 0 : std::unique_ptr<Expr> expr = parser->parse_expr ();
3717 : :
3718 : : // handle error
3719 : : // parse_expr should already emit an error and return nullptr
3720 : 0 : if (!expr)
3721 : 0 : return nullptr;
3722 : :
3723 : 0 : return std::unique_ptr<MetaItemPathExpr> (
3724 : 0 : new MetaItemPathExpr (std::move (path), std::move (expr)));
3725 : 0 : }
3726 : 0 : case COMMA:
3727 : : // just simple path
3728 : 0 : return std::unique_ptr<MetaItemPath> (
3729 : 0 : new MetaItemPath (std::move (path)));
3730 : 0 : default:
3731 : 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3732 : : "unrecognised token '%s' in meta item",
3733 : 0 : get_token_description (lexer->peek_token ()->get_id ()));
3734 : 0 : return nullptr;
3735 : : }
3736 : 108 : }
3737 : :
3738 : : /* Parses a parenthesised sequence of meta item inners. Parentheses are
3739 : : * required here. */
3740 : : std::vector<std::unique_ptr<MetaItemInner>>
3741 : 2259 : AttributeParser::parse_meta_item_seq ()
3742 : : {
3743 : 2259 : std::vector<std::unique_ptr<MetaItemInner>> meta_items;
3744 : :
3745 : 4518 : if (lexer->peek_token ()->get_id () != LEFT_PAREN)
3746 : : {
3747 : 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3748 : : "missing left paren in delim token tree");
3749 : 0 : return {};
3750 : : }
3751 : 2259 : lexer->skip_token ();
3752 : :
3753 : 2259 : while (lexer->peek_token ()->get_id () != END_OF_FILE
3754 : 7332 : && lexer->peek_token ()->get_id () != RIGHT_PAREN)
3755 : : {
3756 : 2439 : std::unique_ptr<MetaItemInner> inner = parse_meta_item_inner ();
3757 : 2439 : if (inner == nullptr)
3758 : : {
3759 : 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3760 : : "failed to parse inner meta item in attribute");
3761 : 0 : return {};
3762 : : }
3763 : 2439 : meta_items.push_back (std::move (inner));
3764 : :
3765 : 4878 : if (lexer->peek_token ()->get_id () != COMMA)
3766 : : break;
3767 : :
3768 : 185 : lexer->skip_token ();
3769 : 2439 : }
3770 : :
3771 : 4518 : if (lexer->peek_token ()->get_id () != RIGHT_PAREN)
3772 : : {
3773 : 0 : rust_error_at (lexer->peek_token ()->get_locus (),
3774 : : "missing right paren in delim token tree");
3775 : 0 : return {};
3776 : : }
3777 : 2259 : lexer->skip_token ();
3778 : :
3779 : 2259 : return meta_items;
3780 : 2259 : }
3781 : :
3782 : : /* Collects any nested token trees into a flat token stream, suitable for
3783 : : * parsing. */
3784 : : std::vector<std::unique_ptr<Token>>
3785 : 19210 : DelimTokenTree::to_token_stream () const
3786 : : {
3787 : 19210 : std::vector<std::unique_ptr<Token>> tokens;
3788 : 148671 : for (const auto &tree : token_trees)
3789 : : {
3790 : 129461 : std::vector<std::unique_ptr<Token>> stream = tree->to_token_stream ();
3791 : :
3792 : 129461 : tokens.insert (tokens.end (), std::make_move_iterator (stream.begin ()),
3793 : : std::make_move_iterator (stream.end ()));
3794 : 129461 : }
3795 : :
3796 : 19210 : tokens.shrink_to_fit ();
3797 : 19210 : return tokens;
3798 : : }
3799 : :
3800 : : std::unique_ptr<MetaItemLitExpr>
3801 : 27 : AttributeParser::parse_meta_item_lit ()
3802 : : {
3803 : 27 : std::unique_ptr<LiteralExpr> lit_expr = parser->parse_literal_expr ({});
3804 : :
3805 : : // TODO: return nullptr instead?
3806 : 27 : if (!lit_expr)
3807 : 0 : lit_expr = std::unique_ptr<LiteralExpr> (
3808 : 0 : new LiteralExpr (Literal::create_error (), {},
3809 : 0 : lexer->peek_token ()->get_locus ()));
3810 : :
3811 : 27 : return std::unique_ptr<MetaItemLitExpr> (
3812 : 27 : new MetaItemLitExpr (std::move (*lit_expr)));
3813 : 27 : }
3814 : :
3815 : : bool
3816 : 0 : AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const
3817 : : {
3818 : 0 : if (items.empty ())
3819 : : return false;
3820 : :
3821 : 0 : for (const auto &inner_item : items)
3822 : : {
3823 : 0 : if (!inner_item->check_cfg_predicate (session))
3824 : 0 : return false;
3825 : : }
3826 : :
3827 : : return true;
3828 : : }
3829 : :
3830 : : bool
3831 : 0 : MetaItemLitExpr::check_cfg_predicate (const Session &) const
3832 : : {
3833 : : /* as far as I can tell, a literal expr can never be a valid cfg body, so
3834 : : * false */
3835 : 0 : return false;
3836 : : }
3837 : :
3838 : : bool
3839 : 0 : MetaListNameValueStr::check_cfg_predicate (const Session &session) const
3840 : : {
3841 : 0 : if (ident.as_string () == "all")
3842 : : {
3843 : 0 : for (const auto &str : strs)
3844 : : {
3845 : 0 : if (!str.check_cfg_predicate (session))
3846 : 0 : return false;
3847 : : }
3848 : : return true;
3849 : : }
3850 : 0 : else if (ident.as_string () == "any")
3851 : : {
3852 : 0 : for (const auto &str : strs)
3853 : : {
3854 : 0 : if (str.check_cfg_predicate (session))
3855 : 0 : return true;
3856 : : }
3857 : : return false;
3858 : : }
3859 : 0 : else if (ident.as_string () == "not")
3860 : : {
3861 : 0 : if (strs.size () != 1)
3862 : : {
3863 : : /* HACK: convert vector platform-dependent size_type to string to
3864 : : * use in printf */
3865 : 0 : rust_error_at (UNKNOWN_LOCATION,
3866 : : "cfg predicate could not be checked for "
3867 : : "MetaListNameValueStr with ident of "
3868 : : "'not' because there are '%s' elements, not '1'",
3869 : 0 : std::to_string (strs.size ()).c_str ());
3870 : 0 : return false;
3871 : : }
3872 : :
3873 : 0 : return !strs[0].check_cfg_predicate (session);
3874 : : }
3875 : : else
3876 : : {
3877 : 0 : rust_error_at (UNKNOWN_LOCATION,
3878 : : "cfg predicate could not be checked for "
3879 : : "MetaListNameValueStr with ident of "
3880 : : "'%s' - ident must be 'all' or 'any'",
3881 : 0 : ident.as_string ().c_str ());
3882 : 0 : return false;
3883 : : }
3884 : : }
3885 : :
3886 : : bool
3887 : 0 : MetaListPaths::check_cfg_predicate (const Session &session) const
3888 : : {
3889 : 0 : if (ident.as_string () == "all")
3890 : : {
3891 : 0 : for (const auto &path : paths)
3892 : : {
3893 : 0 : if (!check_path_exists_in_cfg (session, path))
3894 : 0 : return false;
3895 : : }
3896 : : return true;
3897 : : }
3898 : 0 : else if (ident.as_string () == "any")
3899 : : {
3900 : 0 : for (const auto &path : paths)
3901 : : {
3902 : 0 : if (check_path_exists_in_cfg (session, path))
3903 : 0 : return true;
3904 : : }
3905 : : return false;
3906 : : }
3907 : 0 : else if (ident.as_string () == "not")
3908 : : {
3909 : 0 : if (paths.size () != 1)
3910 : : {
3911 : : // HACK: convert vector platform-dependent size_type to string to
3912 : : // use in printf
3913 : 0 : rust_error_at (UNKNOWN_LOCATION,
3914 : : "cfg predicate could not be checked for MetaListPaths "
3915 : : "with ident of 'not' "
3916 : : "because there are '%s' elements, not '1'",
3917 : 0 : std::to_string (paths.size ()).c_str ());
3918 : 0 : return false;
3919 : : }
3920 : :
3921 : 0 : return !check_path_exists_in_cfg (session, paths[0]);
3922 : : }
3923 : : else
3924 : : {
3925 : 0 : rust_error_at (UNKNOWN_LOCATION,
3926 : : "cfg predicate could not be checked for "
3927 : : "MetaListNameValueStr with ident of "
3928 : : "'%s' - ident must be 'all' or 'any'",
3929 : 0 : ident.as_string ().c_str ());
3930 : 0 : return false;
3931 : : }
3932 : : }
3933 : :
3934 : : bool
3935 : 0 : MetaListPaths::check_path_exists_in_cfg (const Session &session,
3936 : : const SimplePath &path) const
3937 : : {
3938 : 0 : return session.options.target_data.has_key (path.as_string ());
3939 : : }
3940 : :
3941 : : bool
3942 : 113 : MetaItemSeq::check_cfg_predicate (const Session &session) const
3943 : : {
3944 : 113 : if (path.as_string () == "all")
3945 : : {
3946 : 19 : for (const auto &item : seq)
3947 : : {
3948 : 15 : if (!item->check_cfg_predicate (session))
3949 : 13 : return false;
3950 : : }
3951 : : return true;
3952 : : }
3953 : 102 : else if (path.as_string () == "any")
3954 : : {
3955 : 32 : for (const auto &item : seq)
3956 : : {
3957 : 26 : if (item->check_cfg_predicate (session))
3958 : 9 : return true;
3959 : : }
3960 : : return false;
3961 : : }
3962 : 91 : else if (path.as_string () == "not")
3963 : : {
3964 : 91 : if (seq.size () != 1)
3965 : : {
3966 : : /* HACK: convert vector platform-dependent size_type to string to
3967 : : * use in printf */
3968 : 0 : rust_error_at (UNKNOWN_LOCATION,
3969 : : "cfg predicate could not be checked for MetaItemSeq "
3970 : : "with ident of 'not' "
3971 : : "because there are '%s' elements, not '1'",
3972 : 0 : std::to_string (seq.size ()).c_str ());
3973 : 0 : return false;
3974 : : }
3975 : :
3976 : 91 : return !seq[0]->check_cfg_predicate (session);
3977 : : }
3978 : : else
3979 : : {
3980 : 0 : rust_error_at (
3981 : : UNKNOWN_LOCATION,
3982 : : "cfg predicate could not be checked for MetaItemSeq with path of "
3983 : : "'%s' - path must be 'all' or 'any'",
3984 : 0 : path.as_string ().c_str ());
3985 : 0 : return false;
3986 : : }
3987 : : }
3988 : :
3989 : : bool
3990 : 315 : MetaWord::check_cfg_predicate (const Session &session) const
3991 : : {
3992 : 630 : return session.options.target_data.has_key (ident.as_string ());
3993 : : }
3994 : :
3995 : : bool
3996 : 0 : MetaItemPath::check_cfg_predicate (const Session &session) const
3997 : : {
3998 : : /* Strictly speaking, this should always be false, but maybe do check
3999 : : * relating to SimplePath being identifier. Currently, it would return true
4000 : : * if path as identifier existed, and if the path in string form existed
4001 : : * (though this shouldn't occur). */
4002 : 0 : return session.options.target_data.has_key (path.as_string ());
4003 : : }
4004 : :
4005 : : bool
4006 : 1881 : MetaNameValueStr::check_cfg_predicate (const Session &session) const
4007 : : {
4008 : : // DEBUG
4009 : 5674 : rust_debug (
4010 : : "checked key-value pair for cfg: '%s', '%s' - is%s in target data",
4011 : : ident.as_string ().c_str (), str.c_str (),
4012 : : session.options.target_data.has_key_value_pair (ident.as_string (), str)
4013 : : ? ""
4014 : : : " not");
4015 : :
4016 : 3762 : return session.options.target_data.has_key_value_pair (ident.as_string (),
4017 : 1881 : str);
4018 : : }
4019 : :
4020 : : bool
4021 : 0 : MetaItemPathExpr::check_cfg_predicate (const Session &session) const
4022 : : {
4023 : : // FIXME: Accept path expressions
4024 : 0 : rust_assert (expr->is_literal ());
4025 : 0 : return session.options.target_data.has_key_value_pair (path.as_string (),
4026 : 0 : expr->as_string ());
4027 : : }
4028 : :
4029 : : std::vector<std::unique_ptr<Token>>
4030 : 121461 : Token::to_token_stream () const
4031 : : {
4032 : : /* initialisation list doesn't work as it needs copy constructor, so have to
4033 : : * do this */
4034 : 121461 : std::vector<std::unique_ptr<Token>> dummy_vector;
4035 : 121461 : dummy_vector.reserve (1);
4036 : 121461 : dummy_vector.push_back (std::unique_ptr<Token> (clone_token_impl ()));
4037 : 121461 : return dummy_vector;
4038 : : }
4039 : :
4040 : : Attribute
4041 : 0 : MetaNameValueStr::to_attribute () const
4042 : : {
4043 : 0 : LiteralExpr lit_expr (str, Literal::LitType::STRING,
4044 : 0 : PrimitiveCoreType::CORETYPE_UNKNOWN, {}, str_locus);
4045 : : // FIXME: What location do we put here? Is the literal above supposed to have
4046 : : // an empty location as well?
4047 : : // Should MetaNameValueStr keep a location?
4048 : 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4049 : 0 : std::unique_ptr<AttrInputLiteral> (
4050 : 0 : new AttrInputLiteral (std::move (lit_expr))));
4051 : 0 : }
4052 : :
4053 : : Attribute
4054 : 0 : MetaItemPath::to_attribute () const
4055 : : {
4056 : 0 : return Attribute (path, nullptr);
4057 : : }
4058 : :
4059 : : Attribute
4060 : 6 : MetaItemSeq::to_attribute () const
4061 : : {
4062 : 6 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4063 : 6 : new_seq.reserve (seq.size ());
4064 : 12 : for (const auto &e : seq)
4065 : 6 : new_seq.push_back (e->clone_meta_item_inner ());
4066 : :
4067 : 6 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4068 : 6 : new AttrInputMetaItemContainer (std::move (new_seq)));
4069 : 6 : return Attribute (path, std::move (new_seq_container));
4070 : 6 : }
4071 : :
4072 : : Attribute
4073 : 0 : MetaWord::to_attribute () const
4074 : : {
4075 : 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4076 : 0 : nullptr);
4077 : : }
4078 : :
4079 : : Attribute
4080 : 0 : MetaListPaths::to_attribute () const
4081 : : {
4082 : : /* probably one of the most annoying conversions - have to lose specificity by
4083 : : * turning it into just AttrInputMetaItemContainer (i.e. paths-only nature is
4084 : : * no longer known). If conversions back are required, might have to do a
4085 : : * "check all are paths" pass or something. */
4086 : :
4087 : 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4088 : 0 : new_seq.reserve (paths.size ());
4089 : 0 : for (const auto &e : paths)
4090 : 0 : new_seq.push_back (std::unique_ptr<MetaItemPath> (new MetaItemPath (e)));
4091 : :
4092 : 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4093 : 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4094 : 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4095 : 0 : std::move (new_seq_container));
4096 : 0 : }
4097 : :
4098 : : Attribute
4099 : 0 : MetaListNameValueStr::to_attribute () const
4100 : : {
4101 : 0 : std::vector<std::unique_ptr<MetaItemInner>> new_seq;
4102 : 0 : new_seq.reserve (strs.size ());
4103 : 0 : for (const auto &e : strs)
4104 : 0 : new_seq.push_back (
4105 : 0 : std::unique_ptr<MetaNameValueStr> (new MetaNameValueStr (e)));
4106 : :
4107 : 0 : std::unique_ptr<AttrInputMetaItemContainer> new_seq_container (
4108 : 0 : new AttrInputMetaItemContainer (std::move (new_seq)));
4109 : 0 : return Attribute (SimplePath::from_str (ident.as_string (), ident_locus),
4110 : 0 : std::move (new_seq_container));
4111 : 0 : }
4112 : :
4113 : : Attribute
4114 : 0 : MetaItemPathExpr::to_attribute () const
4115 : : {
4116 : 0 : rust_assert (expr->is_literal ());
4117 : 0 : auto &lit = static_cast<LiteralExpr &> (*expr);
4118 : 0 : return Attribute (path, std::unique_ptr<AttrInputLiteral> (
4119 : 0 : new AttrInputLiteral (lit)));
4120 : : }
4121 : :
4122 : : std::vector<Attribute>
4123 : 6 : AttrInputMetaItemContainer::separate_cfg_attrs () const
4124 : : {
4125 : 6 : rust_assert (!items.empty ());
4126 : :
4127 : 6 : if (items.size () == 1)
4128 : 0 : return {};
4129 : :
4130 : 6 : std::vector<Attribute> attrs;
4131 : 6 : attrs.reserve (items.size () - 1);
4132 : :
4133 : 12 : for (auto it = items.begin () + 1; it != items.end (); ++it)
4134 : : {
4135 : 6 : Attribute attr = (*it)->to_attribute ();
4136 : 6 : if (attr.is_empty ())
4137 : : {
4138 : : /* TODO should this be an error that causes us to chuck out
4139 : : * everything? */
4140 : 0 : continue;
4141 : : }
4142 : 6 : attrs.push_back (std::move (attr));
4143 : 6 : }
4144 : :
4145 : 6 : attrs.shrink_to_fit ();
4146 : 6 : return attrs;
4147 : 6 : }
4148 : :
4149 : : bool
4150 : 2130 : Attribute::check_cfg_predicate (const Session &session) const
4151 : : {
4152 : : /* assume that cfg predicate actually can exist, i.e. attribute has cfg or
4153 : : * cfg_attr path */
4154 : 4260 : if (!has_attr_input ()
4155 : 4260 : || (path.as_string () != Values::Attributes::CFG
4156 : 2150 : && path.as_string () != Values::Attributes::CFG_ATTR))
4157 : : {
4158 : : // DEBUG message
4159 : 0 : rust_debug (
4160 : : "tried to check cfg predicate on attr that either has no input "
4161 : : "or invalid path. attr: '%s'",
4162 : : as_string ().c_str ());
4163 : :
4164 : 0 : return false;
4165 : : }
4166 : :
4167 : : // assume that it has already been parsed
4168 : 2130 : if (!is_parsed_to_meta_item ())
4169 : : return false;
4170 : :
4171 : 2130 : auto &meta_item = static_cast<AttrInputMetaItemContainer &> (*attr_input);
4172 : 2130 : return meta_item.get_items ().front ()->check_cfg_predicate (session);
4173 : : }
4174 : :
4175 : : std::vector<Attribute>
4176 : 6 : Attribute::separate_cfg_attrs () const
4177 : : {
4178 : 12 : if (!has_attr_input () || path.as_string () != Values::Attributes::CFG_ATTR)
4179 : 0 : return {};
4180 : :
4181 : : // assume that it has already been parsed
4182 : 6 : if (!is_parsed_to_meta_item ())
4183 : 0 : return {};
4184 : :
4185 : 6 : return attr_input->separate_cfg_attrs ();
4186 : : }
4187 : :
4188 : : bool
4189 : 7273 : Attribute::is_parsed_to_meta_item () const
4190 : : {
4191 : 7273 : return has_attr_input () && attr_input->is_meta_item ();
4192 : : }
4193 : :
4194 : : void
4195 : 33972 : BlockExpr::normalize_tail_expr ()
4196 : : {
4197 : 33972 : if (!expr)
4198 : : {
4199 : : // HACK: try to turn the last statement into a tail expression
4200 : 18420 : if (!statements.empty () && statements.back ()->is_expr ())
4201 : : {
4202 : : // Watch out: This reference become invalid when the vector is
4203 : : // modified.
4204 : 11862 : auto &stmt = static_cast<ExprStmt &> (*statements.back ());
4205 : :
4206 : 11862 : if (!stmt.is_semicolon_followed ())
4207 : : {
4208 : 59 : expr = stmt.take_expr ();
4209 : 59 : statements.pop_back ();
4210 : : }
4211 : : }
4212 : : }
4213 : 33972 : }
4214 : :
4215 : : // needed here because "rust-expr.h" doesn't include "rust-macro.h"
4216 : 6 : AttrInputMacro::AttrInputMacro (const AttrInputMacro &oth)
4217 : 6 : : macro (oth.macro->clone_macro_invocation_impl ())
4218 : 6 : {}
4219 : :
4220 : : AttrInputMacro &
4221 : 0 : AttrInputMacro::operator= (const AttrInputMacro &oth)
4222 : : {
4223 : 0 : macro = std::unique_ptr<MacroInvocation> (
4224 : 0 : oth.macro->clone_macro_invocation_impl ());
4225 : 0 : return *this;
4226 : : }
4227 : :
4228 : : /* Visitor implementations - these are short but inlining can't happen anyway
4229 : : * due to virtual functions and I didn't want to make the ast header includes
4230 : : * any longer than they already are. */
4231 : :
4232 : : void
4233 : 366707 : Token::accept_vis (ASTVisitor &vis)
4234 : : {
4235 : 366707 : vis.visit (*this);
4236 : 366707 : }
4237 : :
4238 : : void
4239 : 47677 : DelimTokenTree::accept_vis (ASTVisitor &vis)
4240 : : {
4241 : 47677 : vis.visit (*this);
4242 : 47677 : }
4243 : :
4244 : : void
4245 : 527789 : IdentifierExpr::accept_vis (ASTVisitor &vis)
4246 : : {
4247 : 527789 : vis.visit (*this);
4248 : 527788 : }
4249 : :
4250 : : void
4251 : 192 : Lifetime::accept_vis (ASTVisitor &vis)
4252 : : {
4253 : 192 : vis.visit (*this);
4254 : 192 : }
4255 : :
4256 : : void
4257 : 3709 : LifetimeParam::accept_vis (ASTVisitor &vis)
4258 : : {
4259 : 3709 : vis.visit (*this);
4260 : 3709 : }
4261 : :
4262 : : void
4263 : 2445477 : LiteralExpr::accept_vis (ASTVisitor &vis)
4264 : : {
4265 : 2445477 : vis.visit (*this);
4266 : 2445477 : }
4267 : :
4268 : : void
4269 : 0 : AttrInputLiteral::accept_vis (ASTVisitor &vis)
4270 : : {
4271 : 0 : vis.visit (*this);
4272 : 0 : }
4273 : :
4274 : : void
4275 : 0 : AttrInputMacro::accept_vis (ASTVisitor &vis)
4276 : : {
4277 : 0 : vis.visit (*this);
4278 : 0 : }
4279 : :
4280 : : void
4281 : 0 : MetaItemLitExpr::accept_vis (ASTVisitor &vis)
4282 : : {
4283 : 0 : vis.visit (*this);
4284 : 0 : }
4285 : :
4286 : : void
4287 : 0 : MetaItemPathExpr::accept_vis (ASTVisitor &vis)
4288 : : {
4289 : 0 : vis.visit (*this);
4290 : 0 : }
4291 : :
4292 : : void
4293 : 44260 : BorrowExpr::accept_vis (ASTVisitor &vis)
4294 : : {
4295 : 44260 : vis.visit (*this);
4296 : 44260 : }
4297 : :
4298 : : void
4299 : 77713 : DereferenceExpr::accept_vis (ASTVisitor &vis)
4300 : : {
4301 : 77713 : vis.visit (*this);
4302 : 77713 : }
4303 : :
4304 : : void
4305 : 11 : ErrorPropagationExpr::accept_vis (ASTVisitor &vis)
4306 : : {
4307 : 11 : vis.visit (*this);
4308 : 11 : }
4309 : :
4310 : : void
4311 : 9525 : NegationExpr::accept_vis (ASTVisitor &vis)
4312 : : {
4313 : 9525 : vis.visit (*this);
4314 : 9525 : }
4315 : :
4316 : : void
4317 : 2161474 : ArithmeticOrLogicalExpr::accept_vis (ASTVisitor &vis)
4318 : : {
4319 : 2161474 : vis.visit (*this);
4320 : 2161474 : }
4321 : :
4322 : : void
4323 : 52200 : ComparisonExpr::accept_vis (ASTVisitor &vis)
4324 : : {
4325 : 52200 : vis.visit (*this);
4326 : 52200 : }
4327 : :
4328 : : void
4329 : 6654 : LazyBooleanExpr::accept_vis (ASTVisitor &vis)
4330 : : {
4331 : 6654 : vis.visit (*this);
4332 : 6654 : }
4333 : :
4334 : : void
4335 : 118057 : TypeCastExpr::accept_vis (ASTVisitor &vis)
4336 : : {
4337 : 118057 : vis.visit (*this);
4338 : 118057 : }
4339 : :
4340 : : void
4341 : 46113 : AssignmentExpr::accept_vis (ASTVisitor &vis)
4342 : : {
4343 : 46113 : vis.visit (*this);
4344 : 46113 : }
4345 : :
4346 : : void
4347 : 13635 : CompoundAssignmentExpr::accept_vis (ASTVisitor &vis)
4348 : : {
4349 : 13635 : vis.visit (*this);
4350 : 13635 : }
4351 : :
4352 : : void
4353 : 4250 : ArrayElemsValues::accept_vis (ASTVisitor &vis)
4354 : : {
4355 : 4250 : vis.visit (*this);
4356 : 4250 : }
4357 : :
4358 : : void
4359 : 1963 : ArrayElemsCopied::accept_vis (ASTVisitor &vis)
4360 : : {
4361 : 1963 : vis.visit (*this);
4362 : 1963 : }
4363 : :
4364 : : void
4365 : 6227 : ArrayExpr::accept_vis (ASTVisitor &vis)
4366 : : {
4367 : 6227 : vis.visit (*this);
4368 : 6227 : }
4369 : :
4370 : : void
4371 : 3794 : ArrayIndexExpr::accept_vis (ASTVisitor &vis)
4372 : : {
4373 : 3794 : vis.visit (*this);
4374 : 3794 : }
4375 : :
4376 : : void
4377 : 9787 : TupleExpr::accept_vis (ASTVisitor &vis)
4378 : : {
4379 : 9787 : vis.visit (*this);
4380 : 9787 : }
4381 : :
4382 : : void
4383 : 17669 : TupleIndexExpr::accept_vis (ASTVisitor &vis)
4384 : : {
4385 : 17669 : vis.visit (*this);
4386 : 17669 : }
4387 : :
4388 : : void
4389 : 1170 : StructExprStruct::accept_vis (ASTVisitor &vis)
4390 : : {
4391 : 1170 : vis.visit (*this);
4392 : 1170 : }
4393 : :
4394 : : void
4395 : 3474 : StructExprFieldIdentifier::accept_vis (ASTVisitor &vis)
4396 : : {
4397 : 3474 : vis.visit (*this);
4398 : 3474 : }
4399 : :
4400 : : void
4401 : 37217 : StructExprFieldIdentifierValue::accept_vis (ASTVisitor &vis)
4402 : : {
4403 : 37217 : vis.visit (*this);
4404 : 37217 : }
4405 : :
4406 : : void
4407 : 748 : StructExprFieldIndexValue::accept_vis (ASTVisitor &vis)
4408 : : {
4409 : 748 : vis.visit (*this);
4410 : 748 : }
4411 : :
4412 : : void
4413 : 23862 : StructExprStructFields::accept_vis (ASTVisitor &vis)
4414 : : {
4415 : 23862 : vis.visit (*this);
4416 : 23862 : }
4417 : :
4418 : : void
4419 : 0 : StructExprStructBase::accept_vis (ASTVisitor &vis)
4420 : : {
4421 : 0 : vis.visit (*this);
4422 : 0 : }
4423 : :
4424 : : void
4425 : 219825 : CallExpr::accept_vis (ASTVisitor &vis)
4426 : : {
4427 : 219825 : vis.visit (*this);
4428 : 219825 : }
4429 : :
4430 : : void
4431 : 58824 : MethodCallExpr::accept_vis (ASTVisitor &vis)
4432 : : {
4433 : 58824 : vis.visit (*this);
4434 : 58824 : }
4435 : :
4436 : : void
4437 : 96574 : FieldAccessExpr::accept_vis (ASTVisitor &vis)
4438 : : {
4439 : 96574 : vis.visit (*this);
4440 : 96574 : }
4441 : :
4442 : : void
4443 : 597 : ClosureExprInner::accept_vis (ASTVisitor &vis)
4444 : : {
4445 : 597 : vis.visit (*this);
4446 : 597 : }
4447 : :
4448 : : void
4449 : 307693 : BlockExpr::accept_vis (ASTVisitor &vis)
4450 : : {
4451 : 307693 : vis.visit (*this);
4452 : 307692 : }
4453 : :
4454 : : void
4455 : 603 : AnonConst::accept_vis (ASTVisitor &vis)
4456 : : {
4457 : 603 : vis.visit (*this);
4458 : 603 : }
4459 : :
4460 : : void
4461 : 112 : ConstBlock::accept_vis (ASTVisitor &vis)
4462 : : {
4463 : 112 : vis.visit (*this);
4464 : 112 : }
4465 : :
4466 : : void
4467 : 511 : ClosureExprInnerTyped::accept_vis (ASTVisitor &vis)
4468 : : {
4469 : 511 : vis.visit (*this);
4470 : 511 : }
4471 : :
4472 : : void
4473 : 257 : ContinueExpr::accept_vis (ASTVisitor &vis)
4474 : : {
4475 : 257 : vis.visit (*this);
4476 : 257 : }
4477 : :
4478 : : void
4479 : 1585 : BreakExpr::accept_vis (ASTVisitor &vis)
4480 : : {
4481 : 1585 : vis.visit (*this);
4482 : 1584 : }
4483 : :
4484 : : void
4485 : 1347 : RangeFromToExpr::accept_vis (ASTVisitor &vis)
4486 : : {
4487 : 1347 : vis.visit (*this);
4488 : 1347 : }
4489 : :
4490 : : void
4491 : 119 : RangeFromExpr::accept_vis (ASTVisitor &vis)
4492 : : {
4493 : 119 : vis.visit (*this);
4494 : 119 : }
4495 : :
4496 : : void
4497 : 119 : RangeToExpr::accept_vis (ASTVisitor &vis)
4498 : : {
4499 : 119 : vis.visit (*this);
4500 : 119 : }
4501 : :
4502 : : void
4503 : 0 : RangeFullExpr::accept_vis (ASTVisitor &vis)
4504 : : {
4505 : 0 : vis.visit (*this);
4506 : 0 : }
4507 : :
4508 : : void
4509 : 119 : RangeFromToInclExpr::accept_vis (ASTVisitor &vis)
4510 : : {
4511 : 119 : vis.visit (*this);
4512 : 119 : }
4513 : :
4514 : : void
4515 : 0 : RangeToInclExpr::accept_vis (ASTVisitor &vis)
4516 : : {
4517 : 0 : vis.visit (*this);
4518 : 0 : }
4519 : :
4520 : : void
4521 : 9171 : ReturnExpr::accept_vis (ASTVisitor &vis)
4522 : : {
4523 : 9171 : vis.visit (*this);
4524 : 9171 : }
4525 : :
4526 : : void
4527 : 11 : TryExpr::accept_vis (ASTVisitor &vis)
4528 : : {
4529 : 11 : vis.visit (*this);
4530 : 11 : }
4531 : :
4532 : : void
4533 : 64379 : UnsafeBlockExpr::accept_vis (ASTVisitor &vis)
4534 : : {
4535 : 64379 : vis.visit (*this);
4536 : 64379 : }
4537 : :
4538 : : void
4539 : 1914 : LoopExpr::accept_vis (ASTVisitor &vis)
4540 : : {
4541 : 1914 : vis.visit (*this);
4542 : 1914 : }
4543 : :
4544 : : void
4545 : 1535 : WhileLoopExpr::accept_vis (ASTVisitor &vis)
4546 : : {
4547 : 1535 : vis.visit (*this);
4548 : 1535 : }
4549 : :
4550 : : void
4551 : 20 : WhileLetLoopExpr::accept_vis (ASTVisitor &vis)
4552 : : {
4553 : 20 : vis.visit (*this);
4554 : 20 : }
4555 : :
4556 : : void
4557 : 329 : ForLoopExpr::accept_vis (ASTVisitor &vis)
4558 : : {
4559 : 329 : vis.visit (*this);
4560 : 329 : }
4561 : :
4562 : : void
4563 : 8555 : IfExpr::accept_vis (ASTVisitor &vis)
4564 : : {
4565 : 8555 : vis.visit (*this);
4566 : 8555 : }
4567 : :
4568 : : void
4569 : 25370 : IfExprConseqElse::accept_vis (ASTVisitor &vis)
4570 : : {
4571 : 25370 : vis.visit (*this);
4572 : 25370 : }
4573 : :
4574 : : void
4575 : 323 : IfLetExpr::accept_vis (ASTVisitor &vis)
4576 : : {
4577 : 323 : vis.visit (*this);
4578 : 323 : }
4579 : :
4580 : : void
4581 : 209 : IfLetExprConseqElse::accept_vis (ASTVisitor &vis)
4582 : : {
4583 : 209 : vis.visit (*this);
4584 : 209 : }
4585 : :
4586 : : void
4587 : 18948 : MatchExpr::accept_vis (ASTVisitor &vis)
4588 : : {
4589 : 18948 : vis.visit (*this);
4590 : 18948 : }
4591 : :
4592 : : void
4593 : 0 : AwaitExpr::accept_vis (ASTVisitor &vis)
4594 : : {
4595 : 0 : vis.visit (*this);
4596 : 0 : }
4597 : :
4598 : : void
4599 : 0 : AsyncBlockExpr::accept_vis (ASTVisitor &vis)
4600 : : {
4601 : 0 : vis.visit (*this);
4602 : 0 : }
4603 : :
4604 : : void
4605 : 341 : InlineAsm::accept_vis (ASTVisitor &vis)
4606 : : {
4607 : 341 : vis.visit (*this);
4608 : 341 : }
4609 : :
4610 : : void
4611 : 28 : LlvmInlineAsm::accept_vis (ASTVisitor &vis)
4612 : : {
4613 : 28 : vis.visit (*this);
4614 : 28 : }
4615 : :
4616 : : void
4617 : 80922 : TypeParam::accept_vis (ASTVisitor &vis)
4618 : : {
4619 : 80922 : vis.visit (*this);
4620 : 80922 : }
4621 : :
4622 : : void
4623 : 30 : LifetimeWhereClauseItem::accept_vis (ASTVisitor &vis)
4624 : : {
4625 : 30 : vis.visit (*this);
4626 : 30 : }
4627 : :
4628 : : void
4629 : 5810 : TypeBoundWhereClauseItem::accept_vis (ASTVisitor &vis)
4630 : : {
4631 : 5810 : vis.visit (*this);
4632 : 5810 : }
4633 : :
4634 : : void
4635 : 23826 : Module::accept_vis (ASTVisitor &vis)
4636 : : {
4637 : 23826 : vis.visit (*this);
4638 : 23826 : }
4639 : :
4640 : : void
4641 : 432 : ExternCrate::accept_vis (ASTVisitor &vis)
4642 : : {
4643 : 432 : vis.visit (*this);
4644 : 432 : }
4645 : :
4646 : : void
4647 : 73 : UseTreeGlob::accept_vis (ASTVisitor &vis)
4648 : : {
4649 : 73 : vis.visit (*this);
4650 : 73 : }
4651 : :
4652 : : void
4653 : 1340 : UseTreeList::accept_vis (ASTVisitor &vis)
4654 : : {
4655 : 1340 : vis.visit (*this);
4656 : 1340 : }
4657 : :
4658 : : void
4659 : 4198 : UseTreeRebind::accept_vis (ASTVisitor &vis)
4660 : : {
4661 : 4198 : vis.visit (*this);
4662 : 4198 : }
4663 : :
4664 : : void
4665 : 12816 : UseDeclaration::accept_vis (ASTVisitor &vis)
4666 : : {
4667 : 12816 : vis.visit (*this);
4668 : 12816 : }
4669 : :
4670 : : void
4671 : 347388 : Function::accept_vis (ASTVisitor &vis)
4672 : : {
4673 : 347388 : vis.visit (*this);
4674 : 347387 : }
4675 : :
4676 : : void
4677 : 25884 : TypeAlias::accept_vis (ASTVisitor &vis)
4678 : : {
4679 : 25884 : vis.visit (*this);
4680 : 25884 : }
4681 : :
4682 : : void
4683 : 27610 : StructStruct::accept_vis (ASTVisitor &vis)
4684 : : {
4685 : 27610 : vis.visit (*this);
4686 : 27610 : }
4687 : :
4688 : : void
4689 : 16918 : TupleStruct::accept_vis (ASTVisitor &vis)
4690 : : {
4691 : 16918 : vis.visit (*this);
4692 : 16918 : }
4693 : :
4694 : : void
4695 : 8692 : EnumItem::accept_vis (ASTVisitor &vis)
4696 : : {
4697 : 8692 : vis.visit (*this);
4698 : 8692 : }
4699 : :
4700 : : void
4701 : 8926 : EnumItemTuple::accept_vis (ASTVisitor &vis)
4702 : : {
4703 : 8926 : vis.visit (*this);
4704 : 8926 : }
4705 : :
4706 : : void
4707 : 1759 : EnumItemStruct::accept_vis (ASTVisitor &vis)
4708 : : {
4709 : 1759 : vis.visit (*this);
4710 : 1759 : }
4711 : :
4712 : : void
4713 : 5593 : EnumItemDiscriminant::accept_vis (ASTVisitor &vis)
4714 : : {
4715 : 5593 : vis.visit (*this);
4716 : 5593 : }
4717 : :
4718 : : void
4719 : 9932 : Enum::accept_vis (ASTVisitor &vis)
4720 : : {
4721 : 9932 : vis.visit (*this);
4722 : 9932 : }
4723 : :
4724 : : void
4725 : 1830 : Union::accept_vis (ASTVisitor &vis)
4726 : : {
4727 : 1830 : vis.visit (*this);
4728 : 1830 : }
4729 : :
4730 : : void
4731 : 8586 : ConstantItem::accept_vis (ASTVisitor &vis)
4732 : : {
4733 : 8586 : vis.visit (*this);
4734 : 8586 : }
4735 : :
4736 : : void
4737 : 933 : StaticItem::accept_vis (ASTVisitor &vis)
4738 : : {
4739 : 933 : vis.visit (*this);
4740 : 933 : }
4741 : :
4742 : : void
4743 : 754 : TraitItemConst::accept_vis (ASTVisitor &vis)
4744 : : {
4745 : 754 : vis.visit (*this);
4746 : 754 : }
4747 : :
4748 : : void
4749 : 15342 : TraitItemType::accept_vis (ASTVisitor &vis)
4750 : : {
4751 : 15342 : vis.visit (*this);
4752 : 15342 : }
4753 : :
4754 : : void
4755 : 68549 : Trait::accept_vis (ASTVisitor &vis)
4756 : : {
4757 : 68549 : vis.visit (*this);
4758 : 68549 : }
4759 : :
4760 : : void
4761 : 16612 : InherentImpl::accept_vis (ASTVisitor &vis)
4762 : : {
4763 : 16612 : vis.visit (*this);
4764 : 16612 : }
4765 : :
4766 : : void
4767 : 81488 : TraitImpl::accept_vis (ASTVisitor &vis)
4768 : : {
4769 : 81488 : vis.visit (*this);
4770 : 81488 : }
4771 : :
4772 : : void
4773 : 15 : ExternalTypeItem::accept_vis (ASTVisitor &vis)
4774 : : {
4775 : 15 : vis.visit (*this);
4776 : 15 : }
4777 : :
4778 : : void
4779 : 16 : ExternalStaticItem::accept_vis (ASTVisitor &vis)
4780 : : {
4781 : 16 : vis.visit (*this);
4782 : 16 : }
4783 : :
4784 : : void
4785 : 26325 : ExternBlock::accept_vis (ASTVisitor &vis)
4786 : : {
4787 : 26325 : vis.visit (*this);
4788 : 26325 : }
4789 : :
4790 : : void
4791 : 10800 : MacroMatchFragment::accept_vis (ASTVisitor &vis)
4792 : : {
4793 : 10800 : vis.visit (*this);
4794 : 10800 : }
4795 : :
4796 : : void
4797 : 5175 : MacroMatchRepetition::accept_vis (ASTVisitor &vis)
4798 : : {
4799 : 5175 : vis.visit (*this);
4800 : 5175 : }
4801 : :
4802 : : void
4803 : 512 : MacroMatcher::accept_vis (ASTVisitor &vis)
4804 : : {
4805 : 512 : vis.visit (*this);
4806 : 512 : }
4807 : :
4808 : : void
4809 : 23180 : MacroRulesDefinition::accept_vis (ASTVisitor &vis)
4810 : : {
4811 : 23180 : vis.visit (*this);
4812 : 23180 : }
4813 : :
4814 : : void
4815 : 14788 : MacroInvocation::accept_vis (ASTVisitor &vis)
4816 : : {
4817 : 14788 : vis.visit (*this);
4818 : 14788 : }
4819 : :
4820 : : void
4821 : 1111 : EmptyStmt::accept_vis (ASTVisitor &vis)
4822 : : {
4823 : 1111 : vis.visit (*this);
4824 : 1111 : }
4825 : :
4826 : : void
4827 : 250370 : LetStmt::accept_vis (ASTVisitor &vis)
4828 : : {
4829 : 250370 : vis.visit (*this);
4830 : 250370 : }
4831 : :
4832 : : void
4833 : 185289 : ExprStmt::accept_vis (ASTVisitor &vis)
4834 : : {
4835 : 185289 : vis.visit (*this);
4836 : 185288 : }
4837 : :
4838 : : void
4839 : 34380 : TraitBound::accept_vis (ASTVisitor &vis)
4840 : : {
4841 : 34380 : vis.visit (*this);
4842 : 34380 : }
4843 : :
4844 : : void
4845 : 0 : ImplTraitType::accept_vis (ASTVisitor &vis)
4846 : : {
4847 : 0 : vis.visit (*this);
4848 : 0 : }
4849 : :
4850 : : void
4851 : 214 : TraitObjectType::accept_vis (ASTVisitor &vis)
4852 : : {
4853 : 214 : vis.visit (*this);
4854 : 214 : }
4855 : :
4856 : : void
4857 : 68 : ParenthesisedType::accept_vis (ASTVisitor &vis)
4858 : : {
4859 : 68 : vis.visit (*this);
4860 : 68 : }
4861 : :
4862 : : void
4863 : 1819 : ImplTraitTypeOneBound::accept_vis (ASTVisitor &vis)
4864 : : {
4865 : 1819 : vis.visit (*this);
4866 : 1819 : }
4867 : :
4868 : : void
4869 : 2750 : TraitObjectTypeOneBound::accept_vis (ASTVisitor &vis)
4870 : : {
4871 : 2750 : vis.visit (*this);
4872 : 2750 : }
4873 : :
4874 : : void
4875 : 7472 : TupleType::accept_vis (ASTVisitor &vis)
4876 : : {
4877 : 7472 : vis.visit (*this);
4878 : 7472 : }
4879 : :
4880 : : void
4881 : 1016 : NeverType::accept_vis (ASTVisitor &vis)
4882 : : {
4883 : 1016 : vis.visit (*this);
4884 : 1016 : }
4885 : :
4886 : : void
4887 : 136063 : RawPointerType::accept_vis (ASTVisitor &vis)
4888 : : {
4889 : 136063 : vis.visit (*this);
4890 : 136063 : }
4891 : :
4892 : : void
4893 : 98865 : ReferenceType::accept_vis (ASTVisitor &vis)
4894 : : {
4895 : 98865 : vis.visit (*this);
4896 : 98865 : }
4897 : :
4898 : : void
4899 : 13255 : ArrayType::accept_vis (ASTVisitor &vis)
4900 : : {
4901 : 13255 : vis.visit (*this);
4902 : 13255 : }
4903 : :
4904 : : void
4905 : 15664 : SliceType::accept_vis (ASTVisitor &vis)
4906 : : {
4907 : 15664 : vis.visit (*this);
4908 : 15664 : }
4909 : :
4910 : : void
4911 : 5159 : InferredType::accept_vis (ASTVisitor &vis)
4912 : : {
4913 : 5159 : vis.visit (*this);
4914 : 5159 : }
4915 : :
4916 : : void
4917 : 828 : BareFunctionType::accept_vis (ASTVisitor &vis)
4918 : : {
4919 : 828 : vis.visit (*this);
4920 : 828 : }
4921 : :
4922 : : void
4923 : 2 : MetaItemSeq::accept_vis (ASTVisitor &vis)
4924 : : {
4925 : 2 : vis.visit (*this);
4926 : 2 : }
4927 : :
4928 : : void
4929 : 0 : MetaItemPath::accept_vis (ASTVisitor &vis)
4930 : : {
4931 : 0 : vis.visit (*this);
4932 : 0 : }
4933 : :
4934 : : void
4935 : 0 : MetaListPaths::accept_vis (ASTVisitor &vis)
4936 : : {
4937 : 0 : vis.visit (*this);
4938 : 0 : }
4939 : :
4940 : : void
4941 : 5 : MetaNameValueStr::accept_vis (ASTVisitor &vis)
4942 : : {
4943 : 5 : vis.visit (*this);
4944 : 5 : }
4945 : :
4946 : : void
4947 : 0 : MetaListNameValueStr::accept_vis (ASTVisitor &vis)
4948 : : {
4949 : 0 : vis.visit (*this);
4950 : 0 : }
4951 : :
4952 : : void
4953 : 0 : AttrInputMetaItemContainer::accept_vis (ASTVisitor &vis)
4954 : : {
4955 : 0 : vis.visit (*this);
4956 : 0 : }
4957 : :
4958 : : void
4959 : 0 : MetaWord::accept_vis (ASTVisitor &vis)
4960 : : {
4961 : 0 : vis.visit (*this);
4962 : 0 : }
4963 : :
4964 : : void
4965 : 0 : FormatArgs::accept_vis (ASTVisitor &vis)
4966 : : {
4967 : 0 : vis.visit (*this);
4968 : 0 : }
4969 : :
4970 : : void
4971 : 168 : OffsetOf::accept_vis (ASTVisitor &vis)
4972 : : {
4973 : 168 : vis.visit (*this);
4974 : 168 : }
4975 : :
4976 : : std::string
4977 : 0 : FormatArgs::as_string () const
4978 : : {
4979 : : // FIXME(Arthur): Improve
4980 : 0 : return "FormatArgs";
4981 : : }
4982 : :
4983 : : std::string
4984 : 0 : OffsetOf::as_string () const
4985 : : {
4986 : 0 : return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")";
4987 : : }
4988 : :
4989 : : location_t
4990 : 2 : FormatArgs::get_locus () const
4991 : : {
4992 : 2 : return loc;
4993 : : }
4994 : :
4995 : : bool
4996 : 0 : FormatArgs::is_expr_without_block () const
4997 : : {
4998 : 0 : return false;
4999 : : }
5000 : :
5001 : : void
5002 : 0 : FormatArgs::mark_for_strip ()
5003 : : {
5004 : 0 : marked_for_strip = true;
5005 : 0 : }
5006 : :
5007 : : bool
5008 : 0 : FormatArgs::is_marked_for_strip () const
5009 : : {
5010 : 0 : return marked_for_strip;
5011 : : }
5012 : :
5013 : : std::vector<Attribute> &
5014 : 0 : FormatArgs::get_outer_attrs ()
5015 : : {
5016 : 0 : rust_unreachable ();
5017 : : }
5018 : :
5019 : : void
5020 : 0 : FormatArgs::set_outer_attrs (std::vector<Attribute>)
5021 : : {
5022 : 0 : rust_unreachable ();
5023 : : }
5024 : :
5025 : : Expr *
5026 : 0 : FormatArgs::clone_expr_impl () const
5027 : : {
5028 : 0 : std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
5029 : :
5030 : 0 : return new FormatArgs (*this);
5031 : : }
5032 : :
5033 : : std::vector<Attribute> &
5034 : 0 : OffsetOf::get_outer_attrs ()
5035 : : {
5036 : 0 : rust_unreachable ();
5037 : : }
5038 : :
5039 : : void
5040 : 0 : OffsetOf::set_outer_attrs (std::vector<Attribute>)
5041 : : {
5042 : 0 : rust_unreachable ();
5043 : : }
5044 : :
5045 : : Expr *
5046 : 96 : OffsetOf::clone_expr_impl () const
5047 : : {
5048 : 96 : return new OffsetOf (*this);
5049 : : }
5050 : :
5051 : : } // namespace AST
5052 : :
5053 : : std::ostream &
5054 : 0 : operator<< (std::ostream &os, Identifier const &i)
5055 : : {
5056 : 0 : return os << i.as_string ();
5057 : : }
5058 : :
5059 : : } // namespace Rust
|