22
22
23
23
#include " rust-system.h"
24
24
#include " rust-hir-map.h"
25
-
26
- // gccrs imports
27
- // required for AST::Token
28
25
#include " rust-token.h"
29
26
#include " rust-location.h"
30
27
31
28
namespace Rust {
32
29
// TODO: remove typedefs and make actual types for these
33
30
typedef std::string Identifier;
34
31
typedef int TupleIndex;
35
-
36
32
struct Session ;
37
33
38
34
namespace AST {
@@ -48,34 +44,6 @@ enum DelimType
48
44
CURLY
49
45
};
50
46
51
- // Base AST node object - TODO is this really required or useful? Where to draw
52
- // line?
53
- /* class Node {
54
- public:
55
- // Gets node's Location.
56
- Location get_locus() const {
57
- return loc;
58
- }
59
-
60
- // Sets node's Location.
61
- void set_locus(Location loc_) {
62
- loc = loc_;
63
- }
64
-
65
- // Get node output as a string. Pure virtual.
66
- virtual std::string as_string() const = 0;
67
-
68
- virtual ~Node() {}
69
-
70
- // TODO: constructor including Location? Make all derived classes have
71
- Location?
72
-
73
- private:
74
- // The node's location.
75
- Location loc;
76
- };*/
77
- // decided to not have node as a "node" would never need to be stored
78
-
79
47
// forward decl for use in token tree method
80
48
class Token ;
81
49
@@ -108,6 +76,14 @@ class TokenTree
108
76
class MacroMatch
109
77
{
110
78
public:
79
+ enum MacroMatchType
80
+ {
81
+ Fragment,
82
+ Repetition,
83
+ Matcher,
84
+ Tok
85
+ };
86
+
111
87
virtual ~MacroMatch () {}
112
88
113
89
virtual std::string as_string () const = 0;
@@ -121,6 +97,8 @@ class MacroMatch
121
97
122
98
virtual void accept_vis (ASTVisitor &vis) = 0;
123
99
100
+ virtual MacroMatchType get_macro_match_type () const = 0;
101
+
124
102
protected:
125
103
// pure virtual clone implementation
126
104
virtual MacroMatch *clone_macro_match_impl () const = 0;
@@ -234,6 +212,11 @@ class Token : public TokenTree, public MacroMatch
234
212
// Get a new token pointer copy.
235
213
const_TokenPtr get_tok_ptr () const { return tok_ref; }
236
214
215
+ MacroMatchType get_macro_match_type () const override
216
+ {
217
+ return MacroMatchType::Tok;
218
+ }
219
+
237
220
protected:
238
221
// No virtual for now as not polymorphic but can be in future
239
222
/* virtual*/ Token *clone_token_impl () const { return new Token (*this ); }
@@ -788,6 +771,13 @@ class DelimTokenTree : public TokenTree, public AttrInput
788
771
{
789
772
return AttrInput::AttrInputType::TOKEN_TREE;
790
773
}
774
+
775
+ std::vector<std::unique_ptr<TokenTree> > &get_token_trees ()
776
+ {
777
+ return token_trees;
778
+ }
779
+
780
+ DelimType get_delim_type () const { return delim_type; }
791
781
};
792
782
793
783
/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
@@ -1485,6 +1475,160 @@ struct MacroInvocData
1485
1475
}
1486
1476
};
1487
1477
1478
+ class SingleASTNode
1479
+ {
1480
+ public:
1481
+ enum NodeType
1482
+ {
1483
+ EXPRESSION,
1484
+ ITEM,
1485
+ STMT,
1486
+ };
1487
+
1488
+ SingleASTNode (std::unique_ptr<Expr> expr)
1489
+ : type (EXPRESSION), expr (std::move (expr)), item (nullptr ), stmt (nullptr )
1490
+ {}
1491
+
1492
+ SingleASTNode (std::unique_ptr<Item> item)
1493
+ : type (ITEM), expr (nullptr ), item (std::move (item)), stmt (nullptr )
1494
+ {}
1495
+
1496
+ SingleASTNode (std::unique_ptr<Stmt> stmt)
1497
+ : type (STMT), expr (nullptr ), item (nullptr ), stmt (std::move (stmt))
1498
+ {}
1499
+
1500
+ SingleASTNode (SingleASTNode const &other)
1501
+ {
1502
+ type = other.type ;
1503
+ switch (type)
1504
+ {
1505
+ case EXPRESSION:
1506
+ expr = other.expr ->clone_expr ();
1507
+ break ;
1508
+
1509
+ case ITEM:
1510
+ item = other.item ->clone_item ();
1511
+ break ;
1512
+
1513
+ case STMT:
1514
+ stmt = other.stmt ->clone_stmt ();
1515
+ break ;
1516
+ }
1517
+ }
1518
+
1519
+ SingleASTNode operator = (SingleASTNode const &other)
1520
+ {
1521
+ type = other.type ;
1522
+ switch (type)
1523
+ {
1524
+ case EXPRESSION:
1525
+ expr = other.expr ->clone_expr ();
1526
+ break ;
1527
+
1528
+ case ITEM:
1529
+ item = other.item ->clone_item ();
1530
+ break ;
1531
+
1532
+ case STMT:
1533
+ stmt = other.stmt ->clone_stmt ();
1534
+ break ;
1535
+ }
1536
+ return *this ;
1537
+ }
1538
+
1539
+ SingleASTNode (SingleASTNode &&other) = default ;
1540
+ SingleASTNode &operator = (SingleASTNode &&other) = default ;
1541
+
1542
+ std::unique_ptr<Expr> &get_expr ()
1543
+ {
1544
+ rust_assert (type == EXPRESSION);
1545
+ return expr;
1546
+ }
1547
+
1548
+ std::unique_ptr<Item> &get_item ()
1549
+ {
1550
+ rust_assert (type == ITEM);
1551
+ return item;
1552
+ }
1553
+
1554
+ std::unique_ptr<Stmt> &get_stmt ()
1555
+ {
1556
+ rust_assert (type == STMT);
1557
+ return stmt;
1558
+ }
1559
+
1560
+ void accept_vis (ASTVisitor &vis)
1561
+ {
1562
+ switch (type)
1563
+ {
1564
+ case EXPRESSION:
1565
+ expr->accept_vis (vis);
1566
+ break ;
1567
+
1568
+ case ITEM:
1569
+ item->accept_vis (vis);
1570
+ break ;
1571
+
1572
+ case STMT:
1573
+ stmt->accept_vis (vis);
1574
+ break ;
1575
+ }
1576
+ }
1577
+
1578
+ private:
1579
+ NodeType type;
1580
+
1581
+ // FIXME make this a union
1582
+ std::unique_ptr<Expr> expr;
1583
+ std::unique_ptr<Item> item;
1584
+ std::unique_ptr<Stmt> stmt;
1585
+ };
1586
+
1587
+ /* Basically, a "fragment" that can be incorporated into the AST, created as
1588
+ * a result of macro expansion. Really annoying to work with due to the fact
1589
+ * that macros can really expand to anything. As such, horrible representation
1590
+ * at the moment. */
1591
+ class ASTFragment
1592
+ {
1593
+ private:
1594
+ /* basic idea: essentially, a vector of tagged unions of different AST node
1595
+ * types. Now, this could actually be stored without a tagged union if the
1596
+ * different AST node types had a unified parent, but that would create
1597
+ * issues with the diamond problem or significant performance penalties. So
1598
+ * a tagged union had to be used instead. A vector is used to represent the
1599
+ * ability for a macro to expand to two statements, for instance. */
1600
+
1601
+ std::vector<SingleASTNode> nodes;
1602
+
1603
+ public:
1604
+ ASTFragment (std::vector<SingleASTNode> nodes) : nodes (std::move (nodes)) {}
1605
+
1606
+ ASTFragment (ASTFragment const &other)
1607
+ {
1608
+ nodes.clear ();
1609
+ nodes.reserve (other.nodes .size ());
1610
+ for (auto &n : other.nodes )
1611
+ {
1612
+ nodes.push_back (n);
1613
+ }
1614
+ }
1615
+
1616
+ ASTFragment &operator = (ASTFragment const &other)
1617
+ {
1618
+ nodes.clear ();
1619
+ nodes.reserve (other.nodes .size ());
1620
+ for (auto &n : other.nodes )
1621
+ {
1622
+ nodes.push_back (n);
1623
+ }
1624
+ return *this ;
1625
+ }
1626
+
1627
+ static ASTFragment create_empty () { return ASTFragment ({}); }
1628
+
1629
+ std::vector<SingleASTNode> &get_nodes () { return nodes; }
1630
+ };
1631
+
1488
1632
/* A macro invocation item (or statement) AST node (i.e. semi-coloned macro
1489
1633
* invocation) */
1490
1634
class MacroInvocationSemi : public MacroItem ,
@@ -1496,14 +1640,20 @@ class MacroInvocationSemi : public MacroItem,
1496
1640
std::vector<Attribute> outer_attrs;
1497
1641
MacroInvocData invoc_data;
1498
1642
Location locus;
1643
+ NodeId node_id;
1644
+
1645
+ // this is the expanded macro
1646
+ ASTFragment fragment;
1499
1647
1500
1648
public:
1501
1649
std::string as_string () const override ;
1502
1650
1503
1651
MacroInvocationSemi (MacroInvocData invoc_data,
1504
1652
std::vector<Attribute> outer_attrs, Location locus)
1505
1653
: outer_attrs (std::move (outer_attrs)),
1506
- invoc_data (std::move (invoc_data)), locus (locus)
1654
+ invoc_data (std::move (invoc_data)), locus (locus),
1655
+ node_id (Analysis::Mappings::get ()->get_next_node_id ()),
1656
+ fragment (ASTFragment::create_empty ())
1507
1657
{}
1508
1658
1509
1659
void accept_vis (ASTVisitor &vis) override ;
@@ -1527,6 +1677,14 @@ class MacroInvocationSemi : public MacroItem,
1527
1677
1528
1678
Location get_locus () const override final { return locus; }
1529
1679
1680
+ MacroInvocData &get_invoc_data () { return invoc_data; }
1681
+
1682
+ ASTFragment &get_fragment () { return fragment; }
1683
+
1684
+ void set_fragment (ASTFragment &&f) { fragment = std::move (f); }
1685
+
1686
+ NodeId get_macro_node_id () const { return node_id; }
1687
+
1530
1688
protected:
1531
1689
MacroInvocationSemi *clone_macro_invocation_semi_impl () const
1532
1690
{
0 commit comments