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