/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. solidity is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with solidity. If not, see . */ #pragma once #include #include #include #include #include #include #include #include #include namespace solidity::langutil { class CharStream; } namespace solidity::yul { struct AsmAnalysisInfo; struct Dialect; } namespace std { std::ostream& operator<<(std::ostream& _outputStream, solidity::langutil::ErrorList const& _errors); } namespace solidity::phaser { /** * Class representing parsed and analysed Yul program that we can apply optimisations to. * The program is already disambiguated and has several prerequisite optimiser steps applied to it * so that the requirements of any possible step that could be later applied by the user are * already satisfied. * * The class allows the user to apply extra optimisations and obtain metrics and general * information about the resulting syntax tree. */ class Program { public: Program(Program const& program); Program(Program&& program): m_ast(std::move(program.m_ast)), m_dialect{program.m_dialect}, m_nameDispenser(std::move(program.m_nameDispenser)) {} Program operator=(Program const& program) = delete; Program operator=(Program&& program) = delete; static std::variant load(langutil::CharStream& _sourceCode); void optimise(std::vector const& _optimisationSteps); size_t codeSize() const { return computeCodeSize(*m_ast); } yul::Block const& ast() const { return *m_ast; } friend std::ostream& operator<<(std::ostream& _stream, Program const& _program); std::string toJson() const; private: Program( yul::Dialect const& _dialect, std::unique_ptr _ast ): m_ast(std::move(_ast)), m_dialect{_dialect}, m_nameDispenser(_dialect, *m_ast, {}) {} static std::variant, langutil::ErrorList> parseObject( yul::Dialect const& _dialect, langutil::CharStream _source ); static std::variant, langutil::ErrorList> analyzeAST( yul::Dialect const& _dialect, yul::Block const& _ast ); static std::unique_ptr disambiguateAST( yul::Dialect const& _dialect, yul::Block const& _ast, yul::AsmAnalysisInfo const& _analysisInfo ); static std::unique_ptr applyOptimisationSteps( yul::Dialect const& _dialect, yul::NameDispenser& _nameDispenser, std::unique_ptr _ast, std::vector const& _optimisationSteps ); static size_t computeCodeSize(yul::Block const& _ast); std::unique_ptr m_ast; yul::Dialect const& m_dialect; yul::NameDispenser m_nameDispenser; }; }