mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move call graphs from CompilerStack to ContractDefinitionAnnotation
This commit is contained in:
parent
6c28120f19
commit
54eb34d6fd
@ -49,6 +49,8 @@ class Type;
|
|||||||
using TypePointer = Type const*;
|
using TypePointer = Type const*;
|
||||||
using namespace util;
|
using namespace util;
|
||||||
|
|
||||||
|
struct CallGraph;
|
||||||
|
|
||||||
struct ASTAnnotation
|
struct ASTAnnotation
|
||||||
{
|
{
|
||||||
ASTAnnotation() = default;
|
ASTAnnotation() = default;
|
||||||
@ -162,6 +164,10 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu
|
|||||||
/// Mapping containing the nodes that define the arguments for base constructors.
|
/// Mapping containing the nodes that define the arguments for base constructors.
|
||||||
/// These can either be inheritance specifiers or modifier invocations.
|
/// These can either be inheritance specifiers or modifier invocations.
|
||||||
std::map<FunctionDefinition const*, ASTNode const*> baseConstructorArguments;
|
std::map<FunctionDefinition const*, ASTNode const*> baseConstructorArguments;
|
||||||
|
/// A graph with edges representing calls between functions that may happen during contract construction.
|
||||||
|
SetOnce<std::shared_ptr<CallGraph const>> creationCallGraph;
|
||||||
|
/// A graph with edges representing calls between functions that may happen in a deployed contract.
|
||||||
|
SetOnce<std::shared_ptr<CallGraph const>> deployedCallGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CallableDeclarationAnnotation: DeclarationAnnotation
|
struct CallableDeclarationAnnotation: DeclarationAnnotation
|
||||||
|
@ -407,8 +407,18 @@ bool CompilerStack::analyze()
|
|||||||
if (auto const* contractDefinition = dynamic_cast<ContractDefinition*>(node.get()))
|
if (auto const* contractDefinition = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
{
|
{
|
||||||
Contract& contractState = m_contracts.at(contractDefinition->fullyQualifiedName());
|
Contract& contractState = m_contracts.at(contractDefinition->fullyQualifiedName());
|
||||||
contractState.creationCallGraph.emplace(FunctionCallGraphBuilder::buildCreationGraph(*contractDefinition));
|
|
||||||
contractState.deployedCallGraph.emplace(FunctionCallGraphBuilder::buildDeployedGraph(*contractDefinition, *contractState.creationCallGraph));
|
contractState.contract->annotation().creationCallGraph = make_unique<CallGraph>(
|
||||||
|
FunctionCallGraphBuilder::buildCreationGraph(
|
||||||
|
*contractDefinition
|
||||||
|
)
|
||||||
|
);
|
||||||
|
contractState.contract->annotation().deployedCallGraph = make_unique<CallGraph>(
|
||||||
|
FunctionCallGraphBuilder::buildDeployedGraph(
|
||||||
|
*contractDefinition,
|
||||||
|
**contractState.contract->annotation().creationCallGraph
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,24 +960,6 @@ string const& CompilerStack::metadata(Contract const& _contract) const
|
|||||||
return _contract.metadata.init([&]{ return createMetadata(_contract); });
|
return _contract.metadata.init([&]{ return createMetadata(_contract); });
|
||||||
}
|
}
|
||||||
|
|
||||||
CallGraph 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
CallGraph 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)
|
||||||
@ -1307,7 +1299,10 @@ 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());
|
generator.verifyCallGraphs(
|
||||||
|
**compiledContract.contract->annotation().creationCallGraph,
|
||||||
|
**compiledContract.contract->annotation().deployedCallGraph
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
|
void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
|
||||||
|
@ -347,12 +347,6 @@ 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.
|
|
||||||
CallGraph const& creationCallGraph(std::string const& _contractName) const;
|
|
||||||
|
|
||||||
/// @returns a graph with edges representing calls between functions that may happen in a deployed contract.
|
|
||||||
CallGraph 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.
|
||||||
@ -394,8 +388,6 @@ 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<CallGraph const> creationCallGraph;
|
|
||||||
std::optional<CallGraph 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
|
||||||
|
@ -116,8 +116,8 @@ tuple<CallGraphMap, CallGraphMap> collectGraphs(CompilerStack const& _compilerSt
|
|||||||
soltestAssert(fullyQualifiedContractName.size() > 0 && fullyQualifiedContractName[0] == ':', "");
|
soltestAssert(fullyQualifiedContractName.size() > 0 && fullyQualifiedContractName[0] == ':', "");
|
||||||
string contractName = fullyQualifiedContractName.substr(1);
|
string contractName = fullyQualifiedContractName.substr(1);
|
||||||
|
|
||||||
get<0>(graphs).emplace(contractName, &_compilerStack.creationCallGraph(fullyQualifiedContractName));
|
get<0>(graphs).emplace(contractName, _compilerStack.contractDefinition(fullyQualifiedContractName).annotation().creationCallGraph->get());
|
||||||
get<1>(graphs).emplace(contractName, &_compilerStack.deployedCallGraph(fullyQualifiedContractName));
|
get<1>(graphs).emplace(contractName, _compilerStack.contractDefinition(fullyQualifiedContractName).annotation().deployedCallGraph->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
return graphs;
|
return graphs;
|
||||||
|
Loading…
Reference in New Issue
Block a user