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