mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
CompilerStack: Build call graphs in the analysis phase
This commit is contained in:
parent
4c283f00c1
commit
53d70dec57
@ -399,6 +399,19 @@ bool CompilerStack::analyze()
|
|||||||
if (source->ast && !typeChecker.checkTypeRequirements(*source->ast))
|
if (source->ast && !typeChecker.checkTypeRequirements(*source->ast))
|
||||||
noErrors = false;
|
noErrors = false;
|
||||||
|
|
||||||
|
if (noErrors)
|
||||||
|
{
|
||||||
|
for (Source const* source: m_sourceOrder)
|
||||||
|
if (source->ast)
|
||||||
|
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
|
||||||
|
if (auto const* contractDefinition = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
|
{
|
||||||
|
Contract& contractState = m_contracts.at(contractDefinition->fullyQualifiedName());
|
||||||
|
contractState.creationCallGraph.emplace(FunctionCallGraphBuilder::buildCreationGraph(*contractDefinition));
|
||||||
|
contractState.deployedCallGraph.emplace(FunctionCallGraphBuilder::buildDeployedGraph(*contractDefinition, *contractState.creationCallGraph));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (noErrors)
|
if (noErrors)
|
||||||
{
|
{
|
||||||
// Checks that can only be done when all types of all AST nodes are known.
|
// Checks that can only be done when all types of all AST nodes are known.
|
||||||
@ -937,6 +950,24 @@ string const& CompilerStack::metadata(Contract const& _contract) const
|
|||||||
return _contract.metadata.init([&]{ return createMetadata(_contract); });
|
return _contract.metadata.init([&]{ return createMetadata(_contract); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionCallGraphBuilder::ContractCallGraph const& CompilerStack::creationCallGraph(string const& _contractName) const
|
||||||
|
{
|
||||||
|
if (m_stackState < AnalysisPerformed)
|
||||||
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Analysis was not successful."));
|
||||||
|
|
||||||
|
solAssert(contract(_contractName).creationCallGraph.has_value(), "");
|
||||||
|
return contract(_contractName).creationCallGraph.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionCallGraphBuilder::ContractCallGraph const& CompilerStack::deployedCallGraph(string const& _contractName) const
|
||||||
|
{
|
||||||
|
if (m_stackState < AnalysisPerformed)
|
||||||
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Analysis was not successful."));
|
||||||
|
|
||||||
|
solAssert(contract(_contractName).deployedCallGraph.has_value(), "");
|
||||||
|
return contract(_contractName).deployedCallGraph.value();
|
||||||
|
}
|
||||||
|
|
||||||
Scanner const& CompilerStack::scanner(string const& _sourceName) const
|
Scanner const& CompilerStack::scanner(string const& _sourceName) const
|
||||||
{
|
{
|
||||||
if (m_stackState < SourcesSet)
|
if (m_stackState < SourcesSet)
|
||||||
@ -1275,6 +1306,8 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
|
|||||||
|
|
||||||
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings);
|
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings);
|
||||||
tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run(_contract, otherYulSources);
|
tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run(_contract, otherYulSources);
|
||||||
|
|
||||||
|
generator.verifyCallGraphs(compiledContract.creationCallGraph.value(), compiledContract.deployedCallGraph.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
|
void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <libsolidity/analysis/FunctionCallGraph.h>
|
||||||
#include <libsolidity/interface/ReadFile.h>
|
#include <libsolidity/interface/ReadFile.h>
|
||||||
#include <libsolidity/interface/OptimiserSettings.h>
|
#include <libsolidity/interface/OptimiserSettings.h>
|
||||||
#include <libsolidity/interface/Version.h>
|
#include <libsolidity/interface/Version.h>
|
||||||
@ -342,6 +343,12 @@ public:
|
|||||||
/// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions
|
/// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions
|
||||||
Json::Value gasEstimates(std::string const& _contractName) const;
|
Json::Value gasEstimates(std::string const& _contractName) const;
|
||||||
|
|
||||||
|
/// @returns a graph with edges representing calls between functions that may happen during contract construction.
|
||||||
|
FunctionCallGraphBuilder::ContractCallGraph const& creationCallGraph(std::string const& _contractName) const;
|
||||||
|
|
||||||
|
/// @returns a graph with edges representing calls between functions that may happen in a deployed contract.
|
||||||
|
FunctionCallGraphBuilder::ContractCallGraph const& deployedCallGraph(std::string const& _contractName) const;
|
||||||
|
|
||||||
/// Changes the format of the metadata appended at the end of the bytecode.
|
/// Changes the format of the metadata appended at the end of the bytecode.
|
||||||
/// This is mostly a workaround to avoid bytecode and gas differences between compiler builds
|
/// This is mostly a workaround to avoid bytecode and gas differences between compiler builds
|
||||||
/// caused by differences in metadata. Should only be used for testing.
|
/// caused by differences in metadata. Should only be used for testing.
|
||||||
@ -383,6 +390,8 @@ private:
|
|||||||
util::LazyInit<Json::Value const> runtimeGeneratedSources;
|
util::LazyInit<Json::Value const> runtimeGeneratedSources;
|
||||||
mutable std::optional<std::string const> sourceMapping;
|
mutable std::optional<std::string const> sourceMapping;
|
||||||
mutable std::optional<std::string const> runtimeSourceMapping;
|
mutable std::optional<std::string const> runtimeSourceMapping;
|
||||||
|
std::optional<FunctionCallGraphBuilder::ContractCallGraph const> creationCallGraph;
|
||||||
|
std::optional<FunctionCallGraphBuilder::ContractCallGraph const> deployedCallGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Loads the missing sources from @a _ast (named @a _path) using the callback
|
/// Loads the missing sources from @a _ast (named @a _path) using the callback
|
||||||
|
Loading…
Reference in New Issue
Block a user