/src/solidity/libyul/optimiser/ASTWalker.h
Line | Count | Source |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * Generic AST walker. |
20 | | */ |
21 | | |
22 | | #pragma once |
23 | | |
24 | | #include <libyul/ASTForward.h> |
25 | | |
26 | | #include <libyul/Exceptions.h> |
27 | | #include <libyul/YulName.h> |
28 | | |
29 | | #include <map> |
30 | | #include <optional> |
31 | | #include <set> |
32 | | #include <vector> |
33 | | |
34 | | namespace solidity::yul |
35 | | { |
36 | | |
37 | | /** |
38 | | * Generic AST walker. |
39 | | */ |
40 | | class ASTWalker |
41 | | { |
42 | | public: |
43 | 498M | virtual ~ASTWalker() = default; |
44 | 1.42G | virtual void operator()(Literal const&) {} |
45 | 1.75G | virtual void operator()(Identifier const&) {} |
46 | | virtual void operator()(FunctionCall const& _funCall); |
47 | | virtual void operator()(ExpressionStatement const& _statement); |
48 | | virtual void operator()(Assignment const& _assignment); |
49 | | virtual void operator()(VariableDeclaration const& _varDecl); |
50 | | virtual void operator()(If const& _if); |
51 | | virtual void operator()(Switch const& _switch); |
52 | | virtual void operator()(FunctionDefinition const&); |
53 | | virtual void operator()(ForLoop const&); |
54 | 28.6M | virtual void operator()(Break const&) {} |
55 | 3.97M | virtual void operator()(Continue const&) {} |
56 | 6.49M | virtual void operator()(Leave const&) {} |
57 | | virtual void operator()(Block const& _block); |
58 | | |
59 | | virtual void visit(Statement const& _st); |
60 | | virtual void visit(Expression const& _e); |
61 | | |
62 | | protected: |
63 | | template <class T> |
64 | | void walkVector(T const& _statements) |
65 | 1.38G | { |
66 | 1.38G | for (auto const& statement: _statements) |
67 | 4.16G | visit(statement); |
68 | 1.38G | } void solidity::yul::ASTWalker::walkVector<std::__1::vector<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block>, std::__1::allocator<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> > > >(std::__1::vector<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block>, std::__1::allocator<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> > > const&) Line | Count | Source | 65 | 347M | { | 66 | 347M | for (auto const& statement: _statements) | 67 | 2.26G | visit(statement); | 68 | 347M | } |
void solidity::yul::ASTWalker::walkVector<ranges::reverse_view<ranges::ref_view<std::__1::vector<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal>, std::__1::allocator<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> > > const> > >(ranges::reverse_view<ranges::ref_view<std::__1::vector<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal>, std::__1::allocator<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> > > const> > const&) Line | Count | Source | 65 | 1.04G | { | 66 | 1.04G | for (auto const& statement: _statements) | 67 | 1.90G | visit(statement); | 68 | 1.04G | } |
|
69 | | }; |
70 | | |
71 | | /** |
72 | | * Generic AST modifier (i.e. non-const version of ASTWalker). |
73 | | */ |
74 | | class ASTModifier |
75 | | { |
76 | | public: |
77 | 15.7M | virtual ~ASTModifier() = default; |
78 | 918M | virtual void operator()(Literal&) {} |
79 | 767M | virtual void operator()(Identifier&) {} |
80 | | virtual void operator()(FunctionCall& _funCall); |
81 | | virtual void operator()(ExpressionStatement& _statement); |
82 | | virtual void operator()(Assignment& _assignment); |
83 | | virtual void operator()(VariableDeclaration& _varDecl); |
84 | | virtual void operator()(If& _if); |
85 | | virtual void operator()(Switch& _switch); |
86 | | virtual void operator()(FunctionDefinition&); |
87 | | virtual void operator()(ForLoop&); |
88 | | virtual void operator()(Break&); |
89 | | virtual void operator()(Continue&); |
90 | | virtual void operator()(Leave&); |
91 | | virtual void operator()(Block& _block); |
92 | | |
93 | | virtual void visit(Statement& _st); |
94 | | virtual void visit(Expression& _e); |
95 | | |
96 | | protected: |
97 | | template <class T> |
98 | | void walkVector(T&& _statements) |
99 | 594M | { |
100 | 594M | for (auto& st: _statements) |
101 | 1.81G | visit(st); |
102 | 594M | } void solidity::yul::ASTModifier::walkVector<ranges::reverse_view<ranges::ref_view<std::__1::vector<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal>, std::__1::allocator<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> > > > > >(ranges::reverse_view<ranges::ref_view<std::__1::vector<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal>, std::__1::allocator<std::__1::variant<solidity::yul::FunctionCall, solidity::yul::Identifier, solidity::yul::Literal> > > > >&&) Line | Count | Source | 99 | 465M | { | 100 | 465M | for (auto& st: _statements) | 101 | 838M | visit(st); | 102 | 465M | } |
void solidity::yul::ASTModifier::walkVector<std::__1::vector<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block>, std::__1::allocator<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> > >&>(std::__1::vector<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block>, std::__1::allocator<std::__1::variant<solidity::yul::ExpressionStatement, solidity::yul::Assignment, solidity::yul::VariableDeclaration, solidity::yul::FunctionDefinition, solidity::yul::If, solidity::yul::Switch, solidity::yul::ForLoop, solidity::yul::Break, solidity::yul::Continue, solidity::yul::Leave, solidity::yul::Block> > >&) Line | Count | Source | 99 | 128M | { | 100 | 128M | for (auto& st: _statements) | 101 | 975M | visit(st); | 102 | 128M | } |
|
103 | | }; |
104 | | |
105 | | namespace detail |
106 | | { |
107 | | template < |
108 | | typename Node, |
109 | | typename Visitor, |
110 | | typename Base = std::conditional_t<std::is_const_v<Node>, ASTWalker, ASTModifier> |
111 | | > |
112 | | struct ForEach: Base |
113 | | { |
114 | 27.6M | ForEach(Visitor& _visitor): visitor(_visitor) {}NameCollector.cpp:solidity::yul::detail::ForEach<solidity::yul::Assignment const, solidity::yul::assignedVariableNames(solidity::yul::Block const&)::$_0&, solidity::yul::ASTWalker>::ForEach(solidity::yul::assignedVariableNames(solidity::yul::Block const&)::$_0&) Line | Count | Source | 114 | 27.5M | ForEach(Visitor& _visitor): visitor(_visitor) {} |
NameCollector.cpp:solidity::yul::detail::ForEach<solidity::yul::FunctionDefinition const, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_0&, solidity::yul::ASTWalker>::ForEach(solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_0&) Line | Count | Source | 114 | 92.6k | ForEach(Visitor& _visitor): visitor(_visitor) {} |
|
115 | | |
116 | | using Base::operator(); |
117 | | void operator()(Node& _node) override |
118 | 22.9M | { |
119 | 22.9M | visitor(_node); |
120 | 22.9M | Base::operator()(_node); |
121 | 22.9M | } NameCollector.cpp:solidity::yul::detail::ForEach<solidity::yul::Assignment const, solidity::yul::assignedVariableNames(solidity::yul::Block const&)::$_0&, solidity::yul::ASTWalker>::operator()(solidity::yul::Assignment const&) Line | Count | Source | 118 | 22.6M | { | 119 | 22.6M | visitor(_node); | 120 | 22.6M | Base::operator()(_node); | 121 | 22.6M | } |
NameCollector.cpp:solidity::yul::detail::ForEach<solidity::yul::FunctionDefinition const, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_0&, solidity::yul::ASTWalker>::operator()(solidity::yul::FunctionDefinition const&) Line | Count | Source | 118 | 294k | { | 119 | 294k | visitor(_node); | 120 | 294k | Base::operator()(_node); | 121 | 294k | } |
|
122 | | |
123 | | Visitor& visitor; |
124 | | }; |
125 | | } |
126 | | |
127 | | /// Helper function that traverses the AST and calls the visitor for each |
128 | | /// node of a specific type. |
129 | | template<typename Node, typename Entry, typename Visitor> |
130 | | void forEach(Entry&& _entry, Visitor&& _visitor) |
131 | 27.6M | { |
132 | 27.6M | detail::ForEach<Node, Visitor&>{_visitor}(_entry); |
133 | 27.6M | } NameCollector.cpp:void solidity::yul::forEach<solidity::yul::Assignment const, solidity::yul::Block const&, solidity::yul::assignedVariableNames(solidity::yul::Block const&)::$_0>(solidity::yul::Block const&, solidity::yul::assignedVariableNames(solidity::yul::Block const&)::$_0&&) Line | Count | Source | 131 | 27.5M | { | 132 | 27.5M | detail::ForEach<Node, Visitor&>{_visitor}(_entry); | 133 | 27.5M | } |
NameCollector.cpp:void solidity::yul::forEach<solidity::yul::FunctionDefinition const, solidity::yul::Block const&, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_0>(solidity::yul::Block const&, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_0&&) Line | Count | Source | 131 | 92.6k | { | 132 | 92.6k | detail::ForEach<Node, Visitor&>{_visitor}(_entry); | 133 | 92.6k | } |
|
134 | | |
135 | | } |