]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/ast/rust-ast.h
libstdc++: fix bits/version.def typo
[thirdparty/gcc.git] / gcc / rust / ast / rust-ast.h
CommitLineData
6441eb6d 1// Copyright (C) 2020-2025 Free Software Foundation, Inc.
6b35ae12
JP
2
3// This file is part of GCC.
4
5// GCC is free software; you can redistribute it and/or modify it under
6// the terms of the GNU General Public License as published by the Free
7// Software Foundation; either version 3, or (at your option) any later
8// version.
9
10// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11// WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13// for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with GCC; see the file COPYING3. If not see
17// <http://www.gnu.org/licenses/>.
18
19#ifndef RUST_AST_BASE_H
20#define RUST_AST_BASE_H
21// Base for AST used in gccrs, basically required by all specific ast things
22
23#include "rust-system.h"
24#include "rust-hir-map.h"
25#include "rust-token.h"
26#include "rust-location.h"
55fb35c5 27#include "rust-diagnostics.h"
f1c7ce7e 28#include "rust-keyword-values.h"
6b35ae12
JP
29
30namespace Rust {
31// TODO: remove typedefs and make actual types for these
6b35ae12
JP
32typedef int TupleIndex;
33struct Session;
e88ce5cc 34struct MacroExpander;
6b35ae12 35
865efbdc 36class Identifier
fcb228d1
PEP
37{
38public:
1c3a8fbb 39 // Create dummy identifier
6050e071 40 Identifier () : ident (""), loc (UNDEF_LOCATION) {}
1c3a8fbb 41 // Create identifier with dummy location
e99e565e 42 Identifier (std::string ident, location_t loc = UNDEF_LOCATION)
6050e071 43 : ident (ident), loc (loc)
1c3a8fbb
RT
44 {}
45 // Create identifier from token
46 Identifier (const_TokenPtr token)
6050e071 47 : ident (token->get_str ()), loc (token->get_locus ())
fcb228d1
PEP
48 {}
49
5373b8e6
PEP
50 Identifier (const Identifier &) = default;
51 Identifier (Identifier &&) = default;
52 Identifier &operator= (const Identifier &) = default;
53 Identifier &operator= (Identifier &&) = default;
54
df1da364 55 location_t get_locus () const { return loc; }
865efbdc 56 const std::string &as_string () const { return ident; }
fcb228d1
PEP
57
58 bool empty () const { return ident.empty (); }
59
12b3858d
PEP
60 bool operator== (const Identifier &other) const
61 {
62 return ident == other.ident;
63 }
64
fcb228d1
PEP
65private:
66 std::string ident;
e99e565e 67 location_t loc;
fcb228d1
PEP
68};
69
70std::ostream &
71operator<< (std::ostream &os, Identifier const &i);
72
6b35ae12
JP
73namespace AST {
74// foward decl: ast visitor
75class ASTVisitor;
76using AttrVec = std::vector<Attribute>;
77
cd773704
MP
78class Visitable
79{
80public:
8b089cb5 81 virtual ~Visitable () = default;
cd773704
MP
82 virtual void accept_vis (ASTVisitor &vis) = 0;
83};
84
6b35ae12
JP
85// Delimiter types - used in macros and whatever.
86enum DelimType
87{
88 PARENS,
89 SQUARE,
90 CURLY
91};
92
93// forward decl for use in token tree method
94class Token;
95
96// A tree of tokens (or a single token) - abstract base class
cd773704 97class TokenTree : public Visitable
6b35ae12
JP
98{
99public:
100 virtual ~TokenTree () {}
101
102 // Unique pointer custom clone function
103 std::unique_ptr<TokenTree> clone_token_tree () const
104 {
105 return std::unique_ptr<TokenTree> (clone_token_tree_impl ());
106 }
107
108 virtual std::string as_string () const = 0;
109
fcb228d1
PEP
110 /* Converts token tree to a flat token stream. Tokens must be pointer to
111 * avoid mutual dependency with Token. */
24c86440 112 virtual std::vector<std::unique_ptr<Token>> to_token_stream () const = 0;
6b35ae12
JP
113
114protected:
115 // pure virtual clone implementation
116 virtual TokenTree *clone_token_tree_impl () const = 0;
117};
118
119// Abstract base class for a macro match
cd773704 120class MacroMatch : public Visitable
6b35ae12
JP
121{
122public:
123 enum MacroMatchType
124 {
125 Fragment,
126 Repetition,
127 Matcher,
128 Tok
129 };
130
131 virtual ~MacroMatch () {}
132
133 virtual std::string as_string () const = 0;
e99e565e 134 virtual location_t get_match_locus () const = 0;
6b35ae12
JP
135
136 // Unique pointer custom clone function
137 std::unique_ptr<MacroMatch> clone_macro_match () const
138 {
139 return std::unique_ptr<MacroMatch> (clone_macro_match_impl ());
140 }
141
6b35ae12
JP
142 virtual MacroMatchType get_macro_match_type () const = 0;
143
144protected:
145 // pure virtual clone implementation
146 virtual MacroMatch *clone_macro_match_impl () const = 0;
147};
148
149// A token is a kind of token tree (except delimiter tokens)
150class Token : public TokenTree, public MacroMatch
151{
152 // A token is a kind of token tree (except delimiter tokens)
153 // A token is a kind of MacroMatch (except $ and delimiter tokens)
154#if 0
155 // TODO: improve member variables - current ones are the same as lexer token
156 // Token kind.
157 TokenId token_id;
158 // Token location.
d991a3f1 159 location_t locus;
6b35ae12
JP
160 // Associated text (if any) of token.
161 std::string str;
162 // Token type hint (if any).
163 PrimitiveCoreType type_hint;
164#endif
165
166 const_TokenPtr tok_ref;
167
fcb228d1
PEP
168 /* new idea: wrapper around const_TokenPtr used for heterogeneuous storage
169 * in token trees. rather than convert back and forth when parsing macros,
170 * just wrap it. */
6b35ae12
JP
171
172public:
173 // Unique pointer custom clone function
174 std::unique_ptr<Token> clone_token () const
175 {
176 return std::unique_ptr<Token> (clone_token_impl ());
177 }
178
179#if 0
180 /* constructor from general text - avoid using if lexer const_TokenPtr is
181 * available */
d991a3f1 182 Token (TokenId token_id, location_t locus, std::string str,
6b35ae12
JP
183 PrimitiveCoreType type_hint)
184 : token_id (token_id), locus (locus), str (std::move (str)),
185 type_hint (type_hint)
186 {}
187#endif
188 // not doable with new implementation - will have to make a const_TokenPtr
189
190 // Constructor from lexer const_TokenPtr
191#if 0
192 /* TODO: find workaround for std::string being nullptr - probably have to
193 * introduce new method in lexer Token, or maybe make conversion method
194 * there */
195 Token (const_TokenPtr lexer_token_ptr)
196 : token_id (lexer_token_ptr->get_id ()),
197 locus (lexer_token_ptr->get_locus ()), str (""),
198 type_hint (lexer_token_ptr->get_type_hint ())
199 {
200 // FIXME: change to "should have str" later?
201 if (lexer_token_ptr->has_str ())
202 {
203 str = lexer_token_ptr->get_str ();
204
205 // DEBUG
206 rust_debug ("ast token created with str '%s'", str.c_str ());
207 }
208 else
209 {
210 // FIXME: is this returning correct thing?
211 str = lexer_token_ptr->get_token_description ();
212
213 // DEBUG
214 rust_debug ("ast token created with string '%s'", str.c_str ());
215 }
216
217 // DEBUG
218 if (lexer_token_ptr->should_have_str () && !lexer_token_ptr->has_str ())
219 {
220 rust_debug (
221 "BAD: for token '%s', should have string but does not!",
222 lexer_token_ptr->get_token_description ());
223 }
224 }
225#endif
226 Token (const_TokenPtr lexer_tok_ptr) : tok_ref (std::move (lexer_tok_ptr)) {}
227
228 bool is_string_lit () const
229 {
230 switch (get_id ())
231 {
232 case STRING_LITERAL:
233 case BYTE_STRING_LITERAL:
908a4f88 234 case RAW_STRING_LITERAL:
6b35ae12
JP
235 return true;
236 default:
237 return false;
238 }
239 }
240
241 std::string as_string () const override;
e99e565e
OA
242 location_t get_match_locus () const override
243 {
244 return tok_ref->get_locus ();
245 };
6b35ae12
JP
246
247 void accept_vis (ASTVisitor &vis) override;
248
249 // Return copy of itself but in token stream form.
24c86440 250 std::vector<std::unique_ptr<Token>> to_token_stream () const override;
6b35ae12
JP
251
252 TokenId get_id () const { return tok_ref->get_id (); }
253 const std::string &get_str () const { return tok_ref->get_str (); }
254
df1da364 255 location_t get_locus () const { return tok_ref->get_locus (); }
6b35ae12
JP
256
257 PrimitiveCoreType get_type_hint () const { return tok_ref->get_type_hint (); }
258
259 // Get a new token pointer copy.
260 const_TokenPtr get_tok_ptr () const { return tok_ref; }
261
262 MacroMatchType get_macro_match_type () const override
263 {
264 return MacroMatchType::Tok;
265 }
266
267protected:
268 // No virtual for now as not polymorphic but can be in future
269 /*virtual*/ Token *clone_token_impl () const { return new Token (*this); }
270
fcb228d1
PEP
271 /* Use covariance to implement clone function as returning this object
272 * rather than base */
6b35ae12
JP
273 Token *clone_token_tree_impl () const final override
274 {
275 return clone_token_impl ();
276 }
277
fcb228d1
PEP
278 /* Use covariance to implement clone function as returning this object
279 * rather than base */
6b35ae12
JP
280 Token *clone_macro_match_impl () const final override
281 {
282 return clone_token_impl ();
283 }
284};
285
286// A literal - value with a type. Used in LiteralExpr and LiteralPattern.
287struct Literal
288{
289public:
290 enum LitType
291 {
292 CHAR,
293 STRING,
294 BYTE,
295 BYTE_STRING,
908a4f88 296 RAW_STRING,
6b35ae12
JP
297 INT,
298 FLOAT,
299 BOOL,
300 ERROR
301 };
302
303private:
fcb228d1
PEP
304 /* TODO: maybe make subclasses of each type of literal with their typed
305 * values (or generics) */
6b35ae12
JP
306 std::string value_as_string;
307 LitType type;
308 PrimitiveCoreType type_hint;
309
310public:
311 std::string as_string () const { return value_as_string; }
312
313 LitType get_lit_type () const { return type; }
314
315 PrimitiveCoreType get_type_hint () const { return type_hint; }
316
317 Literal (std::string value_as_string, LitType type,
318 PrimitiveCoreType type_hint)
319 : value_as_string (std::move (value_as_string)), type (type),
320 type_hint (type_hint)
321 {}
322
323 static Literal create_error ()
324 {
325 return Literal ("", ERROR, PrimitiveCoreType::CORETYPE_UNKNOWN);
326 }
327
328 // Returns whether literal is in an invalid state.
329 bool is_error () const { return type == ERROR; }
330};
331
fcb228d1
PEP
332/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
333 * to be defined */
6b35ae12
JP
334class AttrInputLiteral;
335
336/* TODO: move applicable stuff into here or just don't include it because
337 * nothing uses it A segment of a path (maybe) */
338class PathSegment
339{
340public:
341 virtual ~PathSegment () {}
342
343 virtual std::string as_string () const = 0;
344
345 // TODO: add visitor here?
346};
347
348// A segment of a simple path without generic or type arguments
349class SimplePathSegment : public PathSegment
350{
351 std::string segment_name;
d991a3f1 352 location_t locus;
6b35ae12
JP
353 NodeId node_id;
354
355 // only allow identifiers, "super", "self", "crate", or "$crate"
356public:
357 // TODO: put checks in constructor to enforce this rule?
d991a3f1 358 SimplePathSegment (std::string segment_name, location_t locus)
6b35ae12 359 : segment_name (std::move (segment_name)), locus (locus),
fd788dd5 360 node_id (Analysis::Mappings::get ().get_next_node_id ())
6b35ae12
JP
361 {}
362
363 /* Returns whether simple path segment is in an invalid state (currently, if
364 * empty). */
365 bool is_error () const { return segment_name.empty (); }
366
367 // Creates an error SimplePathSegment
368 static SimplePathSegment create_error ()
369 {
1678cdd3 370 return SimplePathSegment (std::string (""), UNDEF_LOCATION);
6b35ae12
JP
371 }
372
373 std::string as_string () const override;
374
df1da364 375 location_t get_locus () const { return locus; }
6b35ae12
JP
376 NodeId get_node_id () const { return node_id; }
377 const std::string &get_segment_name () const { return segment_name; }
378 bool is_super_path_seg () const
379 {
f1c7ce7e 380 return as_string ().compare (Values::Keywords::SUPER) == 0;
6b35ae12
JP
381 }
382 bool is_crate_path_seg () const
383 {
f1c7ce7e
PEP
384 return as_string ().compare (Values::Keywords::CRATE) == 0;
385 }
386 bool is_lower_self_seg () const
387 {
388 return as_string ().compare (Values::Keywords::SELF) == 0;
389 }
390 bool is_big_self () const
391 {
392 return as_string ().compare (Values::Keywords::SELF_ALIAS) == 0;
6b35ae12 393 }
6b35ae12
JP
394};
395
396// A simple path without generic or type arguments
865efbdc 397class SimplePath
6b35ae12 398{
ac013291 399 bool opening_scope_resolution;
6b35ae12 400 std::vector<SimplePathSegment> segments;
d991a3f1 401 location_t locus;
6b35ae12
JP
402 NodeId node_id;
403
404public:
405 // Constructor
406 SimplePath (std::vector<SimplePathSegment> path_segments,
407 bool has_opening_scope_resolution = false,
d991a3f1 408 location_t locus = UNDEF_LOCATION)
ac013291 409 : opening_scope_resolution (has_opening_scope_resolution),
6b35ae12 410 segments (std::move (path_segments)), locus (locus),
fd788dd5 411 node_id (Analysis::Mappings::get ().get_next_node_id ())
6b35ae12
JP
412 {}
413
987a411d
PEP
414 SimplePath (Identifier ident)
415 : opening_scope_resolution (false),
416 segments ({SimplePathSegment (ident.as_string (), ident.get_locus ())}),
417 locus (ident.get_locus ()),
fd788dd5 418 node_id (Analysis::Mappings::get ().get_next_node_id ())
987a411d
PEP
419 {}
420
6b35ae12
JP
421 // Creates an empty SimplePath.
422 static SimplePath create_empty ()
423 {
424 return SimplePath (std::vector<SimplePathSegment> ());
425 }
426
427 // Returns whether the SimplePath is empty, i.e. has path segments.
428 bool is_empty () const { return segments.empty (); }
429
865efbdc 430 const std::string as_string () const;
6b35ae12 431
ac013291 432 bool has_opening_scope_resolution () const
e53b3688 433 {
ac013291 434 return opening_scope_resolution;
e53b3688
PEP
435 }
436
865efbdc
PEP
437 location_t get_locus () const { return locus; }
438 NodeId get_node_id () const { return node_id; }
6b35ae12
JP
439
440 // does this need visitor if not polymorphic? probably not
441
442 // path-to-string comparison operator
443 bool operator== (const std::string &rhs) const
444 {
ac013291 445 return !opening_scope_resolution && segments.size () == 1
6b35ae12
JP
446 && segments[0].as_string () == rhs;
447 }
448
449 /* Creates a single-segment SimplePath from a string. This will not check to
450 * ensure that this is a valid identifier in path, so be careful. Also, this
451 * will have no location data.
452 * TODO have checks? */
d991a3f1 453 static SimplePath from_str (std::string str, location_t locus)
6b35ae12
JP
454 {
455 std::vector<AST::SimplePathSegment> single_segments
456 = {AST::SimplePathSegment (std::move (str), locus)};
e61de665 457 return SimplePath (std::move (single_segments), false, locus);
6b35ae12
JP
458 }
459
460 const std::vector<SimplePathSegment> &get_segments () const
461 {
462 return segments;
463 }
464
465 std::vector<SimplePathSegment> &get_segments () { return segments; }
7e7cffb7
PH
466
467 const SimplePathSegment &get_final_segment () const
468 {
469 return segments.back ();
470 }
6b35ae12
JP
471};
472
473// path-to-string inverse comparison operator
474inline bool
475operator!= (const SimplePath &lhs, const std::string &rhs)
476{
477 return !(lhs == rhs);
478}
479
480// forward decl for Attribute
481class AttrInput;
482
ceed844b
PEP
483// Visibility of item - if the item has it, then it is some form of public
484struct Visibility
485{
486public:
487 enum VisType
488 {
489 PRIV,
490 PUB,
491 PUB_CRATE,
492 PUB_SELF,
493 PUB_SUPER,
494 PUB_IN_PATH
495 };
496
497private:
498 VisType vis_type;
499 // Only assigned if vis_type is IN_PATH
500 SimplePath in_path;
501 location_t locus;
502
503 // should this store location info?
504
505public:
506 // Creates a Visibility - TODO make constructor protected or private?
507 Visibility (VisType vis_type, SimplePath in_path, location_t locus)
508 : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
509 {}
510
511 VisType get_vis_type () const { return vis_type; }
512
513 // Returns whether visibility is in an error state.
514 bool is_error () const
515 {
516 return vis_type == PUB_IN_PATH && in_path.is_empty ();
517 }
518
519 // Returns whether a visibility has a path
520 bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; }
521
522 // Returns whether visibility is public or not.
523 bool is_public () const { return vis_type != PRIV && !is_error (); }
524
525 location_t get_locus () const { return locus; }
526
527 // empty?
528 // Creates an error visibility.
529 static Visibility create_error ()
530 {
531 return Visibility (PUB_IN_PATH, SimplePath::create_empty (),
532 UNDEF_LOCATION);
533 }
534
535 // Unique pointer custom clone function
536 /*std::unique_ptr<Visibility> clone_visibility() const {
537 return std::unique_ptr<Visibility>(clone_visibility_impl());
538 }*/
539
540 /* TODO: think of a way to only allow valid Visibility states - polymorphism
541 * is one idea but may be too resource-intensive. */
542
543 // Creates a public visibility with no further features/arguments.
544 // empty?
545 static Visibility create_public (location_t pub_vis_location)
546 {
547 return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
548 }
549
550 // Creates a public visibility with crate-relative paths
551 static Visibility create_crate (location_t crate_tok_location,
552 location_t crate_vis_location)
553 {
554 return Visibility (PUB_CRATE,
f1c7ce7e
PEP
555 SimplePath::from_str (Values::Keywords::CRATE,
556 crate_tok_location),
ceed844b
PEP
557 crate_vis_location);
558 }
559
560 // Creates a public visibility with self-relative paths
561 static Visibility create_self (location_t self_tok_location,
562 location_t self_vis_location)
563 {
564 return Visibility (PUB_SELF,
f1c7ce7e
PEP
565 SimplePath::from_str (Values::Keywords::SELF,
566 self_tok_location),
ceed844b
PEP
567 self_vis_location);
568 }
569
570 // Creates a public visibility with parent module-relative paths
571 static Visibility create_super (location_t super_tok_location,
572 location_t super_vis_location)
573 {
574 return Visibility (PUB_SUPER,
f1c7ce7e
PEP
575 SimplePath::from_str (Values::Keywords::SUPER,
576 super_tok_location),
ceed844b
PEP
577 super_vis_location);
578 }
579
580 // Creates a private visibility
581 static Visibility create_private ()
582 {
583 return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION);
584 }
585
586 // Creates a public visibility with a given path or whatever.
587 static Visibility create_in_path (SimplePath in_path,
588 location_t in_path_vis_location)
589 {
590 return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
591 }
592
593 std::string as_string () const;
594 const SimplePath &get_path () const { return in_path; }
595 SimplePath &get_path () { return in_path; }
596
597protected:
598 // Clone function implementation - not currently virtual but may be if
599 // polymorphism used
600 /*virtual*/ Visibility *clone_visibility_impl () const
601 {
602 return new Visibility (*this);
603 }
604};
605
6b35ae12
JP
606// aka Attr
607// Attribute AST representation
608struct Attribute
609{
610private:
611 SimplePath path;
612
613 // bool has_attr_input;
614 std::unique_ptr<AttrInput> attr_input;
615
d991a3f1 616 location_t locus;
6b35ae12 617
9a7a79eb
PEP
618 bool inner_attribute;
619
6b35ae12
JP
620 // TODO: maybe a variable storing whether attr input is parsed or not
621
622public:
623 // Returns whether Attribute has AttrInput
624 bool has_attr_input () const { return attr_input != nullptr; }
625
626 // Constructor has pointer AttrInput for polymorphism reasons
627 Attribute (SimplePath path, std::unique_ptr<AttrInput> input,
d991a3f1 628 location_t locus = UNDEF_LOCATION, bool inner_attribute = false)
9a7a79eb
PEP
629 : path (std::move (path)), attr_input (std::move (input)), locus (locus),
630 inner_attribute (inner_attribute)
6b35ae12
JP
631 {}
632
ad1f5108
PEP
633 bool is_derive () const;
634
90ee6314 635 std::vector<std::reference_wrapper<AST::SimplePath>> get_traits_to_derive ();
de8bc8f9 636
6b35ae12
JP
637 // default destructor
638 ~Attribute () = default;
639
640 // no point in being defined inline as requires virtual call anyway
641 Attribute (const Attribute &other);
642
643 // no point in being defined inline as requires virtual call anyway
644 Attribute &operator= (const Attribute &other);
645
646 // default move semantics
647 Attribute (Attribute &&other) = default;
648 Attribute &operator= (Attribute &&other) = default;
649
650 // Unique pointer custom clone function
651 std::unique_ptr<Attribute> clone_attribute () const
652 {
653 return std::unique_ptr<Attribute> (clone_attribute_impl ());
654 }
655
656 // Creates an empty attribute (which is invalid)
657 static Attribute create_empty ()
658 {
659 return Attribute (SimplePath::create_empty (), nullptr);
660 }
661
662 // Returns whether the attribute is considered an "empty" attribute.
663 bool is_empty () const { return attr_input == nullptr && path.is_empty (); }
664
a75a697f
MK
665 // Returns whether the attribute has no input
666 bool empty_input () const { return !attr_input; }
667
df1da364 668 location_t get_locus () const { return locus; }
6b35ae12
JP
669
670 AttrInput &get_attr_input () const { return *attr_input; }
671
672 /* e.g.:
673 #![crate_type = "lib"]
674 #[test]
675 #[cfg(target_os = "linux")]
676 #[allow(non_camel_case_types)]
677 #![allow(unused_variables)]
678 */
679
680 // Full built-in attribute list:
681 /* cfg
682 * cfg_attr
683 * test
684 * ignore
685 * should_panic
686 * derive
687 * macro_export
688 * macro_use
689 * proc_macro
690 * proc_macro_derive
691 * proc_macro_attribute
692 * allow
693 * warn
694 * deny
695 * forbid
696 * deprecated
697 * must_use
698 * link
699 * link_name
700 * no_link
701 * repr
702 * crate_type
703 * no_main
704 * export_name
705 * link_section
706 * no_mangle
707 * used
708 * crate_name
709 * inline
710 * cold
711 * no_builtins
712 * target_feature
713 * doc
714 * no_std
715 * no_implicit_prelude
716 * path
717 * recursion_limit
718 * type_length_limit
719 * panic_handler
720 * global_allocator
721 * windows_subsystem
722 * feature */
723
724 std::string as_string () const;
725
9a7a79eb
PEP
726 bool is_inner_attribute () const { return inner_attribute; }
727
6b35ae12
JP
728 // no visitor pattern as not currently polymorphic
729
730 const SimplePath &get_path () const { return path; }
731 SimplePath &get_path () { return path; }
732
733 // Call to parse attribute body to meta item syntax.
734 void parse_attr_to_meta_item ();
735
fcb228d1
PEP
736 /* Determines whether cfg predicate is true and item with attribute should
737 * not be stripped. Attribute body must already be parsed to meta item. */
6b35ae12
JP
738 bool check_cfg_predicate (const Session &session) const;
739
740 // Returns whether body has been parsed to meta item form or not.
741 bool is_parsed_to_meta_item () const;
742
743 /* Returns any attributes generated from cfg_attr attributes. Attribute body
744 * must already be parsed to meta item. */
745 std::vector<Attribute> separate_cfg_attrs () const;
746
747protected:
fcb228d1
PEP
748 // not virtual as currently no subclasses of Attribute, but could be in
749 // future
6b35ae12
JP
750 /*virtual*/ Attribute *clone_attribute_impl () const
751 {
752 return new Attribute (*this);
753 }
754};
755
756// Attribute body - abstract base class
cd773704 757class AttrInput : public Visitable
6b35ae12
JP
758{
759public:
760 enum AttrInputType
761 {
762 LITERAL,
842a8307 763 MACRO,
6b35ae12
JP
764 META_ITEM,
765 TOKEN_TREE,
766 };
767
768 virtual ~AttrInput () {}
769
770 // Unique pointer custom clone function
771 std::unique_ptr<AttrInput> clone_attr_input () const
772 {
773 return std::unique_ptr<AttrInput> (clone_attr_input_impl ());
774 }
775
776 virtual std::string as_string () const = 0;
777
6b35ae12
JP
778 virtual bool check_cfg_predicate (const Session &session) const = 0;
779
780 // Parse attribute input to meta item, if possible
781 virtual AttrInput *parse_to_meta_item () const { return nullptr; }
782
783 virtual std::vector<Attribute> separate_cfg_attrs () const { return {}; }
784
785 // Returns whether attr input has been parsed to meta item syntax.
786 virtual bool is_meta_item () const = 0;
787
788 virtual AttrInputType get_attr_input_type () const = 0;
789
790protected:
791 // pure virtual clone implementation
792 virtual AttrInput *clone_attr_input_impl () const = 0;
793};
794
795// Forward decl - defined in rust-macro.h
796class MetaNameValueStr;
797
798// abstract base meta item inner class
cd773704 799class MetaItemInner : public Visitable
6b35ae12
JP
800{
801protected:
802 // pure virtual as MetaItemInner
803 virtual MetaItemInner *clone_meta_item_inner_impl () const = 0;
804
805public:
5920e4b7
PEP
806 enum class Kind
807 {
808 LitExpr,
809 MetaItem,
810 };
811
6b35ae12
JP
812 // Unique pointer custom clone function
813 std::unique_ptr<MetaItemInner> clone_meta_item_inner () const
814 {
815 return std::unique_ptr<MetaItemInner> (clone_meta_item_inner_impl ());
816 }
817
5920e4b7
PEP
818 virtual Kind get_kind () = 0;
819
6b35ae12
JP
820 virtual ~MetaItemInner ();
821
df1da364 822 virtual location_t get_locus () const = 0;
8e2abbef 823
6b35ae12
JP
824 virtual std::string as_string () const = 0;
825
6b35ae12
JP
826 /* HACK: used to simplify parsing - creates a copy of that type, or returns
827 * null */
828 virtual std::unique_ptr<MetaNameValueStr> to_meta_name_value_str () const;
829
830 // HACK: used to simplify parsing - same thing
831 virtual SimplePath to_path_item () const
832 {
833 return SimplePath::create_empty ();
834 }
835
836 virtual Attribute to_attribute () const { return Attribute::create_empty (); }
837
838 virtual bool check_cfg_predicate (const Session &session) const = 0;
839
840 virtual bool is_key_value_pair () const { return false; }
841};
842
843// Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
844class AttrInputMetaItemContainer : public AttrInput
845{
24c86440 846 std::vector<std::unique_ptr<MetaItemInner>> items;
6b35ae12
JP
847
848public:
24c86440 849 AttrInputMetaItemContainer (std::vector<std::unique_ptr<MetaItemInner>> items)
6b35ae12
JP
850 : items (std::move (items))
851 {}
852
853 // copy constructor with vector clone
854 AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other)
855 {
856 items.reserve (other.items.size ());
857 for (const auto &e : other.items)
858 items.push_back (e->clone_meta_item_inner ());
859 }
860
861 // copy assignment operator with vector clone
862 AttrInputMetaItemContainer &
863 operator= (const AttrInputMetaItemContainer &other)
864 {
865 AttrInput::operator= (other);
866
867 items.reserve (other.items.size ());
868 for (const auto &e : other.items)
869 items.push_back (e->clone_meta_item_inner ());
870
871 return *this;
872 }
873
874 // default move constructors
875 AttrInputMetaItemContainer (AttrInputMetaItemContainer &&other) = default;
876 AttrInputMetaItemContainer &operator= (AttrInputMetaItemContainer &&other)
877 = default;
878
879 std::string as_string () const override;
880
881 void accept_vis (ASTVisitor &vis) override;
882
883 bool check_cfg_predicate (const Session &session) const override;
884
885 AttrInputType get_attr_input_type () const final override
886 {
887 return AttrInput::AttrInputType::META_ITEM;
888 }
889
890 // Clones this object.
891 std::unique_ptr<AttrInputMetaItemContainer>
892 clone_attr_input_meta_item_container () const
893 {
894 return std::unique_ptr<AttrInputMetaItemContainer> (
895 clone_attr_input_meta_item_container_impl ());
896 }
897
898 std::vector<Attribute> separate_cfg_attrs () const override;
899
900 bool is_meta_item () const override { return true; }
901
902 // TODO: this mutable getter seems dodgy
24c86440
AC
903 std::vector<std::unique_ptr<MetaItemInner>> &get_items () { return items; }
904 const std::vector<std::unique_ptr<MetaItemInner>> &get_items () const
6b35ae12
JP
905 {
906 return items;
907 }
908
909protected:
910 // Use covariance to implement clone function as returning this type
911 AttrInputMetaItemContainer *clone_attr_input_impl () const final override
912 {
913 return clone_attr_input_meta_item_container_impl ();
914 }
915
916 AttrInputMetaItemContainer *clone_attr_input_meta_item_container_impl () const
917 {
918 return new AttrInputMetaItemContainer (*this);
919 }
920};
921
922// A token tree with delimiters
923class DelimTokenTree : public TokenTree, public AttrInput
924{
925 DelimType delim_type;
24c86440 926 std::vector<std::unique_ptr<TokenTree>> token_trees;
d991a3f1 927 location_t locus;
6b35ae12
JP
928
929protected:
930 DelimTokenTree *clone_delim_tok_tree_impl () const
931 {
932 return new DelimTokenTree (*this);
933 }
934
935 /* Use covariance to implement clone function as returning a DelimTokenTree
936 * object */
937 DelimTokenTree *clone_attr_input_impl () const final override
938 {
939 return clone_delim_tok_tree_impl ();
940 }
941
942 /* Use covariance to implement clone function as returning a DelimTokenTree
943 * object */
944 DelimTokenTree *clone_token_tree_impl () const final override
945 {
946 return clone_delim_tok_tree_impl ();
947 }
948
949public:
950 DelimTokenTree (DelimType delim_type,
24c86440
AC
951 std::vector<std::unique_ptr<TokenTree>> token_trees
952 = std::vector<std::unique_ptr<TokenTree>> (),
d991a3f1 953 location_t locus = UNDEF_LOCATION)
6b35ae12
JP
954 : delim_type (delim_type), token_trees (std::move (token_trees)),
955 locus (locus)
956 {}
957
958 // Copy constructor with vector clone
959 DelimTokenTree (DelimTokenTree const &other)
960 : delim_type (other.delim_type), locus (other.locus)
961 {
38216691 962 token_trees.clear ();
6b35ae12
JP
963 token_trees.reserve (other.token_trees.size ());
964 for (const auto &e : other.token_trees)
965 token_trees.push_back (e->clone_token_tree ());
966 }
967
968 // overloaded assignment operator with vector clone
969 DelimTokenTree &operator= (DelimTokenTree const &other)
970 {
971 delim_type = other.delim_type;
972 locus = other.locus;
973
38216691 974 token_trees.clear ();
6b35ae12
JP
975 token_trees.reserve (other.token_trees.size ());
976 for (const auto &e : other.token_trees)
977 token_trees.push_back (e->clone_token_tree ());
978
979 return *this;
980 }
981
982 // move constructors
983 DelimTokenTree (DelimTokenTree &&other) = default;
984 DelimTokenTree &operator= (DelimTokenTree &&other) = default;
985
986 static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
987
988 std::string as_string () const override;
989
990 void accept_vis (ASTVisitor &vis) override;
991
992 bool check_cfg_predicate (const Session &) const override
993 {
994 // this should never be called - should be converted first
995 rust_assert (false);
996 return false;
997 }
998
999 AttrInputMetaItemContainer *parse_to_meta_item () const override;
1000
24c86440 1001 std::vector<std::unique_ptr<Token>> to_token_stream () const override;
6b35ae12
JP
1002
1003 std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const
1004 {
1005 return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ());
1006 }
1007
1008 bool is_meta_item () const override { return false; }
1009
1010 AttrInputType get_attr_input_type () const final override
1011 {
1012 return AttrInput::AttrInputType::TOKEN_TREE;
1013 }
1014
24c86440 1015 std::vector<std::unique_ptr<TokenTree>> &get_token_trees ()
6b35ae12
JP
1016 {
1017 return token_trees;
1018 }
1019
2d2fa103
PEP
1020 const std::vector<std::unique_ptr<TokenTree>> &get_token_trees () const
1021 {
1022 return token_trees;
1023 }
1024
6b35ae12 1025 DelimType get_delim_type () const { return delim_type; }
4aa6cae2 1026 location_t get_locus () const { return locus; }
6b35ae12
JP
1027};
1028
fcb228d1
PEP
1029/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr
1030 * to be defined */
6b35ae12
JP
1031class AttrInputLiteral;
1032
1033// abstract base meta item class
1034class MetaItem : public MetaItemInner
1035{
5920e4b7
PEP
1036public:
1037 enum class ItemKind
1038 {
1039 Path,
1040 Word,
1041 NameValueStr,
1042 PathLit,
1043 Seq,
1044 ListPaths,
1045 ListNameValueStr,
1046 };
1047
1048 MetaItemInner::Kind get_kind () override
1049 {
1050 return MetaItemInner::Kind::MetaItem;
1051 }
1052
1053 virtual ItemKind get_item_kind () const = 0;
6b35ae12
JP
1054};
1055
1056// Forward decl - defined in rust-expr.h
1057class MetaItemLitExpr;
1058
1059// Forward decl - defined in rust-expr.h
1060class MetaItemPathLit;
1061
1062// Forward decl - defined in rust-macro.h
1063class MetaItemPath;
1064
1065// Forward decl - defined in rust-macro.h
1066class MetaItemSeq;
1067
1068// Forward decl - defined in rust-macro.h
1069class MetaWord;
1070
1071// Forward decl - defined in rust-macro.h
1072class MetaListPaths;
1073
1074// Forward decl - defined in rust-macro.h
1075class MetaListNameValueStr;
1076
fcb228d1
PEP
1077/* Base statement abstract class. Note that most "statements" are not allowed
1078 * in top-level module scope - only a subclass of statements called "items"
1079 * are. */
9c50565e 1080class Stmt : public Visitable
6b35ae12
JP
1081{
1082public:
9035128b
AC
1083 enum class Kind
1084 {
1085 Empty,
1086 Item,
1087 Let,
1088 Expr,
1089 MacroInvocation,
1090 };
1091
6b35ae12
JP
1092 // Unique pointer custom clone function
1093 std::unique_ptr<Stmt> clone_stmt () const
1094 {
1095 return std::unique_ptr<Stmt> (clone_stmt_impl ());
1096 }
1097
1098 virtual ~Stmt () {}
1099
1100 virtual std::string as_string () const = 0;
1101
df1da364 1102 virtual location_t get_locus () const = 0;
6b35ae12
JP
1103
1104 virtual void mark_for_strip () = 0;
1105 virtual bool is_marked_for_strip () const = 0;
1106 NodeId get_node_id () const { return node_id; }
1107
9035128b 1108 virtual Kind get_stmt_kind () = 0;
6b35ae12 1109
9035128b
AC
1110 // TODO: Can we remove these two?
1111 virtual bool is_item () const = 0;
35a4c25a
OA
1112 virtual bool is_expr () const { return false; }
1113
8bc4ce7c
MJ
1114 virtual void add_semicolon () {}
1115
6b35ae12 1116protected:
fd788dd5 1117 Stmt () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
6b35ae12
JP
1118
1119 // Clone function implementation as pure virtual method
1120 virtual Stmt *clone_stmt_impl () const = 0;
1121
1122 NodeId node_id;
1123};
1124
1125// Rust "item" AST node (declaration of top-level/module-level allowed stuff)
1126class Item : public Stmt
1127{
1128public:
9c50565e
AC
1129 enum class Kind
1130 {
1131 MacroRulesDefinition,
1132 MacroInvocation,
1133 Module,
1134 ExternCrate,
1135 UseDeclaration,
1136 Function,
1137 TypeAlias,
1138 Struct,
1139 EnumItem,
1140 Enum,
1141 Union,
1142 ConstantItem,
1143 StaticItem,
1144 Trait,
1145 Impl,
1146 ExternBlock,
1147 };
1148
1149 virtual Kind get_item_kind () const = 0;
1150
6b35ae12
JP
1151 // Unique pointer custom clone function
1152 std::unique_ptr<Item> clone_item () const
1153 {
1154 return std::unique_ptr<Item> (clone_item_impl ());
1155 }
1156
1157 /* Adds crate names to the vector passed by reference, if it can
1158 * (polymorphism). TODO: remove, unused. */
1159 virtual void
1160 add_crate_name (std::vector<std::string> &names ATTRIBUTE_UNUSED) const
1161 {}
1162
9035128b
AC
1163 Stmt::Kind get_stmt_kind () final { return Stmt::Kind::Item; }
1164
6b35ae12
JP
1165 // FIXME: ARTHUR: Is it okay to have removed that final? Is it *required*
1166 // behavior that we have items that can also be expressions?
1167 bool is_item () const override { return true; }
1168
f5d02c4f
AC
1169 virtual std::vector<Attribute> &get_outer_attrs () = 0;
1170 virtual const std::vector<Attribute> &get_outer_attrs () const = 0;
1171
1172 virtual bool has_outer_attrs () const { return !get_outer_attrs ().empty (); }
1173
6b35ae12
JP
1174protected:
1175 // Clone function implementation as pure virtual method
1176 virtual Item *clone_item_impl () const = 0;
1177
1178 /* Save having to specify two clone methods in derived classes by making
1179 * statement clone return item clone. Hopefully won't affect performance too
1180 * much. */
1181 Item *clone_stmt_impl () const final override { return clone_item_impl (); }
1182};
1183
513b0154
PEP
1184// Item that supports visibility - abstract base class
1185class VisItem : public Item
1186{
1187 Visibility visibility;
1188 std::vector<Attribute> outer_attrs;
1189
1190protected:
1191 // Visibility constructor
1192 VisItem (Visibility visibility,
1193 std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
1194 : visibility (std::move (visibility)), outer_attrs (std::move (outer_attrs))
1195 {}
1196
1197 // Visibility copy constructor
1198 VisItem (VisItem const &other)
1199 : visibility (other.visibility), outer_attrs (other.outer_attrs)
1200 {}
1201
1202 // Overload assignment operator to clone
1203 VisItem &operator= (VisItem const &other)
1204 {
1205 visibility = other.visibility;
1206 outer_attrs = other.outer_attrs;
1207
1208 return *this;
1209 }
1210
1211 // move constructors
1212 VisItem (VisItem &&other) = default;
1213 VisItem &operator= (VisItem &&other) = default;
1214
1215public:
1216 /* Does the item have some kind of public visibility (non-default
1217 * visibility)? */
1218 bool has_visibility () const { return visibility.is_public (); }
1219
1220 std::string as_string () const override;
1221
1222 // TODO: this mutable getter seems really dodgy. Think up better way.
1223 Visibility &get_visibility () { return visibility; }
1224 const Visibility &get_visibility () const { return visibility; }
1225
1226 std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
1227 const std::vector<Attribute> &get_outer_attrs () const override
1228 {
1229 return outer_attrs;
1230 }
9c50565e
AC
1231
1232 virtual Item::Kind get_item_kind () const override = 0;
513b0154 1233};
9c50565e 1234
6b35ae12
JP
1235// forward decl of ExprWithoutBlock
1236class ExprWithoutBlock;
1237
1238// Base expression AST node - abstract
9c50565e 1239class Expr : public Visitable
6b35ae12
JP
1240{
1241public:
9c50565e
AC
1242 enum class Kind
1243 {
1244 PathInExpression,
1245 QualifiedPathInExpression,
1246 Literal,
1247 Operator,
1248 Grouped,
1249 Array,
1250 ArrayIndex,
1251 Tuple,
1252 TupleIndex,
1253 Struct,
1254 Call,
1255 MethodCall,
1256 FieldAccess,
1257 Closure,
1258 Block,
1259 Continue,
1260 Break,
1261 Range,
1262 Box,
1263 Return,
1264 UnsafeBlock,
1265 Loop,
1266 If,
1267 IfLet,
1268 Match,
1269 Await,
1270 AsyncBlock,
1271 InlineAsm,
69782437 1272 LlvmInlineAsm,
9c50565e
AC
1273 Identifier,
1274 FormatArgs,
1275 MacroInvocation,
c1d6807f
AC
1276 Borrow,
1277 Dereference,
1278 ErrorPropagation,
1279 Negation,
1280 ArithmeticOrLogical,
1281 Comparison,
1282 LazyBoolean,
1283 TypeCast,
1284 Assignment,
1285 CompoundAssignment,
9c50565e
AC
1286 };
1287
1288 virtual Kind get_expr_kind () const = 0;
1289
6b35ae12
JP
1290 // Unique pointer custom clone function
1291 std::unique_ptr<Expr> clone_expr () const
1292 {
1293 return std::unique_ptr<Expr> (clone_expr_impl ());
1294 }
1295
1296 /* TODO: public methods that could be useful:
1297 * - get_type() - returns type of expression. set_type() may also be useful
1298 * for some?
1299 * - evaluate() - evaluates expression if constant? can_evaluate()? */
1300
6b35ae12
JP
1301 virtual std::string as_string () const = 0;
1302
1303 virtual ~Expr () {}
1304
df1da364 1305 virtual location_t get_locus () const = 0;
6b35ae12 1306
e88ce5cc 1307 virtual bool is_literal () const { return false; }
1308
6b35ae12
JP
1309 // HACK: strictly not needed, but faster than full downcast clone
1310 virtual bool is_expr_without_block () const = 0;
1311
6b35ae12
JP
1312 virtual void mark_for_strip () = 0;
1313 virtual bool is_marked_for_strip () const = 0;
1314
1315 virtual NodeId get_node_id () const { return node_id; }
1316
1317 virtual void set_node_id (NodeId id) { node_id = id; }
1318
36bca0cc
PEP
1319 virtual std::vector<Attribute> &get_outer_attrs () = 0;
1320
48408712
MJ
1321 // TODO: think of less hacky way to implement this kind of thing
1322 // Sets outer attributes.
1323 virtual void set_outer_attrs (std::vector<Attribute>) = 0;
1324
6b35ae12
JP
1325protected:
1326 // Constructor
fd788dd5 1327 Expr () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
6b35ae12
JP
1328
1329 // Clone function implementation as pure virtual method
1330 virtual Expr *clone_expr_impl () const = 0;
1331
6b35ae12
JP
1332 NodeId node_id;
1333};
1334
1335// AST node for an expression without an accompanying block - abstract
1336class ExprWithoutBlock : public Expr
1337{
1338protected:
1339 // pure virtual clone implementation
1340 virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0;
1341
fcb228d1
PEP
1342 /* Save having to specify two clone methods in derived classes by making
1343 * expr clone return exprwithoutblock clone. Hopefully won't affect
1344 * performance too much. */
6b35ae12
JP
1345 ExprWithoutBlock *clone_expr_impl () const final override
1346 {
1347 return clone_expr_without_block_impl ();
1348 }
1349
1350 bool is_expr_without_block () const final override { return true; };
1351
1352public:
1353 // Unique pointer custom clone function
1354 std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
1355 {
1356 return std::unique_ptr<ExprWithoutBlock> (clone_expr_without_block_impl ());
1357 }
6b35ae12
JP
1358};
1359
1360/* HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
1361 * Pratt parser */
fcb228d1
PEP
1362/* Alternatively, identifiers could just be represented as single-segment
1363 * paths
6b35ae12
JP
1364 */
1365class IdentifierExpr : public ExprWithoutBlock
1366{
1367 std::vector<Attribute> outer_attrs;
1368 Identifier ident;
d991a3f1 1369 location_t locus;
6b35ae12
JP
1370
1371public:
1372 IdentifierExpr (Identifier ident, std::vector<Attribute> outer_attrs,
d991a3f1 1373 location_t locus)
6b35ae12
JP
1374 : outer_attrs (std::move (outer_attrs)), ident (std::move (ident)),
1375 locus (locus)
1376 {}
1377
fcb228d1 1378 std::string as_string () const override { return ident.as_string (); }
6b35ae12 1379
df1da364 1380 location_t get_locus () const override final { return locus; }
6b35ae12
JP
1381
1382 Identifier get_ident () const { return ident; }
1383
1384 void accept_vis (ASTVisitor &vis) override;
1385
1386 // Clones this object.
1387 std::unique_ptr<IdentifierExpr> clone_identifier_expr () const
1388 {
1389 return std::unique_ptr<IdentifierExpr> (clone_identifier_expr_impl ());
1390 }
1391
1392 // "Error state" if ident is empty, so base stripping on this.
1c3a8fbb 1393 void mark_for_strip () override { ident = {""}; }
6b35ae12
JP
1394 bool is_marked_for_strip () const override { return ident.empty (); }
1395
1396 const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
36bca0cc 1397 std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
6b35ae12
JP
1398
1399 void set_outer_attrs (std::vector<Attribute> new_attrs) override
1400 {
1401 outer_attrs = std::move (new_attrs);
1402 }
1403
9c50565e 1404 Expr::Kind get_expr_kind () const override { return Expr::Kind::Identifier; }
b503080c 1405
6b35ae12
JP
1406protected:
1407 // Clone method implementation
1408 IdentifierExpr *clone_expr_without_block_impl () const final override
1409 {
1410 return clone_identifier_expr_impl ();
1411 }
1412
1413 IdentifierExpr *clone_identifier_expr_impl () const
1414 {
1415 return new IdentifierExpr (*this);
1416 }
1417};
1418
1419// Pattern base AST node
cd773704 1420class Pattern : public Visitable
6b35ae12
JP
1421{
1422public:
c1ccc7c0 1423 enum class Kind
1424 {
1425 Literal,
1426 Identifier,
1427 Wildcard,
1428 Rest,
1429 Range,
1430 Reference,
1431 Struct,
1432 TupleStruct,
1433 Tuple,
1434 Grouped,
1435 Slice,
1436 Alt,
1437 Path,
1438 MacroInvocation,
1439 };
1440
6b35ae12
JP
1441 // Unique pointer custom clone function
1442 std::unique_ptr<Pattern> clone_pattern () const
1443 {
1444 return std::unique_ptr<Pattern> (clone_pattern_impl ());
1445 }
1446
c1ccc7c0 1447 virtual Kind get_pattern_kind () = 0;
1448
6b35ae12
JP
1449 // possible virtual methods: is_refutable()
1450
1451 virtual ~Pattern () {}
1452
1453 virtual std::string as_string () const = 0;
6b35ae12
JP
1454
1455 // as only one kind of pattern can be stripped, have default of nothing
1456 virtual void mark_for_strip () {}
1457 virtual bool is_marked_for_strip () const { return false; }
1458
df1da364 1459 virtual location_t get_locus () const = 0;
292aec08 1460 virtual NodeId get_node_id () const = 0;
6b35ae12
JP
1461
1462protected:
1463 // Clone pattern implementation as pure virtual method
1464 virtual Pattern *clone_pattern_impl () const = 0;
1465};
1466
1467// forward decl for Type
1468class TraitBound;
1469
1470// Base class for types as represented in AST - abstract
9c50565e 1471class Type : public Visitable
6b35ae12
JP
1472{
1473public:
1474 // Unique pointer custom clone function
1475 std::unique_ptr<Type> clone_type () const
1476 {
1477 return std::unique_ptr<Type> (clone_type_impl ());
1478 }
1479
1480 // virtual destructor
1481 virtual ~Type () {}
1482
1483 virtual std::string as_string () const = 0;
1484
1485 /* HACK: convert to trait bound. Virtual method overriden by classes that
1486 * enable this. */
1487 virtual TraitBound *to_trait_bound (bool) const { return nullptr; }
1488 /* as pointer, shouldn't require definition beforehand, only forward
1489 * declaration. */
1490
6b35ae12
JP
1491 // as only two kinds of types can be stripped, have default of nothing
1492 virtual void mark_for_strip () {}
1493 virtual bool is_marked_for_strip () const { return false; }
1494
df1da364 1495 virtual location_t get_locus () const = 0;
6b35ae12
JP
1496
1497 NodeId get_node_id () const { return node_id; }
1498
1499protected:
fd788dd5 1500 Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
6b35ae12
JP
1501
1502 // Clone function implementation as pure virtual method
1503 virtual Type *clone_type_impl () const = 0;
1504
1505 NodeId node_id;
1506};
1507
1508// A type without parentheses? - abstract
1509class TypeNoBounds : public Type
1510{
1511public:
1512 // Unique pointer custom clone function
1513 std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
1514 {
1515 return std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
1516 }
1517
1518protected:
1519 // Clone function implementation as pure virtual method
1520 virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
1521
fcb228d1
PEP
1522 /* Save having to specify two clone methods in derived classes by making
1523 * type clone return typenobounds clone. Hopefully won't affect performance
1524 * too much. */
6b35ae12
JP
1525 TypeNoBounds *clone_type_impl () const final override
1526 {
1527 return clone_type_no_bounds_impl ();
1528 }
1529
1530 TypeNoBounds () : Type () {}
1531};
1532
fcb228d1
PEP
1533/* Abstract base class representing a type param bound - Lifetime and
1534 * TraitBound extends it */
cd773704 1535class TypeParamBound : public Visitable
6b35ae12
JP
1536{
1537public:
9b4f8f2d
PH
1538 enum TypeParamBoundType
1539 {
1540 TRAIT,
1541 LIFETIME
1542 };
1543
6b35ae12
JP
1544 virtual ~TypeParamBound () {}
1545
1546 // Unique pointer custom clone function
1547 std::unique_ptr<TypeParamBound> clone_type_param_bound () const
1548 {
1549 return std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
1550 }
1551
1552 virtual std::string as_string () const = 0;
1553
6b35ae12
JP
1554 NodeId get_node_id () const { return node_id; }
1555
df1da364 1556 virtual location_t get_locus () const = 0;
6b35ae12 1557
9b4f8f2d
PH
1558 virtual TypeParamBoundType get_bound_type () const = 0;
1559
6b35ae12
JP
1560protected:
1561 // Clone function implementation as pure virtual method
1562 virtual TypeParamBound *clone_type_param_bound_impl () const = 0;
1563
1564 TypeParamBound (NodeId node_id) : node_id (node_id) {}
1565
1566 NodeId node_id;
1567};
1568
1569// Represents a lifetime (and is also a kind of type param bound)
1570class Lifetime : public TypeParamBound
1571{
1572public:
1573 enum LifetimeType
1574 {
1575 NAMED, // corresponds to LIFETIME_OR_LABEL
1576 STATIC, // corresponds to 'static
1577 WILDCARD // corresponds to '_
1578 };
1579
1580private:
1581 LifetimeType lifetime_type;
1582 std::string lifetime_name;
d991a3f1 1583 location_t locus;
6b35ae12
JP
1584 NodeId node_id;
1585
1586public:
1587 // Constructor
1588 Lifetime (LifetimeType type, std::string name = std::string (),
d991a3f1 1589 location_t locus = UNDEF_LOCATION)
fd788dd5 1590 : TypeParamBound (Analysis::Mappings::get ().get_next_node_id ()),
6b35ae12
JP
1591 lifetime_type (type), lifetime_name (std::move (name)), locus (locus)
1592 {}
1593
1594 Lifetime (NodeId id, LifetimeType type, std::string name = std::string (),
d991a3f1 1595 location_t locus = UNDEF_LOCATION)
6b35ae12
JP
1596 : TypeParamBound (id), lifetime_type (type),
1597 lifetime_name (std::move (name)), locus (locus)
1598 {}
1599
50f30592
JD
1600 static Lifetime elided () { return Lifetime (WILDCARD, ""); }
1601
6b35ae12 1602 // Returns true if the lifetime is in an error state.
6b35ae12
JP
1603 std::string as_string () const override;
1604
1605 void accept_vis (ASTVisitor &vis) override;
1606
9b4f8f2d 1607 LifetimeType get_lifetime_type () const { return lifetime_type; }
6b35ae12 1608
df1da364 1609 location_t get_locus () const override final { return locus; }
6b35ae12
JP
1610
1611 std::string get_lifetime_name () const { return lifetime_name; }
1612
9b4f8f2d
PH
1613 TypeParamBoundType get_bound_type () const override
1614 {
1615 return TypeParamBound::TypeParamBoundType::LIFETIME;
1616 }
1617
6b35ae12 1618protected:
fcb228d1
PEP
1619 /* Use covariance to implement clone function as returning this object
1620 * rather than base */
6b35ae12
JP
1621 Lifetime *clone_type_param_bound_impl () const override
1622 {
1623 return new Lifetime (node_id, lifetime_type, lifetime_name, locus);
1624 }
1625};
1626
fcb228d1
PEP
1627/* Base generic parameter in AST. Abstract - can be represented by a Lifetime
1628 * or Type param */
cd773704 1629class GenericParam : public Visitable
6b35ae12
JP
1630{
1631public:
1632 enum class Kind
1633 {
1634 Lifetime,
1635 Type,
1636 Const,
1637 };
1638
1639 virtual ~GenericParam () {}
1640
1641 // Unique pointer custom clone function
1642 std::unique_ptr<GenericParam> clone_generic_param () const
1643 {
1644 return std::unique_ptr<GenericParam> (clone_generic_param_impl ());
1645 }
1646
1647 virtual std::string as_string () const = 0;
1648
df1da364 1649 virtual location_t get_locus () const = 0;
6b35ae12
JP
1650
1651 virtual Kind get_kind () const = 0;
1652
fb7e607d 1653 NodeId get_node_id () const { return node_id; }
6b35ae12
JP
1654
1655protected:
fd788dd5 1656 GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
6b35ae12
JP
1657 GenericParam (NodeId node_id) : node_id (node_id) {}
1658
1659 // Clone function implementation as pure virtual method
1660 virtual GenericParam *clone_generic_param_impl () const = 0;
1661
1662 NodeId node_id;
1663};
1664
1665// A lifetime generic parameter (as opposed to a type generic parameter)
1666class LifetimeParam : public GenericParam
1667{
1668 Lifetime lifetime;
1669 std::vector<Lifetime> lifetime_bounds;
6fef5bc4 1670 AST::AttrVec outer_attrs;
d991a3f1 1671 location_t locus;
6b35ae12
JP
1672
1673public:
1674 Lifetime get_lifetime () const { return lifetime; }
1675
7065e2db
PEP
1676 Lifetime &get_lifetime () { return lifetime; }
1677
6fef5bc4 1678 AST::AttrVec &get_outer_attrs () { return outer_attrs; }
7065e2db 1679
6b35ae12
JP
1680 // Returns whether the lifetime param has any lifetime bounds.
1681 bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
1682
bd2240d3
JD
1683 std::vector<Lifetime> &get_lifetime_bounds () { return lifetime_bounds; }
1684
9b4f8f2d
PH
1685 const std::vector<Lifetime> &get_lifetime_bounds () const
1686 {
1687 return lifetime_bounds;
1688 }
1689
6b35ae12 1690 // Returns whether the lifetime param has an outer attribute.
6fef5bc4 1691 bool has_outer_attribute () const { return !outer_attrs.empty (); }
6b35ae12 1692
6b35ae12
JP
1693 // Constructor
1694 LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds,
6fef5bc4 1695 AST::AttrVec outer_attrs, location_t locus)
6b35ae12
JP
1696 : lifetime (std::move (lifetime)),
1697 lifetime_bounds (std::move (lifetime_bounds)),
6fef5bc4 1698 outer_attrs (std::move (outer_attrs)), locus (locus)
6b35ae12
JP
1699 {}
1700
1701 std::string as_string () const override;
1702
1703 void accept_vis (ASTVisitor &vis) override;
1704
df1da364 1705 location_t get_locus () const override final { return locus; }
6b35ae12
JP
1706
1707 Kind get_kind () const override final { return Kind::Lifetime; }
1708
1709protected:
fcb228d1
PEP
1710 /* Use covariance to implement clone function as returning this object
1711 * rather than base */
6b35ae12
JP
1712 LifetimeParam *clone_generic_param_impl () const override
1713 {
1714 return new LifetimeParam (*this);
1715 }
1716};
1717
9e7e3ea6
OA
1718class AssociatedItem : public Visitable
1719{
1720protected:
1721 // Clone function implementation as pure virtual method
1722 virtual AssociatedItem *clone_associated_item_impl () const = 0;
1723
1724public:
1725 virtual ~AssociatedItem () {}
1726
1727 std::unique_ptr<AssociatedItem> clone_associated_item () const
1728 {
1729 return std::unique_ptr<AssociatedItem> (clone_associated_item_impl ());
1730 }
1731
1732 virtual std::string as_string () const = 0;
1733
1734 virtual void mark_for_strip () = 0;
1735 virtual bool is_marked_for_strip () const = 0;
1736
1737 virtual location_t get_locus () const = 0;
1738};
1739
6b35ae12 1740// Item used in trait declarations - abstract base class
1740fbe1 1741class TraitItem : public AssociatedItem
6b35ae12
JP
1742{
1743protected:
d991a3f1 1744 TraitItem (location_t locus)
fd788dd5 1745 : node_id (Analysis::Mappings::get ().get_next_node_id ()),
ceed844b
PEP
1746 vis (Visibility::create_private ()), locus (locus)
1747 {}
1748
1749 TraitItem (Visibility vis, location_t locus)
fd788dd5 1750 : node_id (Analysis::Mappings::get ().get_next_node_id ()), vis (vis),
ceed844b 1751 locus (locus)
fa7675df 1752 {}
6b35ae12
JP
1753
1754 // Clone function implementation as pure virtual method
9e7e3ea6 1755 virtual TraitItem *clone_associated_item_impl () const override = 0;
6b35ae12
JP
1756
1757 NodeId node_id;
ceed844b 1758 Visibility vis;
d991a3f1 1759 location_t locus;
6b35ae12
JP
1760
1761public:
6b35ae12
JP
1762 // Unique pointer custom clone function
1763 std::unique_ptr<TraitItem> clone_trait_item () const
1764 {
9e7e3ea6 1765 return std::unique_ptr<TraitItem> (clone_associated_item_impl ());
6b35ae12
JP
1766 }
1767
6b35ae12 1768 NodeId get_node_id () const { return node_id; }
74ef5529 1769 location_t get_locus () const override { return locus; }
6b35ae12
JP
1770};
1771
6b35ae12 1772// Abstract base class for an item used inside an extern block
cd773704 1773class ExternalItem : public Visitable
6b35ae12
JP
1774{
1775public:
fd788dd5 1776 ExternalItem () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
6b35ae12 1777
709db9bb 1778 ExternalItem (NodeId node_id) : node_id (node_id) {}
1779
6b35ae12
JP
1780 virtual ~ExternalItem () {}
1781
1782 // Unique pointer custom clone function
1783 std::unique_ptr<ExternalItem> clone_external_item () const
1784 {
1785 return std::unique_ptr<ExternalItem> (clone_external_item_impl ());
1786 }
1787
1788 virtual std::string as_string () const = 0;
1789
6b35ae12
JP
1790 virtual void mark_for_strip () = 0;
1791 virtual bool is_marked_for_strip () const = 0;
1792
709db9bb 1793 virtual NodeId get_node_id () const { return node_id; }
6b35ae12
JP
1794
1795protected:
1796 // Clone function implementation as pure virtual method
1797 virtual ExternalItem *clone_external_item_impl () const = 0;
1798
1799 NodeId node_id;
1800};
1801
1802/* Data structure to store the data used in macro invocations and macro
1803 * invocations with semicolons. */
1804struct MacroInvocData
1805{
1806private:
1807 SimplePath path;
1808 DelimTokenTree token_tree;
1809
1810 // One way of parsing the macro. Probably not applicable for all macros.
24c86440 1811 std::vector<std::unique_ptr<MetaItemInner>> parsed_items;
6b35ae12 1812 bool parsed_to_meta_item = false;
e88ce5cc 1813 MacroExpander *expander = nullptr;
6b35ae12
JP
1814
1815public:
1816 std::string as_string () const;
1817
1818 MacroInvocData (SimplePath path, DelimTokenTree token_tree)
1819 : path (std::move (path)), token_tree (std::move (token_tree))
1820 {}
1821
1822 // Copy constructor with vector clone
1823 MacroInvocData (const MacroInvocData &other)
1824 : path (other.path), token_tree (other.token_tree),
1825 parsed_to_meta_item (other.parsed_to_meta_item)
1826 {
1827 parsed_items.reserve (other.parsed_items.size ());
1828 for (const auto &e : other.parsed_items)
1829 parsed_items.push_back (e->clone_meta_item_inner ());
1830 }
1831
1832 // Copy assignment operator with vector clone
1833 MacroInvocData &operator= (const MacroInvocData &other)
1834 {
1835 path = other.path;
1836 token_tree = other.token_tree;
1837 parsed_to_meta_item = other.parsed_to_meta_item;
e88ce5cc 1838 expander = other.expander;
6b35ae12
JP
1839
1840 parsed_items.reserve (other.parsed_items.size ());
1841 for (const auto &e : other.parsed_items)
1842 parsed_items.push_back (e->clone_meta_item_inner ());
1843
1844 return *this;
1845 }
1846
1847 // Move constructors
1848 MacroInvocData (MacroInvocData &&other) = default;
1849 MacroInvocData &operator= (MacroInvocData &&other) = default;
1850
1851 // Invalid if path is empty, so base stripping on that.
1852 void mark_for_strip () { path = SimplePath::create_empty (); }
1853 bool is_marked_for_strip () const { return path.is_empty (); }
1854
1855 // Returns whether the macro has been parsed already.
1856 bool is_parsed () const { return parsed_to_meta_item; }
1857 // TODO: update on other ways of parsing it
1858
1859 // TODO: this mutable getter seems kinda dodgy
1860 DelimTokenTree &get_delim_tok_tree () { return token_tree; }
1861 const DelimTokenTree &get_delim_tok_tree () const { return token_tree; }
1862
38216691
AC
1863 // Set the delim token tree of a macro invocation
1864 void set_delim_tok_tree (DelimTokenTree tree) { token_tree = tree; }
1865
6b35ae12
JP
1866 // TODO: this mutable getter seems kinda dodgy
1867 SimplePath &get_path () { return path; }
1868 const SimplePath &get_path () const { return path; }
1869
e88ce5cc 1870 void set_expander (MacroExpander *new_expander) { expander = new_expander; }
1871 MacroExpander *get_expander ()
1872 {
1873 rust_assert (expander);
1874 return expander;
1875 }
1876
6b35ae12 1877 void
24c86440 1878 set_meta_item_output (std::vector<std::unique_ptr<MetaItemInner>> new_items)
6b35ae12
JP
1879 {
1880 parsed_items = std::move (new_items);
1881 }
1882 // TODO: mutable getter seems kinda dodgy
24c86440 1883 std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items ()
6b35ae12
JP
1884 {
1885 return parsed_items;
1886 }
24c86440 1887 const std::vector<std::unique_ptr<MetaItemInner>> &get_meta_items () const
6b35ae12
JP
1888 {
1889 return parsed_items;
1890 }
1891};
1892
cd773704 1893class SingleASTNode : public Visitable
6b35ae12
JP
1894{
1895public:
1896 enum NodeType
1897 {
1898 EXPRESSION,
1899 ITEM,
1900 STMT,
1901 EXTERN,
1460044f 1902 ASSOC_ITEM,
6b35ae12
JP
1903 TYPE,
1904 };
1905
1906private:
1907 NodeType kind;
1908
1909 // FIXME make this a union
1910 std::unique_ptr<Expr> expr;
1911 std::unique_ptr<Item> item;
1912 std::unique_ptr<Stmt> stmt;
1913 std::unique_ptr<ExternalItem> external_item;
1460044f 1914 std::unique_ptr<AssociatedItem> assoc_item;
6b35ae12
JP
1915 std::unique_ptr<Type> type;
1916
1917public:
1918 SingleASTNode (std::unique_ptr<Expr> expr)
1919 : kind (EXPRESSION), expr (std::move (expr))
1920 {}
1921
1922 SingleASTNode (std::unique_ptr<Item> item)
1923 : kind (ITEM), item (std::move (item))
1924 {}
1925
1926 SingleASTNode (std::unique_ptr<Stmt> stmt)
1927 : kind (STMT), stmt (std::move (stmt))
1928 {}
1929
1930 SingleASTNode (std::unique_ptr<ExternalItem> item)
1931 : kind (EXTERN), external_item (std::move (item))
1932 {}
1933
f84e5642 1934 SingleASTNode (std::unique_ptr<AssociatedItem> item)
1460044f 1935 : kind (ASSOC_ITEM), assoc_item (std::move (item))
6b35ae12
JP
1936 {}
1937
1938 SingleASTNode (std::unique_ptr<Type> type)
1939 : kind (TYPE), type (std::move (type))
1940 {}
1941
55bfecc9 1942 SingleASTNode (SingleASTNode const &other);
6b35ae12 1943
55bfecc9 1944 SingleASTNode operator= (SingleASTNode const &other);
6b35ae12
JP
1945
1946 SingleASTNode (SingleASTNode &&other) = default;
1947 SingleASTNode &operator= (SingleASTNode &&other) = default;
1948
1949 NodeType get_kind () const { return kind; }
1950
1951 std::unique_ptr<Expr> &get_expr ()
1952 {
1953 rust_assert (kind == EXPRESSION);
1954 return expr;
1955 }
1956
1957 std::unique_ptr<Item> &get_item ()
1958 {
1959 rust_assert (kind == ITEM);
1960 return item;
1961 }
1962
1963 std::unique_ptr<Stmt> &get_stmt ()
1964 {
1965 rust_assert (kind == STMT);
1966 return stmt;
1967 }
1968
1969 /**
1970 * Access the inner nodes and take ownership of them.
1971 * You can only call these functions once per node
1972 */
1973
1974 std::unique_ptr<Stmt> take_stmt ()
1975 {
1976 rust_assert (!is_error ());
1977 return std::move (stmt);
1978 }
1979
1980 std::unique_ptr<Expr> take_expr ()
1981 {
1982 rust_assert (!is_error ());
1983 return std::move (expr);
1984 }
1985
1986 std::unique_ptr<Item> take_item ()
1987 {
1988 rust_assert (!is_error ());
1989 return std::move (item);
1990 }
1991
6b35ae12
JP
1992 std::unique_ptr<ExternalItem> take_external_item ()
1993 {
1994 rust_assert (!is_error ());
1995 return std::move (external_item);
1996 }
1997
1460044f 1998 std::unique_ptr<AssociatedItem> take_assoc_item ()
6b35ae12
JP
1999 {
2000 rust_assert (!is_error ());
1460044f
OA
2001 return std::move (assoc_item);
2002 }
2003
6b35ae12
JP
2004 std::unique_ptr<Type> take_type ()
2005 {
2006 rust_assert (!is_error ());
2007 return std::move (type);
2008 }
2009
55bfecc9 2010 void accept_vis (ASTVisitor &vis) override;
6b35ae12 2011
55bfecc9 2012 bool is_error ();
6b35ae12 2013
55bfecc9 2014 std::string as_string () const;
6b35ae12
JP
2015};
2016
6b35ae12
JP
2017// A crate AST object - holds all the data for a single compilation unit
2018struct Crate
2019{
2020 std::vector<Attribute> inner_attrs;
2021 // dodgy spacing required here
2022 /* TODO: is it better to have a vector of items here or a module (implicit
2023 * top-level one)? */
24c86440 2024 std::vector<std::unique_ptr<Item>> items;
6b35ae12
JP
2025
2026 NodeId node_id;
2027
2028public:
2029 // Constructor
24c86440 2030 Crate (std::vector<std::unique_ptr<Item>> items,
6b35ae12
JP
2031 std::vector<Attribute> inner_attrs)
2032 : inner_attrs (std::move (inner_attrs)), items (std::move (items)),
fd788dd5 2033 node_id (Analysis::Mappings::get ().get_next_node_id ())
6b35ae12
JP
2034 {}
2035
2036 // Copy constructor with vector clone
2037 Crate (Crate const &other)
2038 : inner_attrs (other.inner_attrs), node_id (other.node_id)
2039 {
2040 items.reserve (other.items.size ());
2041 for (const auto &e : other.items)
2042 items.push_back (e->clone_item ());
2043 }
2044
2045 ~Crate () = default;
2046
2047 // Overloaded assignment operator with vector clone
2048 Crate &operator= (Crate const &other)
2049 {
2050 inner_attrs = other.inner_attrs;
2051 node_id = other.node_id;
2052
2053 items.reserve (other.items.size ());
2054 for (const auto &e : other.items)
2055 items.push_back (e->clone_item ());
2056
2057 return *this;
2058 }
2059
2060 // Move constructors
2061 Crate (Crate &&other) = default;
2062 Crate &operator= (Crate &&other) = default;
2063
2064 // Get crate representation as string (e.g. for debugging).
2065 std::string as_string () const;
2066
2067 // Delete all crate information, e.g. if fails cfg.
2068 void strip_crate ()
2069 {
2070 inner_attrs.clear ();
2071 inner_attrs.shrink_to_fit ();
2072
2073 items.clear ();
2074 items.shrink_to_fit ();
2075 // TODO: is this the best way to do this?
2076 }
2077
2078 NodeId get_node_id () const { return node_id; }
2079 const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; }
5a9c2732 2080 std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
ebbb3d2d
AC
2081
2082 std::vector<std::unique_ptr<AST::Item>> take_items ()
2083 {
2084 return std::move (items);
2085 }
2086
2087 void set_items (std::vector<std::unique_ptr<AST::Item>> &&new_items)
2088 {
2089 items = std::move (new_items);
2090 }
6b35ae12
JP
2091};
2092
6b35ae12
JP
2093} // namespace AST
2094} // namespace Rust
2095
fcb228d1
PEP
2096namespace std {
2097template <> struct less<Rust::Identifier>
2098{
2099 bool operator() (const Rust::Identifier &lhs,
2100 const Rust::Identifier &rhs) const
2101 {
2102 return lhs.as_string () < rhs.as_string ();
2103 }
2104};
a65c3b49
PEP
2105
2106template <> struct hash<Rust::Identifier>
2107{
2108 std::size_t operator() (const Rust::Identifier &k) const
2109 {
2110 using std::hash;
2111 using std::size_t;
2112 using std::string;
2113
2114 return hash<string> () (k.as_string ()) ^ (hash<int> () (k.get_locus ()));
2115 }
2116};
2117
fcb228d1
PEP
2118} // namespace std
2119
6b35ae12 2120#endif