/* This file is part of cpp-ethereum. cpp-ethereum 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. cpp-ethereum 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 cpp-ethereum. If not, see . */ /** * @author Christian * @date 2014 * Full-stack compiler that converts a source code string to bytecode. */ #pragma once #include #include #include #include namespace dev { namespace solidity { // forward declarations class Scanner; class ContractDefinition; class Compiler; class GlobalContext; class InterfaceHandler; enum class DocumentationType: uint8_t { NATSPEC_USER = 1, NATSPEC_DEV, ABI_INTERFACE }; /** * Easy to use and self-contained Solidity compiler with as few header dependencies as possible. * It holds state and can be used to either step through the compilation stages (and abort e.g. * before compilation to bytecode) or run the whole compilation in one call. */ class CompilerStack { public: CompilerStack(); void reset() { *this = CompilerStack(); } void setSource(std::string const& _sourceCode); void parse(); void parse(std::string const& _sourceCode); /// Compiles the contract that was previously parsed. bytes const& compile(bool _optimize = false); /// Parses and compiles the given source code. bytes const& compile(std::string const& _sourceCode, bool _optimize = false); bytes const& getBytecode() const { return m_bytecode; } /// Streams a verbose version of the assembly to @a _outStream. /// Prerequisite: Successful compilation. void streamAssembly(std::ostream& _outStream); /// Returns a string representing the contract interface in JSON. /// Prerequisite: Successful call to parse or compile. std::string const& getInterface(); /// Returns a string representing the contract's documentation in JSON. /// Prerequisite: Successful call to parse or compile. /// @param type The type of the documentation to get. /// Can be one of 3 types defined at @c documentation_type std::string const& getJsonDocumentation(DocumentationType type); /// Returns the previously used scanner, useful for counting lines during error reporting. Scanner const& getScanner() const { return *m_scanner; } ContractDefinition& getAST() const { return *m_contractASTNode; } /// Compile the given @a _sourceCode to bytecode. If a scanner is provided, it is used for /// scanning the source code - this is useful for printing exception information. static bytes staticCompile(std::string const& _sourceCode, bool _optimize = false); /// Compile under msvc results in error CC2280 CompilerStack& operator=(const CompilerStack& _other) { m_scanner = _other.m_scanner; m_globalContext = _other.m_globalContext; m_contractASTNode = _other.m_contractASTNode; m_parseSuccessful = _other.m_parseSuccessful; m_interface.reset(_other.m_interface.get()); m_userDocumentation.reset(_other.m_userDocumentation.get()); m_devDocumentation.reset(_other.m_devDocumentation.get()); m_compiler = _other.m_compiler; m_interfaceHandler = _other.m_interfaceHandler; m_bytecode = m_bytecode; return *this; } private: std::shared_ptr m_scanner; std::shared_ptr m_globalContext; std::shared_ptr m_contractASTNode; bool m_parseSuccessful; std::unique_ptr m_interface; std::unique_ptr m_userDocumentation; std::unique_ptr m_devDocumentation; std::shared_ptr m_compiler; std::shared_ptr m_interfaceHandler; bytes m_bytecode; }; } }