CompilerStack: Build call graphs in the analysis phase

This commit is contained in:
Mathias Baumann
2021-02-23 10:46:28 +01:00
committed by Kamil Śliwak
parent 4c283f00c1
commit 53d70dec57
2 changed files with 42 additions and 0 deletions
+33
View File
@@ -399,6 +399,19 @@ bool CompilerStack::analyze()
if (source->ast && !typeChecker.checkTypeRequirements(*source->ast))
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)
{
// 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); });
}
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
{
if (m_stackState < SourcesSet)
@@ -1275,6 +1306,8 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings);
tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run(_contract, otherYulSources);
generator.verifyCallGraphs(compiledContract.creationCallGraph.value(), compiledContract.deployedCallGraph.value());
}
void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)