Skip to content

Commit 25c4154

Browse files
committed
Function reference resolver.
1 parent dd8f127 commit 25c4154

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

libyul/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ add_library(yul
4040
Dialect.cpp
4141
Dialect.h
4242
Exceptions.h
43+
FunctionReferenceResolver.cpp
44+
FunctionReferenceResolver.h
4345
Object.cpp
4446
Object.h
4547
ObjectParser.cpp

libyul/FunctionReferenceResolver.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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+
#include <libyul/FunctionReferenceResolver.h>
20+
21+
#include <libyul/AST.h>
22+
#include <libsolutil/CommonData.h>
23+
24+
#include <range/v3/view/reverse.hpp>
25+
26+
using namespace std;
27+
using namespace solidity::yul;
28+
using namespace solidity::util;
29+
30+
FunctionReferenceResolver::FunctionReferenceResolver(Block const& _ast)
31+
{
32+
(*this)(_ast);
33+
yulAssert(m_scopes.empty());
34+
}
35+
36+
void FunctionReferenceResolver::operator()(FunctionCall const& _functionCall)
37+
{
38+
for (auto&& scope: m_scopes | ranges::views::reverse)
39+
if (FunctionDefinition const** function = util::valueOrNullptr(scope, _functionCall.functionName.name))
40+
{
41+
m_functionReferences[&_functionCall] = *function;
42+
break;
43+
}
44+
45+
// If we did not find anything, it was a builtin call.
46+
47+
ASTWalker::operator()(_functionCall);
48+
}
49+
50+
void FunctionReferenceResolver::operator()(Block const& _block)
51+
{
52+
m_scopes.emplace_back();
53+
for (auto const& statement: _block.statements)
54+
if (auto const* function = get_if<FunctionDefinition>(&statement))
55+
m_scopes.back()[function->name] = function;
56+
57+
ASTWalker::operator()(_block);
58+
59+
m_scopes.pop_back();
60+
}

libyul/FunctionReferenceResolver.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
#pragma once
20+
21+
#include <libyul/optimiser/ASTWalker.h>
22+
23+
namespace solidity::yul
24+
{
25+
26+
/**
27+
* Resolves references to user-defined functions in function calls.
28+
* Assumes the code is correct, i.e. does not check for references to be valid or unique.
29+
*
30+
* Be careful not to iterate over the result - it is not deterministic.
31+
*/
32+
class FunctionReferenceResolver: private ASTWalker
33+
{
34+
public:
35+
explicit FunctionReferenceResolver(Block const& _ast);
36+
std::map<FunctionCall const*, FunctionDefinition const*> const& references() const { return m_functionReferences; }
37+
38+
private:
39+
using ASTWalker::operator();
40+
void operator()(FunctionCall const& _functionCall) override;
41+
void operator()(Block const& _block) override;
42+
43+
std::map<FunctionCall const*, FunctionDefinition const*> m_functionReferences;
44+
std::vector<std::map<YulString, FunctionDefinition const*>> m_scopes;
45+
};
46+
47+
48+
}

0 commit comments

Comments
 (0)