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 namespace util;
|
||||
|
||||
struct CallGraph;
|
||||
|
||||
struct ASTAnnotation
|
||||
{
|
||||
ASTAnnotation() = default;
|
||||
@ -162,6 +164,10 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, StructurallyDocu
|
||||
/// Mapping containing the nodes that define the arguments for base constructors.
|
||||
/// These can either be inheritance specifiers or modifier invocations.
|
||||
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
|
||||
|
@ -407,8 +407,18 @@ bool CompilerStack::analyze()
|
||||
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));
|
||||
|
||||
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); });
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
if (m_stackState < SourcesSet)
|
||||
@ -1307,7 +1299,10 @@ 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());
|
||||
generator.verifyCallGraphs(
|
||||
**compiledContract.contract->annotation().creationCallGraph,
|
||||
**compiledContract.contract->annotation().deployedCallGraph
|
||||
);
|
||||
}
|
||||
|
||||
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
|
||||
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.
|
||||
/// 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.
|
||||
@ -394,8 +388,6 @@ private:
|
||||
util::LazyInit<Json::Value const> runtimeGeneratedSources;
|
||||
mutable std::optional<std::string const> sourceMapping;
|
||||
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
|
||||
|
@ -116,8 +116,8 @@ tuple<CallGraphMap, CallGraphMap> collectGraphs(CompilerStack const& _compilerSt
|
||||
soltestAssert(fullyQualifiedContractName.size() > 0 && fullyQualifiedContractName[0] == ':', "");
|
||||
string contractName = fullyQualifiedContractName.substr(1);
|
||||
|
||||
get<0>(graphs).emplace(contractName, &_compilerStack.creationCallGraph(fullyQualifiedContractName));
|
||||
get<1>(graphs).emplace(contractName, &_compilerStack.deployedCallGraph(fullyQualifiedContractName));
|
||||
get<0>(graphs).emplace(contractName, _compilerStack.contractDefinition(fullyQualifiedContractName).annotation().creationCallGraph->get());
|
||||
get<1>(graphs).emplace(contractName, _compilerStack.contractDefinition(fullyQualifiedContractName).annotation().deployedCallGraph->get());
|
||||
}
|
||||
|
||||
return graphs;
|
||||
|
Loading…
Reference in New Issue
Block a user