| 801 | } |
| 802 | |
| 803 | std::pair<std::string, std::map<ContractDefinition const*, std::vector<std::string>>> IRGenerator::evaluateConstructorArguments( |
| 804 | ContractDefinition const& _contract |
| 805 | ) |
| 806 | { |
| 807 | struct InheritanceOrder |
| 808 | { |
| 809 | bool operator()(ContractDefinition const* _c1, ContractDefinition const* _c2) const |
| 810 | { |
| 811 | solAssert(util::contains(linearizedBaseContracts, _c1) && util::contains(linearizedBaseContracts, _c2), ""); |
| 812 | auto it1 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c1); |
| 813 | auto it2 = find(linearizedBaseContracts.begin(), linearizedBaseContracts.end(), _c2); |
| 814 | return it1 < it2; |
| 815 | } |
| 816 | std::vector<ContractDefinition const*> const& linearizedBaseContracts; |
| 817 | } inheritanceOrder{_contract.annotation().linearizedBaseContracts}; |
| 818 | |
| 819 | std::map<ContractDefinition const*, std::vector<std::string>> constructorParams; |
| 820 | |
| 821 | std::map<ContractDefinition const*, std::vector<ASTPointer<Expression>>const *, InheritanceOrder> |
| 822 | baseConstructorArguments(inheritanceOrder); |
| 823 | |
| 824 | for (ASTPointer<InheritanceSpecifier> const& base: _contract.baseContracts()) |
| 825 | if (FunctionDefinition const* baseConstructor = dynamic_cast<ContractDefinition const*>( |
| 826 | base->name().annotation().referencedDeclaration |
| 827 | )->constructor(); baseConstructor && base->arguments()) |
| 828 | solAssert(baseConstructorArguments.emplace( |
| 829 | dynamic_cast<ContractDefinition const*>(baseConstructor->scope()), |
| 830 | base->arguments() |
| 831 | ).second, ""); |
| 832 | |
| 833 | if (FunctionDefinition const* constructor = _contract.constructor()) |
| 834 | for (ASTPointer<ModifierInvocation> const& modifier: constructor->modifiers()) |
| 835 | if (auto const* baseContract = dynamic_cast<ContractDefinition const*>( |
| 836 | modifier->name().annotation().referencedDeclaration |
| 837 | )) |
| 838 | if ( |
| 839 | FunctionDefinition const* baseConstructor = baseContract->constructor(); |
| 840 | baseConstructor && modifier->arguments() |
| 841 | ) |
| 842 | solAssert(baseConstructorArguments.emplace( |
| 843 | dynamic_cast<ContractDefinition const*>(baseConstructor->scope()), |
| 844 | modifier->arguments() |
| 845 | ).second, ""); |
| 846 | |
| 847 | IRGeneratorForStatements generator{m_context, m_utils, m_optimiserSettings}; |
| 848 | for (auto&& [baseContract, arguments]: baseConstructorArguments) |
| 849 | { |
| 850 | solAssert(baseContract && arguments, ""); |
| 851 | if (baseContract->constructor() && !arguments->empty()) |
| 852 | { |
| 853 | std::vector<std::string> params; |
| 854 | for (size_t i = 0; i < arguments->size(); ++i) |
| 855 | params += generator.evaluateExpression( |
| 856 | *(arguments->at(i)), |
| 857 | *(baseContract->constructor()->parameters()[i]->type()) |
| 858 | ).stackSlots(); |
| 859 | constructorParams[baseContract] = std::move(params); |
| 860 | } |
nothing calls this directly
no test coverage detected