/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/YulString.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 | 78.1M | virtual ~ASTWalker() = default; |
44 | 231M | virtual void operator()(Literal const&) {} |
45 | 336M | 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 | 11.3M | virtual void operator()(Break const&) {} |
55 | 1.28M | virtual void operator()(Continue const&) {} |
56 | 2.02M | 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 | 236M | { |
66 | 236M | for (auto const& statement: _statements) |
67 | 798M | visit(statement); |
68 | 236M | } 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 | 76.4M | { | 66 | 76.4M | for (auto const& statement: _statements) | 67 | 437M | visit(statement); | 68 | 76.4M | } |
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 | 160M | { | 66 | 160M | for (auto const& statement: _statements) | 67 | 361M | visit(statement); | 68 | 160M | } |
|
69 | | }; |
70 | | |
71 | | /** |
72 | | * Generic AST modifier (i.e. non-const version of ASTWalker). |
73 | | */ |
74 | | class ASTModifier |
75 | | { |
76 | | public: |
77 | 4.10M | virtual ~ASTModifier() = default; |
78 | 141M | virtual void operator()(Literal&) {} |
79 | 154M | 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 | 99.6M | { |
100 | 99.6M | for (auto& st: _statements) |
101 | 328M | visit(st); |
102 | 99.6M | } 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 | 71.6M | { | 100 | 71.6M | for (auto& st: _statements) | 101 | 153M | visit(st); | 102 | 71.6M | } |
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 | 27.9M | { | 100 | 27.9M | for (auto& st: _statements) | 101 | 175M | visit(st); | 102 | 27.9M | } |
|
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 | 5.81M | 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 | 5.81M | ForEach(Visitor& _visitor): visitor(_visitor) {} |
Unexecuted instantiation: NameCollector.cpp:solidity::yul::detail::ForEach<solidity::yul::FunctionDefinition const, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_1&, solidity::yul::ASTWalker>::ForEach(solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_1&) |
115 | | |
116 | | using Base::operator(); |
117 | | void operator()(Node& _node) override |
118 | 3.07M | { |
119 | 3.07M | visitor(_node); |
120 | 3.07M | Base::operator()(_node); |
121 | 3.07M | } 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 | 3.07M | { | 119 | 3.07M | visitor(_node); | 120 | 3.07M | Base::operator()(_node); | 121 | 3.07M | } |
Unexecuted instantiation: NameCollector.cpp:solidity::yul::detail::ForEach<solidity::yul::FunctionDefinition const, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_1&, solidity::yul::ASTWalker>::operator()(solidity::yul::FunctionDefinition const&) |
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 | 5.81M | { |
132 | 5.81M | detail::ForEach<Node, Visitor&>{_visitor}(_entry); |
133 | 5.81M | } 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 | 5.81M | { | 132 | 5.81M | detail::ForEach<Node, Visitor&>{_visitor}(_entry); | 133 | 5.81M | } |
Unexecuted instantiation: NameCollector.cpp:void solidity::yul::forEach<solidity::yul::FunctionDefinition const, solidity::yul::Block const&, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_1>(solidity::yul::Block const&, solidity::yul::allFunctionDefinitions(solidity::yul::Block const&)::$_1&&) |
134 | | |
135 | | } |