diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 6ff3e91f6..2e422b078 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -516,6 +516,8 @@ bool CompilerStack::compile(State _stopAfter) // Only compile contracts individually which have been requested. map> otherCompilers; + map otherYulSources; + for (Source const* source: m_sourceOrder) for (ASTPointer const& node: source->ast->nodes()) if (auto contract = dynamic_cast(node.get())) @@ -526,7 +528,7 @@ bool CompilerStack::compile(State _stopAfter) if (m_generateEvmBytecode) compileContract(*contract, otherCompilers); if (m_generateIR || m_generateEwasm) - generateIR(*contract); + generateIR(*contract, otherYulSources); if (m_generateEwasm) generateEwasm(*contract); } @@ -1216,17 +1218,15 @@ void CompilerStack::compileContract( _otherCompilers[compiledContract.contract] = compiler; } -void CompilerStack::generateIR(ContractDefinition const& _contract) +void CompilerStack::generateIR( + ContractDefinition const& _contract, + map& _otherYulSources +) { solAssert(m_stackState >= AnalysisPerformed, ""); if (m_hasError) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Called generateIR with errors.")); - if (!_contract.canBeDeployed()) - return; - - map otherYulSources; - Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); if (!compiledContract.yulIR.empty()) return; @@ -1234,12 +1234,15 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) string dependenciesSource; for (auto const* dependency: _contract.annotation().contractDependencies) { - generateIR(*dependency); - otherYulSources.emplace(dependency, m_contracts.at(dependency->fullyQualifiedName()).yulIR); + generateIR(*dependency, _otherYulSources); + _otherYulSources.emplace(dependency, m_contracts.at(dependency->fullyQualifiedName()).yulIR); } + if (!_contract.canBeDeployed()) + return; + 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); } void CompilerStack::generateEwasm(ContractDefinition const& _contract) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index c7f4e4494..8fc264b6f 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -393,7 +393,10 @@ private: /// Generate Yul IR for a single contract. /// The IR is stored but otherwise unused. - void generateIR(ContractDefinition const& _contract); + void generateIR( + ContractDefinition const& _contract, + std::map& _otherYulSources + ); /// Generate Ewasm representation for a single contract. void generateEwasm(ContractDefinition const& _contract); diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index de43bf9fa..ed021bcdf 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -1521,7 +1521,7 @@ BOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract) "settings": { "outputSelection": { "BlockRewardAuRaCoins.sol": { - "BlockRewardAuRaCoins": ["evm.bytecode.sourceMap"] + "BlockRewardAuRaCoins": ["ir", "evm.bytecode.sourceMap"] } } } @@ -1540,6 +1540,7 @@ BOOST_AUTO_TEST_CASE(dependency_tracking_of_abstract_contract) BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"].size() == 1); BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"].isObject()); BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["evm"].isObject()); + BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["ir"].isString()); BOOST_REQUIRE(result["contracts"]["BlockRewardAuRaCoins.sol"]["BlockRewardAuRaCoins"]["evm"]["bytecode"].isObject()); BOOST_REQUIRE(result["sources"].isObject()); BOOST_REQUIRE(result["sources"].size() == 2);