mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11470 from ethereum/cacheVirtualLookup
Cache functions by name.
This commit is contained in:
commit
9be57546db
@ -276,6 +276,17 @@ FunctionDefinition const* ContractDefinition::nextConstructor(ContractDefinition
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
multimap<std::string, FunctionDefinition const*> const& ContractDefinition::definedFunctionsByName() const
|
||||||
|
{
|
||||||
|
return m_definedFunctionsByName.init([&]{
|
||||||
|
std::multimap<std::string, FunctionDefinition const*> result;
|
||||||
|
for (FunctionDefinition const* fun: filteredNodes<FunctionDefinition>(m_subNodes))
|
||||||
|
result.insert({fun->name(), fun});
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TypeNameAnnotation& TypeName::annotation() const
|
TypeNameAnnotation& TypeName::annotation() const
|
||||||
{
|
{
|
||||||
return initAnnotation<TypeNameAnnotation>();
|
return initAnnotation<TypeNameAnnotation>();
|
||||||
@ -397,6 +408,7 @@ FunctionDefinition const& FunctionDefinition::resolveVirtual(
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
solAssert(!isConstructor(), "");
|
solAssert(!isConstructor(), "");
|
||||||
|
solAssert(!name().empty(), "");
|
||||||
|
|
||||||
// If we are not doing super-lookup and the function is not virtual, we can stop here.
|
// If we are not doing super-lookup and the function is not virtual, we can stop here.
|
||||||
if (_searchStart == nullptr && !virtualSemantics())
|
if (_searchStart == nullptr && !virtualSemantics())
|
||||||
@ -416,10 +428,8 @@ FunctionDefinition const& FunctionDefinition::resolveVirtual(
|
|||||||
else
|
else
|
||||||
foundSearchStart = true;
|
foundSearchStart = true;
|
||||||
|
|
||||||
for (FunctionDefinition const* function: c->definedFunctions())
|
for (FunctionDefinition const* function: c->definedFunctions(name()))
|
||||||
if (
|
if (
|
||||||
function->name() == name() &&
|
|
||||||
!function->isConstructor() &&
|
|
||||||
// With super lookup analysis guarantees that there is an implemented function in the chain.
|
// With super lookup analysis guarantees that there is an implemented function in the chain.
|
||||||
// With virtual lookup there are valid cases where returning an unimplemented one is fine.
|
// With virtual lookup there are valid cases where returning an unimplemented one is fine.
|
||||||
(function->isImplemented() || _searchStart == nullptr) &&
|
(function->isImplemented() || _searchStart == nullptr) &&
|
||||||
|
@ -36,6 +36,9 @@
|
|||||||
|
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
#include <range/v3/view/subrange.hpp>
|
||||||
|
#include <range/v3/view/map.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -497,6 +500,13 @@ public:
|
|||||||
std::vector<VariableDeclaration const*> stateVariables() const { return filteredNodes<VariableDeclaration>(m_subNodes); }
|
std::vector<VariableDeclaration const*> stateVariables() const { return filteredNodes<VariableDeclaration>(m_subNodes); }
|
||||||
std::vector<ModifierDefinition const*> functionModifiers() const { return filteredNodes<ModifierDefinition>(m_subNodes); }
|
std::vector<ModifierDefinition const*> functionModifiers() const { return filteredNodes<ModifierDefinition>(m_subNodes); }
|
||||||
std::vector<FunctionDefinition const*> definedFunctions() const { return filteredNodes<FunctionDefinition>(m_subNodes); }
|
std::vector<FunctionDefinition const*> definedFunctions() const { return filteredNodes<FunctionDefinition>(m_subNodes); }
|
||||||
|
/// @returns a view<FunctionDefinition const*> of all functions
|
||||||
|
/// defined in this contract of the given name (excluding inherited functions).
|
||||||
|
auto definedFunctions(std::string const& _name) const
|
||||||
|
{
|
||||||
|
auto&& [b, e] = definedFunctionsByName().equal_range(_name);
|
||||||
|
return ranges::subrange<decltype(b)>(b, e) | ranges::views::values;
|
||||||
|
}
|
||||||
std::vector<EventDefinition const*> events() const { return filteredNodes<EventDefinition>(m_subNodes); }
|
std::vector<EventDefinition const*> events() const { return filteredNodes<EventDefinition>(m_subNodes); }
|
||||||
std::vector<EventDefinition const*> const& interfaceEvents() const;
|
std::vector<EventDefinition const*> const& interfaceEvents() const;
|
||||||
/// @returns all errors defined in this contract or any base contract
|
/// @returns all errors defined in this contract or any base contract
|
||||||
@ -546,6 +556,8 @@ public:
|
|||||||
FunctionDefinition const* nextConstructor(ContractDefinition const& _mostDerivedContract) const;
|
FunctionDefinition const* nextConstructor(ContractDefinition const& _mostDerivedContract) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::multimap<std::string, FunctionDefinition const*> const& definedFunctionsByName() const;
|
||||||
|
|
||||||
std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts;
|
std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts;
|
||||||
std::vector<ASTPointer<ASTNode>> m_subNodes;
|
std::vector<ASTPointer<ASTNode>> m_subNodes;
|
||||||
ContractKind m_contractKind;
|
ContractKind m_contractKind;
|
||||||
@ -553,6 +565,7 @@ private:
|
|||||||
|
|
||||||
util::LazyInit<std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList[2];
|
util::LazyInit<std::vector<std::pair<util::FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList[2];
|
||||||
util::LazyInit<std::vector<EventDefinition const*>> m_interfaceEvents;
|
util::LazyInit<std::vector<EventDefinition const*>> m_interfaceEvents;
|
||||||
|
util::LazyInit<std::multimap<std::string, FunctionDefinition const*>> m_definedFunctionsByName;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user